Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android Deeplinking: Inviting/joining other packs #77

Open
wants to merge 28 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e9143e4
Add simple '/pack/:stickerPackId' deeplink
MKuijpers Mar 20, 2021
c361836
Add join screen and deeplink connection to the join screen
MKuijpers Mar 29, 2021
f0829f2
Merge branch 'master' into deeplinking
MKuijpers Apr 2, 2021
4f494a1
Use new invite API for invites/joining
MKuijpers Apr 3, 2021
e0071a5
Small cleanup
MKuijpers Apr 3, 2021
189d08d
Rewrite StickerPackScreen to FC
MKuijpers Apr 3, 2021
f477146
Generate invite URL on client
MKuijpers Apr 3, 2021
7445498
Convert toolbar to FC
MKuijpers Apr 3, 2021
806a394
Revert sticker pack header change to avoid conflicts
MKuijpers Apr 3, 2021
a58c119
Build apk
MKuijpers Apr 12, 2021
9988115
Merge branch 'master' into deeplinking
MKuijpers Apr 12, 2021
90865a0
Add branches wildcard for pull_request in APK build
MKuijpers Apr 12, 2021
f26bbf5
Fix syntax in .yml
MKuijpers Apr 12, 2021
cb86c2d
Temporarily remove path requirement for build-apk.yml
MKuijpers Apr 12, 2021
7874eda
Add (hopefully) correct app path requirement for apk-build.yml
MKuijpers Apr 12, 2021
cbc8886
Extract pack stickers view to component
MKuijpers Apr 17, 2021
f9c4723
Simplify ci change
MKuijpers Apr 17, 2021
eaa9240
Merge branch 'master' into deeplinking
MKuijpers Jan 19, 2023
44dd456
Change deeplink domain to vercel preview domain
MKuijpers Jan 19, 2023
e9120ea
Merge branch 'mvp-screen-changes' into deeplinking
MKuijpers Jan 19, 2023
a0d3b57
Merge branch 'mvp-screen-changes' into deeplinking
MKuijpers Jan 20, 2023
8ab970e
Change join sticker pack screen design by reusing sticker pack screen…
MKuijpers Jan 20, 2023
b0e4a12
Merge branch 'mvp-screen-changes' into deeplinking
MKuijpers Jan 21, 2023
f887b11
Merge branch 'mvp-screen-changes' into deeplinking
MKuijpers Jan 22, 2023
6c732ec
Merge branch 'mvp-screen-changes' into deeplinking
MKuijpers Jan 22, 2023
87b75f2
Implement kicking sticker pack members
MKuijpers Jan 22, 2023
2ef1f27
Merge branch 'master' into deeplinking
MKuijpers Jan 23, 2023
6b93e15
Merge branch 'master' into deeplinking
MKuijpers Feb 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions app/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="kangaroo" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https"
android:host="www.stickr.cf"/>
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />

Expand Down
2 changes: 2 additions & 0 deletions app/src/api/generatedApiWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
AuthApi,
Configuration,
StickerPacksApi,
InvitesApi,
UserApi,
} from "./generated-typescript-api-client/src";

Expand All @@ -20,4 +21,5 @@ export const api = {
users: new UserApi(configuration, baseURL, instance),
auth: new AuthApi(configuration, baseURL, instance),
stickerPacks: new StickerPacksApi(configuration, baseURL, instance),
invites: new InvitesApi(configuration, baseURL, instance),
};
33 changes: 33 additions & 0 deletions app/src/api/hooks/mutations/invites.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { QueryClient, useMutation } from "react-query";
import { QUERY_KEYS } from "../../../constants/ReactQueryKeys";
import {
CreateInviteDto,
InviteRoDto,
StickerPackRo,
} from "../../generated-typescript-api-client/src";
import { api } from "../../generatedApiWrapper";

const useInvite = async (inviteId: string) => {
const { data } = await api.invites.useInvite(inviteId);
return data;
};

export const useInviteMutation = (queryClient: QueryClient) =>
useMutation<StickerPackRo, any, string, unknown>(useInvite, {
onSuccess: () => {
queryClient.invalidateQueries(QUERY_KEYS.ownAndJoinedStickerPacks);
},
});

const createInvite = async (
stickerPackId: string,
createInviteDto: CreateInviteDto,
): Promise<InviteRoDto> => {
const { data } = await api.stickerPacks.createInvite(stickerPackId, createInviteDto || {});
return data;
};

export const useCreateInviteMutation = (stickerPackId: string) =>
useMutation<InviteRoDto, any, CreateInviteDto, unknown>((createInviteDto: CreateInviteDto) =>
createInvite(stickerPackId, createInviteDto),
);
6 changes: 3 additions & 3 deletions app/src/api/hooks/mutations/stickerPack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const createStickerPack = async (createStickerPackDto: CreateStickerPackDto) =>

export const useCreateStickerPackMutation = (queryClient: QueryClient) =>
useMutation<StickerPackRo, any, CreateStickerPackDto, unknown>(createStickerPack, {
onSuccess: () => queryClient.invalidateQueries(QUERY_KEYS.myStickerPacks),
onSuccess: () => queryClient.invalidateQueries(QUERY_KEYS.ownAndJoinedStickerPacks),
});

const removeStickerPack = async (stickerPackId: string) => {
Expand All @@ -25,13 +25,13 @@ const removeStickerPack = async (stickerPackId: string) => {

export const useRemoveStickerPackMutation = (queryClient: QueryClient) =>
useMutation<StickerPackRo, any, string, unknown>(removeStickerPack, {
onSuccess: () => queryClient.invalidateQueries(QUERY_KEYS.myStickerPacks),
onSuccess: () => queryClient.invalidateQueries(QUERY_KEYS.ownAndJoinedStickerPacks),
});

export const useUploadStickerMutation = (queryClient: QueryClient) =>
useMutation<StickerRo, any, UploadStickerRo, unknown>(uploadSticker, {
onSuccess: (data, variables) => {
queryClient.invalidateQueries([QUERY_KEYS.stickerPack, variables.stickerPackId]);
queryClient.invalidateQueries(QUERY_KEYS.myStickerPacks);
queryClient.invalidateQueries(QUERY_KEYS.ownAndJoinedStickerPacks);
},
});
21 changes: 21 additions & 0 deletions app/src/api/hooks/query/invites.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { QueryClient, useQuery } from "react-query";
import { QUERY_KEYS } from "../../../constants/ReactQueryKeys";
import { StickerPackRo } from "../../generated-typescript-api-client/src";
import { api } from "../../generatedApiWrapper";

const getInvitePreview = async (inviteId: string) => {
const { data } = await api.invites.previewInvite(inviteId);
return data;
};

export const useInvitePreview = (queryClient: QueryClient, inviteId: string) =>
useQuery<StickerPackRo, any, StickerPackRo>(
[QUERY_KEYS.invitePreview, inviteId],
() => getInvitePreview(inviteId),
{
onSuccess: (data) => {
queryClient.invalidateQueries(QUERY_KEYS.ownAndJoinedStickerPacks);
queryClient.invalidateQueries([QUERY_KEYS.stickerPack, data.id]);
},
},
);
9 changes: 6 additions & 3 deletions app/src/api/hooks/query/stickerPack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ export const useStickerPack = (id: string) =>
);

const getStickerPacks = async () => {
const { data } = await api.users.getOwnStickerPacks();
const { data } = await api.users.getOwnAndJoinedStickerPacks();
return data;
};

export const useStickerPacks = () =>
useQuery<StickerPackRo[], any, StickerPackRo[]>(QUERY_KEYS.myStickerPacks, getStickerPacks);
export const useOwnAndJoinedStickerPacks = () =>
useQuery<StickerPackRo[], any, StickerPackRo[]>(
QUERY_KEYS.ownAndJoinedStickerPacks,
getStickerPacks,
);
1 change: 1 addition & 0 deletions app/src/constants/Deeplinking.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const DEEPLINK_SITE_DOMAIN = "https://www.stickr.cf";
3 changes: 2 additions & 1 deletion app/src/constants/ReactQueryKeys.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const QUERY_KEYS = {
myStickerPacks: "myStickerPacks",
ownAndJoinedStickerPacks: "ownAndJoinedStickerPacks",
stickerPack: "stickerPack",
invitePreview: "invitePreview",
me: "myProfile",
like: "like",
};
1 change: 1 addition & 0 deletions app/src/constants/StickerPack.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export const ACCOUNT_MAX_PREVIEW_STICKERS = 8;
export const MAX_STICKERS_PER_PACK = 30;
5 changes: 5 additions & 0 deletions app/src/contexts/AuthContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ export const AuthContextProvider = ({ children }: any): React.ReactElement => {
}, []);

