Skip to content

Commit

Permalink
feat: migrate to MMKV
Browse files Browse the repository at this point in the history
storage speed 📈
  • Loading branch information
Rexogamer committed Jan 1, 2025
1 parent 26a9c34 commit 8272aea
Show file tree
Hide file tree
Showing 46 changed files with 600 additions and 511 deletions.
372 changes: 30 additions & 342 deletions App.tsx

Large diffs are not rendered by default.

37 changes: 23 additions & 14 deletions i18n/getLanguage.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,39 @@
import AsyncStorage from '@react-native-async-storage/async-storage';
import type {ModuleType} from 'i18next';

import { storage } from '@rvmob/lib/storage';

const STORE_LANGUAGE_KEY = 'app.language';

export const languageDetectorPlugin = {
type: 'languageDetector' as ModuleType,
async: true,
init: () => {},
detect: async function (callback: (lang: string) => void) {
detect: function () {
try {
await AsyncStorage.getItem(STORE_LANGUAGE_KEY).then(language => {
if (language) {
return callback(language);
} else {
// TODO: use the device's locale
return 'en';
const settings = JSON.parse(storage.getString('settings') ?? '[]');
for (const setting of settings) {
if (setting.key === STORE_LANGUAGE_KEY) {
return setting.value;
}
});
}
// TODO: use device language
return 'en';
} catch (error) {
console.warn(`[APP] Error reading language: ${error}`);
return 'en';
}
},
cacheUserLanguage: async function (language: string) {
cacheUserLanguage: function (language: string) {
try {
//save a user's language choice in Async storage
await AsyncStorage.setItem(STORE_LANGUAGE_KEY, language);
} catch (error) {}
const settings = JSON.parse(storage.getString('settings') ?? '[]');
for (const setting of settings) {
if (setting.key === STORE_LANGUAGE_KEY) {
const index = settings.indexOf(setting);
settings.splice(index, 1);
}
}
settings.push({key: STORE_LANGUAGE_KEY, value: language});
const newData = JSON.stringify(settings);
storage.set('settings', newData);
} catch (error) {}
},
};
1 change: 1 addition & 0 deletions i18n/strings/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"loading": {
"generic": "Loading…",
"connecting": "Logging in…",
"migrating_settings": "Migrating settings…",
"unknown_state": "Uh oh…",
"unknown_state_body": "Please let the developers know that you saw this (value: {{state}})"
},
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"react-native-drawer-layout": "^4.1.1",
"react-native-gesture-handler": "^2.21.2",
"react-native-get-random-values": "^1.11.0",
"react-native-mmkv": "^3.2.0",
"react-native-reanimated": "3.16.6",
"react-native-reanimated-image-viewer": "^1.0.2",
"react-native-svg": "^15.10.1",
Expand Down
88 changes: 11 additions & 77 deletions src/Generic.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import AsyncStorage from '@react-native-async-storage/async-storage';

import {Client} from 'revolt.js';
import type {API, Channel, Message, Server, User} from 'revolt.js';

import {setLanguage} from '@rvmob-i18n/i18n';
import {languages} from '@rvmob-i18n/languages';
import {DEFAULT_API_URL, LOADING_SCREEN_REMARKS} from '@rvmob/lib/consts';
import {checkNotificationPerms} from '@rvmob/lib/notifications';
import {storage} from '@rvmob/lib/storage';
import {themes} from '@rvmob/lib/themes';
import {
CreateChannelModalProps,
Expand Down Expand Up @@ -65,7 +63,7 @@ export const app = {
setting.type === 'number' ? parseInt(raw as string, 10) || 0 : raw;
return toreturn;
},
set: async (k: string, v: string | boolean | undefined) => {
set: (k: string, v: string | boolean | undefined) => {
try {
const setting = app.settings._fetch(k);
if (!setting) {
Expand All @@ -74,32 +72,31 @@ export const app = {
}
setting.value = v;
setting.onChange && setting.onChange(v);
await app.settings.save();
app.settings.save();
} catch (err) {
console.log(`[SETTINGS] Error setting setting ${k} to ${v}: ${err}`);
}
},
save: async () => {
save: () => {
try {
let out: object[] = [];
for (const s of app.settings.list) {
if (s.value !== undefined) {
out.push({key: s.key, value: s.value});
}
}
await AsyncStorage.setItem('settings', JSON.stringify(out));
storage.set('settings', JSON.stringify(out));
} catch (err) {
console.log(`[SETTINGS] Error saving settings: ${err}`);
}
},
clear: async () => {
clear: () => {
try {
AsyncStorage.setItem('settings', '{}').then(() => {
for (const s of app.settings.list) {
delete s.value;
s.onChange && s.onChange(s.default);
}
});
storage.set('settings', '{}');
for (const s of app.settings.list) {
delete s.value;
s.onChange && s.onChange(s.default);
}
} catch (err) {
console.log(`[SETTINGS] Error saving settings: ${err}`);
}
Expand Down Expand Up @@ -409,69 +406,6 @@ export function setFunction(name: string, func: any) {
app[name] = func;
}

async function initialiseSettings() {
const s = await AsyncStorage.getItem('settings');
console.log(s);
if (s) {
try {
const settings = JSON.parse(s) as {key: string; value: any}[];
settings.forEach(key => {
let st: Setting | undefined;
for (const setting of app.settings.list) {
if (setting.key === key.key) {
st = setting;
}
}
if (st) {
st.value = key.value;
st.onInitialize && st.onInitialize(key.value);
} else {
// ignore known good key
if (key.key !== 'app.lastVersion') {
console.warn(
`[SETTINGS] Unknown setting in AsyncStorage settings: ${key}`,
);
}
}
});
} catch (e) {
console.error(e);
}
}
}

async function getAPIURL() {
await initialiseSettings();
console.log(`[APP] Initialised settings (${new Date().getTime()})`);
let url: string = '';
console.log('[AUTH] Getting API URL...');
const instance = app.settings.get('app.instance') as
| string
| null
| undefined;
if (!instance) {
console.log(
'[AUTH] Unable to fetch app.instance; setting apiURL to default',
);
url = DEFAULT_API_URL;
} else {
console.log(`[AUTH] Fetched app.instance; setting apiURL to ${instance}`);
url = instance;
}
return url;
}

export let client = undefined as unknown as Client;

getAPIURL().then(url => {
const apiURL = url;
console.log(`[AUTH] Creating client... (instance: ${apiURL})`);
client = new Client({
unreads: true,
apiURL: apiURL,
});
});

export var selectedRemark =
LOADING_SCREEN_REMARKS[
Math.floor(Math.random() * LOADING_SCREEN_REMARKS.length)
Expand Down
3 changes: 2 additions & 1 deletion src/LegacyMessageView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {autorun} from 'mobx';

import {Message as RevoltMessage} from 'revolt.js';

import {client, app, setFunction, randomizeRemark} from './Generic';
import {app, setFunction, randomizeRemark} from './Generic';
import { client } from './lib/client';
import {styles} from './Theme';
import {Text} from './components/common/atoms';
import {Message} from './components/common/messaging';
Expand Down
Loading

0 comments on commit 8272aea

Please sign in to comment.