1
0
mirror of https://github.com/tooot-app/app synced 2025-06-05 22:19:13 +02:00

619 restructure local storage (#628)

* To MMKV migration working

* POC migrated font size settings

* Moved settings to mmkv

* Fix typos

* Migrated contexts slice

* Migrated app slice

* POC instance emoji update

* Migrated drafts

* Migrated simple instance properties

* All migrated!

* Re-structure files

* Tolerant of undefined settings

* Can properly logging in and out including empty state
This commit is contained in:
xmflsct
2022-12-28 23:41:36 +01:00
committed by GitHub
parent 71ccb4a93c
commit 1ea6aff328
214 changed files with 2151 additions and 3694 deletions

View File

@ -0,0 +1,5 @@
export const androidActionSheetStyles = (colors: any) => ({
containerStyle: { backgroundColor: colors.backgroundDefault },
textStyle: { color: colors.primaryDefault },
titleTextStyle: { color: colors.secondary }
})

View File

@ -0,0 +1,18 @@
import * as WebBrowser from 'expo-web-browser'
import { Platform } from 'react-native'
const browserPackage = async (): Promise<{ browserPackage?: string }> => {
if (Platform.OS === 'android') {
const tabsSupportingBrowsers = await WebBrowser.getCustomTabsSupportingBrowsersAsync()
return {
browserPackage:
tabsSupportingBrowsers?.preferredBrowserPackage ||
tabsSupportingBrowsers.browserPackages[0] ||
tabsSupportingBrowsers.servicePackages[0]
}
} else {
return {}
}
}
export default browserPackage

View File

@ -0,0 +1,49 @@
import Constants from 'expo-constants'
const mapEnvironment = <T = unknown>({
release,
candidate,
development
}: {
release: T
candidate?: T
development?: T
}): T => {
if (isDevelopment) {
if (development) {
return development
} else {
throw new Error('Development environment but no development handler')
}
}
if (isCandidate) {
if (candidate) {
return candidate
} else {
throw new Error('Candidate environment but no candidate handler')
}
}
if (isRelease) {
return release
}
throw new Error(
`Environment not set. Please set the environment in the Expo project settings.`
)
}
const isDevelopment =
__DEV__ ||
['development'].some(channel => (Constants.expoConfig?.extra?.environment) === channel)
const isCandidate = ['candidate'].some(channel =>
(Constants.expoConfig?.extra?.environment) === channel
)
const isRelease = ['release'].some(channel =>
(Constants.expoConfig?.extra?.environment) === channel
)
export { mapEnvironment, isDevelopment, isCandidate, isRelease }

View File

@ -0,0 +1,10 @@
import detect from 'react-native-language-detection';
const detectLanguage = async (
text: string
): Promise<{ language: string; confidence: number } | null> => {
const possibleLanguages = await detect(text).catch(() => {})
return possibleLanguages ? possibleLanguages.filter(lang => lang.confidence > 0.5)?.[0] : null
}
export default detectLanguage

View File

@ -0,0 +1,58 @@
import { getAccountStorage } from '@utils/storage/actions'
const features = [
{
feature: 'account_follow_notify',
version: 3.3
},
{
feature: 'notification_type_status',
version: 3.3
},
{
feature: 'account_return_suspended',
version: 3.3
},
{
feature: 'edit_post',
version: 3.5
},
{
feature: 'deprecate_auth_follow',
version: 3.5
},
{
feature: 'notification_type_update',
version: 3.5
},
{
feature: 'notification_type_admin_signup',
version: 3.5
},
{
feature: 'notification_types_positive_filter',
version: 3.5
},
{
feature: 'trends_new_path',
version: 3.5
},
{
feature: 'follow_tags',
version: 4.0
},
{
feature: 'notification_type_admin_report',
version: 4.0
},
{
feature: 'filter_server_side',
version: 4.0
}
]
export const featureCheck = (feature: string): boolean => {
const version = getAccountStorage.string('version')
return !!features.filter(f => f.feature === feature).filter(f => parseFloat(version) >= f.version)
?.length
}

View File

@ -0,0 +1,54 @@
[
{
"feature": "account_follow_notify",
"version": 3.3
},
{
"feature": "notification_type_status",
"version": 3.3
},
{
"feature": "account_return_suspended",
"version": 3.3
},
{
"feature": "edit_post",
"version": 3.5
},
{
"feature": "deprecate_auth_follow",
"version": 3.5
},
{
"feature": "notification_type_update",
"version": 3.5
},
{
"feature": "notification_type_admin_signup",
"version": 3.5
},
{
"feature": "notification_types_positive_filter",
"version": 3.5
},
{
"feature": "trends_new_path",
"version": 3.5
},
{
"feature": "follow_tags",
"version": 4.0
},
{
"feature": "notification_type_admin_report",
"version": 4.0
},
{
"feature": "filter_server_side",
"version": 4.0
},
{
"feature": "instance_new_path",
"version": 4.0
}
]

View File

@ -0,0 +1,9 @@
import { getGlobalStorage } from '@utils/storage/actions'
import * as Localization from 'expo-localization'
import { Platform } from 'react-native'
const getLanguage = (): string | undefined => {
return Platform.OS === 'ios' ? Localization.locale : getGlobalStorage.string('app.language')
}
export default getLanguage

View File

@ -0,0 +1,9 @@
export const PERMISSION_MANAGE_REPORTS = 0x0000000000000010
export const PERMISSION_MANAGE_USERS = 0x0000000000000400
export const checkPermission = (permission: number, permissions?: string | number): boolean =>
permissions
? !!(
(typeof permissions === 'string' ? parseInt(permissions || '0') : permissions) & permission
)
: false

View File

@ -0,0 +1,21 @@
import * as htmlparser2 from 'htmlparser2'
const removeHTML = (text: string): string => {
let raw: string = ''
const parser = new htmlparser2.Parser({
ontext: (text: string) => {
raw = raw + text
},
onclosetag: (tag: string) => {
if (['p', 'br'].includes(tag)) raw = raw + `\n`
}
})
parser.write(text)
parser.end()
return raw
}
export default removeHTML

View File

@ -0,0 +1,62 @@
import { getAccountStorage } from '@utils/storage/actions'
const getHost = (url: unknown): string | undefined | null => {
if (typeof url !== 'string') return undefined
const matches = url.match(/^(?:https?:\/\/)?(?:[^@\/\n]+@)?(?:www\.)?([^:\/\n]+)/i)
return matches?.[1]
}
const matchStatus = (
url: string
): { id: string; style: 'default' | 'pretty'; sameInstance: boolean } | null => {
// https://social.xmflsct.com/web/statuses/105590085754428765 <- default
// https://social.xmflsct.com/@tooot/105590085754428765 <- pretty
const matcherStatus = new RegExp(/(https?:\/\/)?([^\/]+)\/(web\/statuses|@.+)\/([0-9]+)/)
const matched = url.match(matcherStatus)
if (matched) {
const hostname = matched[2]
const style = matched[3] === 'web/statuses' ? 'default' : 'pretty'
const id = matched[4]
const sameInstance = hostname === getAccountStorage.string('auth.domain')
return { id, style, sameInstance }
}
return null
}
const matchAccount = (
url: string
):
| { id: string; style: 'default'; sameInstance: boolean }
| { username: string; style: 'pretty'; sameInstance: boolean }
| null => {
// https://social.xmflsct.com/web/accounts/14195 <- default
// https://social.xmflsct.com/web/@tooot <- pretty ! cannot be searched on the same instance
// https://social.xmflsct.com/@tooot <- pretty
const matcherAccount = new RegExp(
/(https?:\/\/)?([^\/]+)(\/web\/accounts\/([0-9]+)|\/web\/(@.+)|\/(@.+))/
)
const matched = url.match(matcherAccount)
if (matched) {
const hostname = matched[2]
const account = matched.filter(i => i).reverse()?.[0]
if (account) {
const style = account.startsWith('@') ? 'pretty' : 'default'
const sameInstance = hostname === getAccountStorage.string('auth.domain')
return style === 'default'
? { id: account, style, sameInstance }
: { username: account, style, sameInstance }
} else {
return null
}
}
return null
}
export { getHost, matchStatus, matchAccount }