useEffect(() => {
if (accessToken == undefined) {
setIsAuthenticated(false);
return;
}

api.auth
.testAuth()
.then(() => setIsAuthenticated(true))
Expand Down
36 changes: 32 additions & 4 deletions app/src/navigation/AppNavigator.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import { NavigationContainer } from "@react-navigation/native";
import { LinkingOptions, NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import { LoginScreen } from "../screens/auth/LoginScreen";
import { RegisterScreen } from "../screens/auth/RegisterScreen";
Expand All @@ -22,7 +22,9 @@ import { DiscoverScreen } from "../screens/app/home/DiscoverScreen";
import { SettingsScreen } from "../screens/app/home/SettingsScreen";
import { SettingsUpdateScreen } from "../screens/app/home/SettingsUpdateScreen";
import { CreateAddMembersScreen } from "../screens/app/home/stickerpack/CreateAddMembersScreen";
import { JoinStickerPackScreen } from "../screens/app/home/stickerpack/JoinStickerPackScreen";
import tw from "tailwind-react-native-classnames";
import { DEEPLINK_SITE_DOMAIN } from "../constants/Deeplinking";

export type AuthStackParamList = {
Login: undefined;
Expand All @@ -43,7 +45,7 @@ export const AuthStackScreen = (): JSX.Element => (
export type HomeStackParamList = {
Homescreen: undefined;
StickerPackDetailScreen: {
stickerPack: StickerPackRo;
stickerPackId: string;
};
StickerPackManageScreen: {
stickerPack: StickerPackRo;
Expand All @@ -56,6 +58,9 @@ export type HomeStackParamList = {
name: string;
personal: boolean;
};
JoinStickerPackScreen: {
inviteId: string;
};
};

export type FeedStackParamList = {
Expand Down Expand Up @@ -117,7 +122,7 @@ const BottomTabBar = ({ navigation, state }: BottomTabBarProps<BottomTabBarOptio

const Tab = createBottomTabNavigator();
const HomeTabNavigator = () => (
<Tab.Navigator initialRouteName="Home" tabBar={(props) => <BottomTabBar {...props} />}>
<Tab.Navigator initialRouteName="SharedPacks" tabBar={(props) => <BottomTabBar {...props} />}>
<Tab.Screen name="Feed" component={FeedStackScreen} />
<Tab.Screen name="SharedPacks" component={HomeStackScreen} />
<Tab.Screen name="Discover" component={DiscoverStackScreen} />
Expand Down Expand Up @@ -193,6 +198,11 @@ const HomeStackScreen = () => (
component={CreateAddMembersScreen}
options={{ title: "Create Sticker Pack", headerBackTitle: " " }}
/>
<HomeStack.Screen
name="JoinStickerPackScreen"
component={JoinStickerPackScreen}
options={{ title: "Join Sticker Pack", headerBackTitle: " " }}
/>
</HomeStack.Navigator>
);

Expand Down Expand Up @@ -265,8 +275,26 @@ export const AppNavigator = (): React.ReactElement => {
);
}

const linkingOptions: LinkingOptions = {
prefixes: ["kangaroo://", DEEPLINK_SITE_DOMAIN],
config: {
screens: {
App: {
screens: {
SharedPacks: {
screens: {
initialRouteName: "SharedPacks",
JoinStickerPackScreen: "invite/:inviteId",
},
},
},
},
},
},
};

return (
<NavigationContainer>
<NavigationContainer linking={linkingOptions}>
<RootStackScreen isAuthenticated={isAuthenticated} />
</NavigationContainer>
);
Expand Down
6 changes: 3 additions & 3 deletions app/src/screens/app/home/AccountScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { TextStatElement } from "../../../components/common/TextStatElement";
import { AccountProfileImage } from "../../../components/common/AccountProfileImage";
import { useQueryClient } from "react-query";
import { useMe } from "../../../api/hooks/query/user";
import { useStickerPacks } from "../../../api/hooks/query/stickerPack";
import { useOwnAndJoinedStickerPacks } from "../../../api/hooks/query/stickerPack";
import { QUERY_KEYS } from "../../../constants/ReactQueryKeys";
import { CoverStickerImage } from "../../../components/common/CoverStickerImage";
import { StickerPackRo, StickerRo } from "../../../api/generated-typescript-api-client/src";
Expand All @@ -23,11 +23,11 @@ type Props = StackScreenProps<FeedStackParamList, "AccountScreen">;
export const AccountScreen = ({ navigation }: Props): React.ReactElement => {
const queryClient = useQueryClient();
const myUserQuery = useMe();
const myStickerPacksQuery = useStickerPacks();
const myStickerPacksQuery = useOwnAndJoinedStickerPacks();

useEffect(() => {
() => queryClient.invalidateQueries(QUERY_KEYS.me);
() => queryClient.invalidateQueries(QUERY_KEYS.myStickerPacks);
() => queryClient.invalidateQueries(QUERY_KEYS.ownAndJoinedStickerPacks);

navigation.setOptions({
headerRight: function navigationRightIcon() {
Expand Down
22 changes: 11 additions & 11 deletions app/src/screens/app/home/HomeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { StickerPackRo } from "../../../api/generated-typescript-api-client/src"
import { HomeScreenHeader } from "../../../components/home/HomeScreenHeader";
import { StickerPacksList } from "../../../components/stickerpack/StickerPackList";
import { sortedStickerPacks } from "../../../util/sorting";
import { useStickerPacks } from "../../../api/hooks/query/stickerPack";
import { useOwnAndJoinedStickerPacks } from "../../../api/hooks/query/stickerPack";
import { storeImages } from "../../../util/image_storing";
import { registerStickerPacks } from "../../..//util/sticker_registration";

Expand All @@ -22,18 +22,18 @@ export const HomeScreen = ({ navigation }: Props): React.ReactElement => {
const queryClient = useQueryClient();

useEffect(() => {
() => queryClient.invalidateQueries(QUERY_KEYS.myStickerPacks);
() => queryClient.invalidateQueries(QUERY_KEYS.ownAndJoinedStickerPacks);
}, [accessToken]);

const myStickerPacksQuery = useStickerPacks();
const ownAndJoinedStickerPacksQuery = useOwnAndJoinedStickerPacks();

useEffect(() => {
// TODO: move this to a more valid location?
if (myStickerPacksQuery.data) {
storeImages(myStickerPacksQuery.data);
registerStickerPacks(myStickerPacksQuery.data);
if (ownAndJoinedStickerPacksQuery.data) {
storeImages(ownAndJoinedStickerPacksQuery.data);
registerStickerPacks(ownAndJoinedStickerPacksQuery.data);
}
}, [myStickerPacksQuery.dataUpdatedAt]);
}, [ownAndJoinedStickerPacksQuery.dataUpdatedAt]);

return (
<SafeAreaView style={tailwind("flex-1")}>
Expand All @@ -42,12 +42,12 @@ export const HomeScreen = ({ navigation }: Props): React.ReactElement => {
onLogout={logout}
/>
<StickerPacksList
stickerPacks={sortedStickerPacks(myStickerPacksQuery.data || [])}
refreshing={myStickerPacksQuery.isLoading}
onRefresh={() => queryClient.invalidateQueries(QUERY_KEYS.myStickerPacks)}
stickerPacks={sortedStickerPacks(ownAndJoinedStickerPacksQuery.data || [])}
refreshing={ownAndJoinedStickerPacksQuery.isLoading}
onRefresh={() => queryClient.invalidateQueries(QUERY_KEYS.ownAndJoinedStickerPacks)}
onPressStickerPack={(stickerPack: StickerPackRo) => {
navigation.navigate("StickerPackDetailScreen", {
stickerPack,
stickerPackId: stickerPack.id,
});
}}
/>
Expand Down
Loading