Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 6 additions & 1 deletion global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ interface User {

interface Paged<T> {
items: T[];
next_page: string;
next_page: string | null;
}

interface Post {
Expand Down Expand Up @@ -94,4 +94,9 @@ interface Reply {
score: number;
}

interface SavedContentId {
id: number;
type: "post" | "reply";
}

type Refreshable<T> = [T, boolean, () => void];
14 changes: 13 additions & 1 deletion screens/ModalScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { useReplies } from "../hooks/lotide";
import useTheme from "../hooks/useTheme";
import { RootStackScreenProps } from "../types";
import LotideContext from "../store/LotideContext";
import { savedContentIds } from "../services/StorageService";

export default function ModalScreen({
navigation,
Expand Down Expand Up @@ -48,7 +49,18 @@ export default function ModalScreen({
showCommunityHost
/>
<View style={styles.actions}>
<Icon name="bookmark-outline" size={25} color={theme.text} />
<Pressable
hitSlop={5}
onPress={() => {
savedContentIds
.store(ctx, post.id, "post")
.then(async () =>
console.log(await savedContentIds.query(ctx)),
);
}}
>
<Icon name="bookmark-outline" size={25} color={theme.text} />
</Pressable>
<Pressable
hitSlop={5}
onPress={() => {
Expand Down
42 changes: 42 additions & 0 deletions services/StorageService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,38 @@ export const lotideContextKV = {
},
};

export const savedContentIds = {
async store(ctx: LotideContext, id: number, type: "post" | "reply") {
const [pageId, store] = await this.query(ctx);
store.items = [{ id, type }, ...store.items];
if (store.items.length > 3) {
store.next_page = Math.random().toString(16).substr(2, 16);
serviceKV.store("@content_id_current_pages", ctx.apiUrl, store.next_page);
}
AsyncStorage.setItem(`@content_id_page[${pageId}]`, JSON.stringify(store));
},

async query(
ctx: LotideContext,
page?: string,
): Promise<[string, Paged<SavedContentId>]> {
const pageId = page || (await this.getCurrentPage(ctx));
const storeStr = await AsyncStorage.getItem(`@content_id_page[${pageId}]`);
const store = storeStr
? JSON.parse(storeStr)
: { items: [], next_page: null };
return [pageId, store];
},

async getCurrentPage(ctx: LotideContext): Promise<string> {
return await serviceKV.queryOrStore(
"@content_id_current_pages",
ctx.apiUrl,
() => Math.random().toString(16).substr(2, 16),
);
},
};

const serviceKV = {
async store<T>(path: string, k: string, v: T) {
const storeStr = await AsyncStorage.getItem(path);
Expand All @@ -45,6 +77,16 @@ const serviceKV = {
return storeStr ? JSON.parse(storeStr)[k] : undefined;
},

async queryOrStore<T>(path: string, k: string, v: () => T): Promise<T> {
const value = await this.query<T>(path, k);
if (value === undefined) {
this.store(path, k, v());
return v();
} else {
return value;
}
},

async listKeys(path: string): Promise<string[]> {
const storeStr = await AsyncStorage.getItem(path);
const store = storeStr ? JSON.parse(storeStr) : {};
Expand Down