feat(plugins/settings.plugins): restore default plugin repo when needed
This commit is contained in:
parent
da08b94f76
commit
9e2ac7185d
5 changed files with 82 additions and 30 deletions
|
|
@ -79,6 +79,7 @@ export default async function build(dev = Dev, log = true) {
|
|||
.trim(),
|
||||
),
|
||||
__DEV__: String(dev),
|
||||
// __BUILD_DEFAULT_PLUGIN_REPOSITORY_URL__: ...,
|
||||
|
||||
// See types/build.d.ts for what these flags do
|
||||
__BUILD_FLAG_DEBUG_MODULE_LOOKUPS__: String(dev),
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import {
|
|||
refreshSettingsNavigator,
|
||||
refreshSettingsOverviewScreen,
|
||||
} from '@revenge-mod/discord/modules/settings'
|
||||
import { JsonStorageUpdateMode } from '@revenge-mod/json-storage'
|
||||
import {
|
||||
InternalPluginFlags,
|
||||
isPluginStartedLate,
|
||||
|
|
@ -16,11 +17,14 @@ import {
|
|||
} from '@revenge-mod/plugins/_/repositories'
|
||||
import { lookupGeneratedIconComponent } from '@revenge-mod/utils/discord'
|
||||
import pluginSettings from '../settings'
|
||||
import { addDefaultRepoIfNeeded } from './repos'
|
||||
import type { JsonStorage } from '@revenge-mod/json-storage'
|
||||
import type { PluginApi } from '@revenge-mod/plugins/types'
|
||||
|
||||
export interface Storage {
|
||||
autoUpdate: boolean
|
||||
lastUpdateCheck?: number
|
||||
defaultRepoRestored?: boolean
|
||||
}
|
||||
|
||||
const OUTDATED_THRESHOLD = 24 * 60 * 60 * 1000 // 1 day
|
||||
|
|
@ -65,32 +69,8 @@ registerInternalPlugin<{ jsonStorage: Storage }>(
|
|||
}
|
||||
|
||||
const settings = await api.jsonStorage.get()
|
||||
if (!settings.autoUpdate) return
|
||||
if (
|
||||
settings.lastUpdateCheck !== undefined &&
|
||||
Date.now() - settings.lastUpdateCheck <= OUTDATED_THRESHOLD
|
||||
)
|
||||
return
|
||||
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
const { errors } = await refreshAllRepos()
|
||||
await updateAllPlugins()
|
||||
|
||||
if (!errors.length)
|
||||
await api.jsonStorage.set({
|
||||
lastUpdateCheck: Date.now(),
|
||||
})
|
||||
} catch (e) {
|
||||
ToastActionCreators.open({
|
||||
key: 'PLUGIN_UPDATE_CHECK_FAILED',
|
||||
content: 'Failed to check for plugin updates',
|
||||
IconComponent: CircleXIconComponent,
|
||||
})
|
||||
|
||||
api.logger.warn('Failed to check for plugin updates', e)
|
||||
}
|
||||
}, AUTO_UPDATE_CHECK_DELAY)
|
||||
autoUpdateService(settings)
|
||||
defaultRepoRestoreService(settings, api.jsonStorage)
|
||||
},
|
||||
stop({ cleanup }) {
|
||||
cleanup(refreshSettingsOverviewScreen, refreshSettingsNavigator)
|
||||
|
|
@ -100,5 +80,47 @@ registerInternalPlugin<{ jsonStorage: Storage }>(
|
|||
InternalPluginFlags.Internal | InternalPluginFlags.Essential,
|
||||
)
|
||||
|
||||
function autoUpdateService(settings: Storage) {
|
||||
if (!settings.autoUpdate) return
|
||||
if (
|
||||
settings.lastUpdateCheck !== undefined &&
|
||||
Date.now() - settings.lastUpdateCheck <= OUTDATED_THRESHOLD
|
||||
)
|
||||
return
|
||||
|
||||
setTimeout(async () => {
|
||||
try {
|
||||
const { errors } = await refreshAllRepos()
|
||||
await updateAllPlugins()
|
||||
|
||||
if (!errors.length)
|
||||
await api.jsonStorage.set({
|
||||
lastUpdateCheck: Date.now(),
|
||||
})
|
||||
} catch (e) {
|
||||
ToastActionCreators.open({
|
||||
key: 'PLUGIN_UPDATE_CHECK_FAILED',
|
||||
content: 'Failed to check for plugin updates',
|
||||
IconComponent: CircleXIconComponent,
|
||||
})
|
||||
|
||||
api.logger.warn('Failed to check for plugin updates', e)
|
||||
}
|
||||
}, AUTO_UPDATE_CHECK_DELAY)
|
||||
}
|
||||
|
||||
// TODO: Add UI for this?
|
||||
function defaultRepoRestoreService(
|
||||
settings: Storage,
|
||||
storage: JsonStorage<Storage>,
|
||||
) {
|
||||
if (!settings.defaultRepoRestored) addDefaultRepoIfNeeded()
|
||||
storage.subscribe((update, mode) => {
|
||||
// If user cleared storage, restore the default repo if needed
|
||||
if (mode === JsonStorageUpdateMode.Load && !update.defaultRepoRestored)
|
||||
addDefaultRepoIfNeeded()
|
||||
})
|
||||
}
|
||||
|
||||
// Exposed for the Advanced settings screen (auto-update toggle)
|
||||
export let api: PluginApi<{ jsonStorage: Storage }>
|
||||
|
|
|
|||
29
src/plugins/start/settings.plugins/repos.ts
Normal file
29
src/plugins/start/settings.plugins/repos.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import {
|
||||
listRepos,
|
||||
refreshRepo,
|
||||
setRepos,
|
||||
} from '@revenge-mod/plugins/_/repositories'
|
||||
import { noop } from '@revenge-mod/utils/callback'
|
||||
import type { Repo, RepoConfigEntry } from '@revenge-mod/plugins/_/repositories'
|
||||
|
||||
export async function addDefaultRepoIfNeeded() {
|
||||
if (!__BUILD_DEFAULT_PLUGIN_REPOSITORY_URL__) return
|
||||
|
||||
const repos = await listRepos()
|
||||
if (
|
||||
repos.some(repo => repo.url === __BUILD_DEFAULT_PLUGIN_REPOSITORY_URL__)
|
||||
)
|
||||
return
|
||||
|
||||
const userRepos = toConfig(repos.filter(repo => !repo.internal))
|
||||
await setRepos([
|
||||
{ url: __BUILD_DEFAULT_PLUGIN_REPOSITORY_URL__, enabled: true },
|
||||
...userRepos,
|
||||
])
|
||||
|
||||
await refreshRepo(__BUILD_DEFAULT_PLUGIN_REPOSITORY_URL__).catch(noop)
|
||||
}
|
||||
|
||||
export function toConfig(list: Repo[]): RepoConfigEntry[] {
|
||||
return list.map(({ url, enabled }) => ({ url, enabled }))
|
||||
}
|
||||
|
|
@ -19,6 +19,7 @@ import { lookupGeneratedIconComponent } from '@revenge-mod/utils/discord'
|
|||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { ScrollView, View } from 'react-native'
|
||||
import { api } from '..'
|
||||
import { toConfig } from '../repos'
|
||||
import { formatBytes, messageOf, showErrorToast } from '../utils/repos'
|
||||
import type {
|
||||
DownloadProgressEvent,
|
||||
|
|
@ -44,10 +45,6 @@ const UpIconComponent = lookupGeneratedIconComponent('ArrowSmallUpIcon')!
|
|||
const DownIconComponent = lookupGeneratedIconComponent('ArrowSmallDownIcon')!
|
||||
const TrashIconComponent = lookupGeneratedIconComponent('TrashIcon')!
|
||||
|
||||
function toConfig(list: Repo[]): RepoConfigEntry[] {
|
||||
return list.map(({ url, enabled }) => ({ url, enabled }))
|
||||
}
|
||||
|
||||
function repoSubLabel(repo: Repo, state?: RepoStateEvent['state']) {
|
||||
if (state === 'refreshing') return `${repo.url} (refreshing...)`
|
||||
if (state === 'error') return `${repo.url} (refresh failed)`
|
||||
|
|
@ -206,6 +203,8 @@ export default function RevengePluginsAdvancedSettingScreen() {
|
|||
|
||||
const removeRepo = useCallback(
|
||||
async (repo: Repo) => {
|
||||
// TODO: Add warning for default repo removal, user can clear "Plugin Settings" data to restore the default repo
|
||||
|
||||
await commit(toConfig(userRepos.filter(r => r.url !== repo.url)))
|
||||
|
||||
// Plugins installed from the removed repository turn Sideloaded
|
||||
|
|
|
|||
1
types/build.d.ts
vendored
1
types/build.d.ts
vendored
|
|
@ -4,6 +4,7 @@ declare global {
|
|||
const __DEV__: boolean
|
||||
const __BUILD_DISCORD_SERVER_URL__: string
|
||||
const __BUILD_SOURCE_REPOSITORY_URL__: string
|
||||
const __BUILD_DEFAULT_PLUGIN_REPOSITORY_URL__: string | undefined
|
||||
const __BUILD_LICENSE_URL__: string
|
||||
const __BUILD_COMMIT__: string
|
||||
const __BUILD_BRANCH__: string
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue