Skip to content

Commit

Permalink
feat: add smoelen (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
sverben authored Apr 29, 2024
1 parent 4ad8233 commit 2a66290
Show file tree
Hide file tree
Showing 9 changed files with 275 additions and 47 deletions.
9 changes: 9 additions & 0 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import CustomNavigationBar from "./src/components/navbar";
import SlotScreen from "./src/screens/feed/slot";
import { createStackNavigator } from "@react-navigation/stack";
import AlbumScreen from "./src/screens/media/album";
import SmoelScreen from "./src/screens/media/smoel";
import { Item } from "./src/__generated__/media";
import SlidesScreen from "./src/screens/media/slides";
import { useColorScheme } from "react-native";
Expand All @@ -41,6 +42,7 @@ export type StackParamList = {
Home: undefined;
Slot: { slot: number; title: string };
Album: { album: string; title: string };
Smoel: { smoel: string; title: string };
Slides: { items: Item[]; item: number };
Web: { source: string; title: string };
Search: undefined;
Expand Down Expand Up @@ -96,6 +98,13 @@ export default function App() {
title: route.params.title,
})}
/>
<Stack.Screen
name={"Smoel"}
component={SmoelScreen}
options={({ route }) => ({
title: route.params.title,
})}
/>
<Stack.Screen name={"Slides"} component={SlidesScreen} />
<Stack.Screen
name={"Web"}
Expand Down
77 changes: 76 additions & 1 deletion src/__generated__/media.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions src/auth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { jwtDecode } from "jwt-decode";
import * as SecureStore from "expo-secure-store";
import * as AuthSession from "expo-auth-session";
import { Alert, Platform, SafeAreaView, StyleSheet, View } from "react-native";
import { Button, useTheme, Text } from "react-native-paper";
import { Button, useTheme, Text, ActivityIndicator } from "react-native-paper";
import * as WebBrowser from "expo-web-browser";
import { DiscoveryDocument, TokenError } from "expo-auth-session";
import { DiscoveryDocument } from "expo-auth-session";
import * as Device from "expo-device";
import * as Notifications from "expo-notifications";
import Constants from "expo-constants";
Expand Down Expand Up @@ -330,7 +330,7 @@ export function AuthProvider({ children }: { children: JSX.Element }) {
backgroundColor: theme.colors.primaryContainer,
}}
>
<Text>Loading...</Text>
<ActivityIndicator animating={true} />
</View>
))}
</AuthContext.Provider>
Expand Down
34 changes: 34 additions & 0 deletions src/components/media/albums.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useAtom } from "jotai";
import { apiAtom } from "../../stores/media";
import { AlbumList } from "../../__generated__/media";
import { useEffect, useState } from "react";
import { FlatList } from "react-native";
import Preview from "./preview";
import { ActivityIndicator } from "react-native-paper";

export default function Albums() {
const [albums, setAlbums] = useState<AlbumList[] | null>(null);
const [api] = useAtom(apiAtom);

useEffect(() => {
async function getAlbums() {
if (!api) return;

const { data: albums } = await api.albums.getAlbums();
setAlbums(albums.sort((a, b) => a.order - b.order));
}

getAlbums().then();
}, [api]);

if (!albums) return <ActivityIndicator animating={true} />;
return (
<FlatList
style={{ margin: 5 }}
data={albums}
numColumns={2}
keyExtractor={(item) => item.id}
renderItem={({ item }) => <Preview mode={"album"} album={item} />}
/>
);
}
27 changes: 18 additions & 9 deletions src/components/media/preview.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,31 @@
import { AlbumList } from "../../__generated__/media";
import { Image, StyleSheet, TouchableOpacity } from "react-native";
import { AlbumList, SmoelAlbumList } from "../../__generated__/media";
import { Image, TouchableOpacity, StyleSheet } from "react-native";
import { Text } from "react-native-paper";
import { useNavigation } from "@react-navigation/native";
import { NativeStackNavigationProp } from "react-native-screens/native-stack";
import { StackParamList } from "../../../App";

type NavigationProps = NativeStackNavigationProp<StackParamList>;

export default function Preview({ album }: { album: AlbumList }) {
export default function Preview({
album,
mode,
}: {
album: AlbumList | SmoelAlbumList;
mode: "smoel" | "album";
}) {
const navigation = useNavigation<NavigationProps>();

function navigate() {
if (mode === "album") {
navigation.navigate("Album", { album: album.id, title: album.name });
} else {
navigation.navigate("Smoel", { smoel: album.id, title: album.name });
}
}

return (
<TouchableOpacity
style={styles.container}
onPress={() =>
navigation.navigate("Album", { album: album.id, title: album.name })
}
>
<TouchableOpacity style={styles.container} onPress={navigate}>
<Image source={{ uri: album.preview?.cover_path }} style={styles.image} />
<Text variant={"titleSmall"}>{album.name}</Text>
</TouchableOpacity>
Expand Down
34 changes: 34 additions & 0 deletions src/components/media/smoelen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useAtom } from "jotai";
import { apiAtom } from "../../stores/media";
import { SmoelAlbumList } from "../../__generated__/media";
import { useEffect, useState } from "react";
import { FlatList } from "react-native";
import { ActivityIndicator } from "react-native-paper";
import Preview from "./preview";

export default function Smoelen() {
const [smoelen, setSmoelen] = useState<SmoelAlbumList[] | null>(null);
const [api] = useAtom(apiAtom);

useEffect(() => {
async function getSmoelen() {
if (!api) return;

const { data: albums } = await api.smoelen.getSmoelen();
setSmoelen(albums);
}

getSmoelen().then();
}, [api]);

if (!smoelen) return <ActivityIndicator animating={true} />;
return (
<FlatList
style={{ margin: 5 }}
data={smoelen}
numColumns={2}
keyExtractor={(item) => item.id}
renderItem={({ item }) => <Preview mode={"smoel"} album={item} />}
/>
);
}
4 changes: 2 additions & 2 deletions src/screens/media/album.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { useAtom } from "jotai";
import { apiAtom } from "../../stores/media";
import { StackScreenProps } from "@react-navigation/stack";
import { StackParamList } from "../../../App";
import { Appbar, Text } from "react-native-paper";
import { ActivityIndicator, Appbar } from "react-native-paper";
import { useNavigation } from "@react-navigation/native";
import { NativeStackNavigationProp } from "react-native-screens/native-stack";
import { NativeStackNavigationEventMap } from "react-native-screens/lib/typescript/native-stack/types";
Expand Down Expand Up @@ -119,7 +119,7 @@ export default function AlbumScreen({ route }: Props) {
navigation.navigate("Slides", { items: album.items, item: image });
}

if (!album) return <Text>Loading...</Text>;
if (!album) return <ActivityIndicator animating={true} />;
return (
<FlatList
numColumns={3}
Expand Down
70 changes: 38 additions & 32 deletions src/screens/media/media.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,22 @@ import { useContext, useEffect, useState } from "react";
import AuthContext, { Authed } from "../../auth";
import { useAtom } from "jotai";
import { apiAtom, getApi } from "../../stores/media";
import { AlbumList } from "../../__generated__/media";
import { FlatList, StyleSheet, View } from "react-native";
import Preview from "../../components/media/preview";
import { Appbar, Button, Text } from "react-native-paper";
import { StyleSheet } from "react-native";
import { Appbar, SegmentedButtons } from "react-native-paper";
import { useTheme } from "@react-navigation/native";
import Albums from "../../components/media/albums";
import Smoelen from "../../components/media/smoelen";

enum Page {
ALBUMS = "albums",
SMOELEN = "smoelen",
}

export default function MediaScreen() {
const authState = useContext(AuthContext);
const [api, setApi] = useAtom(apiAtom);
const [albums, setAlbums] = useState<AlbumList[]>([]);
const [page, setPage] = useState<Page>(Page.ALBUMS);
const theme = useTheme();

useEffect(() => {
if (authState.authenticated !== Authed.AUTHENTICATED) {
Expand All @@ -21,39 +28,32 @@ export default function MediaScreen() {
setApi(getApi(token));
});
}, [authState]);
useEffect(() => {
async function getAlbums() {
if (!api) return;

const { data: albums } = await api.albums.getAlbums();
setAlbums(albums.sort((a, b) => a.order - b.order));
}

getAlbums().then();
}, [api]);

return (
<>
<Appbar.Header>
<Appbar.Content title={"Media"} />
</Appbar.Header>
{authState.authenticated === Authed.GUEST && (
<View style={styles.unauthenticated}>
<Text>Je moet eerst inloggen om deze pagina te bekijken</Text>
<Button mode={"contained-tonal"} onPress={authState.login}>
Log in
</Button>
</View>
)}
{authState.authenticated === Authed.AUTHENTICATED && (
<FlatList
style={{ margin: 5 }}
data={albums}
numColumns={2}
keyExtractor={(item) => item.id}
renderItem={({ item }) => <Preview album={item} />}
/>
)}
{page === Page.ALBUMS && <Albums />}
{page === Page.SMOELEN && <Smoelen />}
<SegmentedButtons
style={{
...styles.pageSelector,
backgroundColor: theme.colors.background,
}}
value={page}
onValueChange={(page) => setPage(page as Page)}
buttons={[
{
value: Page.ALBUMS,
label: "Albums",
},
{
value: Page.SMOELEN,
label: "Smoelen ✨",
},
]}
/>
</>
);
}
Expand All @@ -67,4 +67,10 @@ const styles = StyleSheet.create({
padding: 20,
textAlign: "center",
},
pageSelector: {
position: "absolute",
bottom: 0,
margin: 15,
borderRadius: 50,
},
});
Loading

0 comments on commit 2a66290

Please sign in to comment.