Add startup update-confirmation alert with plugin details
This commit is contained in:
parent
2cf998542f
commit
a7385a58df
4 changed files with 159 additions and 6 deletions
|
|
@ -160,6 +160,8 @@ export interface RepoUpdate {
|
|||
installed: string
|
||||
available: string
|
||||
channel: string
|
||||
/** Repository URL this update was found in, added by {@link listAllUpdates}. */
|
||||
repo?: string
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -227,7 +229,7 @@ export async function listAllUpdates(): Promise<{
|
|||
.map(repo =>
|
||||
listUpdates(repo.url).then(
|
||||
result => {
|
||||
updates.push(...result)
|
||||
updates.push(...result.map(u => ({ ...u, repo: repo.url })))
|
||||
},
|
||||
error => {
|
||||
errors.push({ url: repo.url, error })
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
import { Design } from '@revenge-mod/discord/design'
|
||||
import {
|
||||
listRepoPlugins,
|
||||
type RepoPluginListing,
|
||||
type RepoUpdate,
|
||||
} from '@revenge-mod/plugins/_/repositories'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { View } from 'react-native'
|
||||
|
||||
const { AlertModal, AlertActionButton, Text } = Design
|
||||
|
||||
interface UpdateDetail {
|
||||
id: string
|
||||
name: string
|
||||
author: string
|
||||
installed: string
|
||||
available: string
|
||||
channel: string
|
||||
}
|
||||
|
||||
export default function PluginUpdatesFoundAlert({
|
||||
updates,
|
||||
action,
|
||||
}: {
|
||||
updates: RepoUpdate[]
|
||||
action: () => Promise<void>
|
||||
}) {
|
||||
const [details, setDetails] = useState<UpdateDetail[] | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
const repoMap = new Map<string, RepoUpdate[]>()
|
||||
for (const update of updates) {
|
||||
const repo = update.repo!
|
||||
if (!repoMap.has(repo)) repoMap.set(repo, [])
|
||||
repoMap.get(repo)!.push(update)
|
||||
}
|
||||
|
||||
const allDetails: UpdateDetail[] = []
|
||||
|
||||
Promise.all(
|
||||
[...repoMap.entries()].map(async ([repo, repoUpdates]) => {
|
||||
let listings: RepoPluginListing[]
|
||||
try {
|
||||
listings = await listRepoPlugins(repo)
|
||||
} catch {
|
||||
listings = []
|
||||
}
|
||||
|
||||
for (const update of repoUpdates) {
|
||||
const listing = listings.find(l => l.id === update.id)
|
||||
allDetails.push({
|
||||
id: update.id,
|
||||
name: listing?.name ?? update.id,
|
||||
author: listing?.author ?? 'Unknown',
|
||||
installed: update.installed,
|
||||
available: update.available,
|
||||
channel: update.channel,
|
||||
})
|
||||
}
|
||||
}),
|
||||
).then(() => setDetails(allDetails))
|
||||
}, [updates])
|
||||
|
||||
return (
|
||||
<AlertModal
|
||||
title="Updates Found"
|
||||
content={
|
||||
<Text color="text-default">
|
||||
The following plugins have updates available:
|
||||
</Text>
|
||||
}
|
||||
extraContent={
|
||||
<View style={{ paddingTop: 8 }}>
|
||||
{details === null ? (
|
||||
<Text color="text-muted">Loading...</Text>
|
||||
) : (
|
||||
details.map(detail => (
|
||||
<View
|
||||
key={detail.id}
|
||||
style={{ marginBottom: 12 }}
|
||||
>
|
||||
<Text
|
||||
variant="text-md/semibold"
|
||||
color="text-default"
|
||||
>
|
||||
{detail.name}
|
||||
</Text>
|
||||
<Text color="text-muted">
|
||||
{detail.installed} → {detail.available} (
|
||||
{detail.channel})
|
||||
</Text>
|
||||
<Text color="text-muted">
|
||||
by {detail.author}
|
||||
</Text>
|
||||
</View>
|
||||
))
|
||||
)}
|
||||
</View>
|
||||
}
|
||||
actions={
|
||||
<>
|
||||
<AlertActionButton
|
||||
onPress={action}
|
||||
text="Update"
|
||||
variant="primary"
|
||||
/>
|
||||
<AlertActionButton text="Not now" variant="secondary" />
|
||||
</>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
@ -7,12 +7,15 @@ import {
|
|||
registerInternalPlugin,
|
||||
} from '@revenge-mod/plugins/_'
|
||||
import {
|
||||
listAllUpdates,
|
||||
refreshAllRepos,
|
||||
updateAllPlugins,
|
||||
} from '@revenge-mod/plugins/_/repositories'
|
||||
import { lookupGeneratedIconComponent } from '@revenge-mod/utils/discord'
|
||||
import pluginSettings from '../settings'
|
||||
import { showPluginUpdatesFoundAlert } from './utils/alerts'
|
||||
import { addDefaultRepoIfNeeded } from './repos'
|
||||
import { showErrorToast } from './utils/repos'
|
||||
import type { JsonStorage } from '@revenge-mod/json-storage'
|
||||
import type { PluginApi } from '@revenge-mod/plugins/types'
|
||||
|
||||
|
|
@ -78,12 +81,37 @@ function autoUpdateService(settings: Storage) {
|
|||
setTimeout(async () => {
|
||||
try {
|
||||
const { errors } = await refreshAllRepos()
|
||||
await updateAllPlugins()
|
||||
|
||||
if (!errors.length)
|
||||
await api.jsonStorage.set({
|
||||
lastUpdateCheck: Date.now(),
|
||||
if (errors.length) {
|
||||
ToastActionCreators.open({
|
||||
key: 'PLUGIN_UPDATE_CHECK_FAILED',
|
||||
content: 'Failed to refresh some plugin repositories',
|
||||
IconComponent: CircleXIconComponent,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const { updates } = await listAllUpdates()
|
||||
await api.jsonStorage.set({ lastUpdateCheck: Date.now() })
|
||||
|
||||
if (!updates.length) return
|
||||
|
||||
showPluginUpdatesFoundAlert(updates, async () => {
|
||||
const { errors: updateErrors } = await updateAllPlugins()
|
||||
|
||||
if (updateErrors.length) {
|
||||
showErrorToast(
|
||||
updateErrors
|
||||
.map(e => `${e.id}: ${e.error}`)
|
||||
.join('\n'),
|
||||
)
|
||||
} else {
|
||||
ToastActionCreators.open({
|
||||
key: 'PLUGIN_UPDATES_INSTALLED',
|
||||
content: 'Plugins will update on the next reload',
|
||||
})
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
ToastActionCreators.open({
|
||||
key: 'PLUGIN_UPDATE_CHECK_FAILED',
|
||||
|
|
|
|||
|
|
@ -13,8 +13,9 @@ import PluginHasDependentsAlert from '../components/PluginHasDependentsAlert'
|
|||
import PluginMissingDependenciesAlert from '../components/PluginMissingDependenciesAlert'
|
||||
import PluginStatesProvider from '../components/PluginStateProvider'
|
||||
import PluginUninstallConfirmationAlert from '../components/PluginUninstallConfirmationAlert'
|
||||
import PluginUpdatesFoundAlert from '../components/PluginUpdatesFoundAlert'
|
||||
import RepoRemoveConfirmationAlert from '../components/RepoRemoveConfirmationAlert'
|
||||
import type { Repo } from '@revenge-mod/plugins/_/repositories'
|
||||
import type { Repo, RepoUpdate } from '@revenge-mod/plugins/_/repositories'
|
||||
import type { AnyPlugin } from '@revenge-mod/plugins/_'
|
||||
|
||||
export function showPluginClearDataConfirmation(
|
||||
|
|
@ -134,3 +135,13 @@ export function showPluginHasDependentsAlert(
|
|||
</PluginStatesProvider>,
|
||||
)
|
||||
}
|
||||
|
||||
export function showPluginUpdatesFoundAlert(
|
||||
updates: RepoUpdate[],
|
||||
action: () => Promise<void>,
|
||||
) {
|
||||
AlertActionCreators.openAlert(
|
||||
'plugin-updates-found',
|
||||
<PluginUpdatesFoundAlert updates={updates} action={action} />,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue