diff --git a/front/bun.lock b/front/bun.lock index 996396dc..586703dc 100644 --- a/front/bun.lock +++ b/front/bun.lock @@ -14,6 +14,7 @@ "react": "^19.0.0", "react-i18next": "^15.4.0", "react-native": "0.77.0", + "react-native-mmkv": "^3.2.0", "react-native-reanimated": "~3.16.7", "react-native-safe-area-context": "5.1.0", "react-native-screens": "4.6.0", @@ -1647,6 +1648,8 @@ "react-native-gesture-handler": ["react-native-gesture-handler@2.21.2", "", { "dependencies": { "@egjs/hammerjs": "^2.0.17", "hoist-non-react-statics": "^3.3.0", "invariant": "^2.2.4", "prop-types": "^15.7.2" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-HcwB225K9aeZ8e/B8nFzEh+2T4EPWTeamO1l/y3PcQ9cyCDYO2zja/G31ITpYRIqkip7XzGs6wI/gnHOQn1LDQ=="], + "react-native-mmkv": ["react-native-mmkv@3.2.0", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-9y7K//1MaU46TFrXkyU0wT5VGk9Y2FDLFV6NPl+z3jTbm2G7SC1UIxneF6CfhSmBX5CfKze9SO7kwDuRx7flpQ=="], + "react-native-reanimated": ["react-native-reanimated@3.16.7", "", { "dependencies": { "@babel/plugin-transform-arrow-functions": "^7.0.0-0", "@babel/plugin-transform-class-properties": "^7.0.0-0", "@babel/plugin-transform-classes": "^7.0.0-0", "@babel/plugin-transform-nullish-coalescing-operator": "^7.0.0-0", "@babel/plugin-transform-optional-chaining": "^7.0.0-0", "@babel/plugin-transform-shorthand-properties": "^7.0.0-0", "@babel/plugin-transform-template-literals": "^7.0.0-0", "@babel/plugin-transform-unicode-regex": "^7.0.0-0", "@babel/preset-typescript": "^7.16.7", "convert-source-map": "^2.0.0", "invariant": "^2.2.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0", "react": "*", "react-native": "*" } }, "sha512-qoUUQOwE1pHlmQ9cXTJ2MX9FQ9eHllopCLiWOkDkp6CER95ZWeXhJCP4cSm6AD4jigL5jHcZf/SkWrg8ttZUsw=="], "react-native-safe-area-context": ["react-native-safe-area-context@5.1.0", "", { "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-Y4vyJX+0HPJUQNVeIJTj2/UOjbSJcB09OEwirAWDrOZ67Lz5p43AmjxSy8nnZft1rMzoh3rcPuonB6jJyHTfCw=="], diff --git a/front/package.json b/front/package.json index b1a05fb7..9840168e 100644 --- a/front/package.json +++ b/front/package.json @@ -24,6 +24,7 @@ "react": "^19.0.0", "react-i18next": "^15.4.0", "react-native": "0.77.0", + "react-native-mmkv": "^3.2.0", "react-native-reanimated": "~3.16.7", "react-native-safe-area-context": "5.1.0", "react-native-screens": "4.6.0", diff --git a/front/packages/models/src/account-internal.ts b/front/packages/models/src/account-internal.ts index 6d5ca73e..28c80260 100644 --- a/front/packages/models/src/account-internal.ts +++ b/front/packages/models/src/account-internal.ts @@ -19,12 +19,9 @@ */ import { Platform } from "react-native"; -import { MMKV } from "react-native-mmkv"; import { type ZodTypeAny, z } from "zod"; import { type Account, AccountP } from "./accounts"; -export const storage = new MMKV(); - const readAccounts = () => { const acc = storage.getString("accounts"); if (!acc) return []; @@ -42,40 +39,6 @@ const writeAccounts = (accounts: Account[]) => { } }; -export const setCookie = (key: string, val?: unknown) => { - let value = typeof val !== "string" ? JSON.stringify(val) : val; - // Remove illegal values from json. There should not be one in the account anyways. - value = value?.replaceAll(";", ""); - const d = new Date(); - // A year - d.setTime(d.getTime() + 365 * 24 * 60 * 60 * 1000); - const expires = value ? `expires=${d.toUTCString()}` : "expires=Thu, 01 Jan 1970 00:00:01 GMT"; - document.cookie = `${key}=${value};${expires};path=/;samesite=strict`; - return null; -}; - -export const readCookie = ( - cookies: string | undefined, - key: string, - parser?: T, -) => { - if (!cookies) return null; - const name = `${key}=`; - const decodedCookie = decodeURIComponent(cookies); - const ca = decodedCookie.split(";"); - for (let i = 0; i < ca.length; i++) { - let c = ca[i]; - while (c.charAt(0) === " ") { - c = c.substring(1); - } - if (c.indexOf(name) === 0) { - const str = c.substring(name.length, c.length); - return parser ? parser.parse(JSON.parse(str)) : str; - } - } - return null; -}; - export const getCurrentAccount = () => { const accounts = readAccounts(); return accounts.find((x) => x.selected); diff --git a/front/src/providers/settings.ts b/front/src/providers/settings.ts new file mode 100644 index 00000000..183929de --- /dev/null +++ b/front/src/providers/settings.ts @@ -0,0 +1,45 @@ +import { MMKV, useMMKVString } from "react-native-mmkv"; +import type { ZodTypeAny } from "zod"; + +export const storage = new MMKV(); + +function toBase64(utf8: string) { + if (typeof window !== "undefined") return window.btoa(utf8); + return Buffer.from(utf8, "utf8").toString("base64"); +} + +function fromBase64(b64: string) { + if (typeof window !== "undefined") return window.atob(b64); + return Buffer.from(b64, "base64").toString("utf8"); +} + +export const setCookie = (key: string, val?: unknown) => { + const value = toBase64(typeof val !== "string" ? JSON.stringify(val) : val); + const d = new Date(); + // A year + d.setTime(d.getTime() + 365 * 24 * 60 * 60 * 1000); + const expires = value ? `expires=${d.toUTCString()}` : "expires=Thu, 01 Jan 1970 00:00:01 GMT"; + document.cookie = `${key}=${value};${expires};path=/;samesite=strict`; +}; + +export const readCookie = ( + cookies: string | undefined, + key: string, + parser?: T, +) => { + if (!cookies) return undefined; + const decodedCookie = decodeURIComponent(cookies); + const ca = decodedCookie.split(";"); + + const name = `${key}=`; + const ret = ca.find((x) => x.trimStart().startsWith(name)); + if (ret === undefined) return undefined; + const str = fromBase64(ret.substring(name.length)); + return parser ? parser.parse(JSON.parse(str)) : str; +}; + +export const useStoreValue = (key: string, parser?: T) => { + const [val] = useMMKVString(key); + if (!val) return val; + return parser ? parser.parse(JSON.parse(val)) : val; +};