@samitouri / QOSami-HFS / commits / 085ea048

admin/home: right-click on check-for-updates

Massimo Melina committed Dec 20, 2023 at 21:55 UTC 085ea048ff1ccd07f2a90075235ae3e7b5da01eb
3 files changed +21 -22
README.md
+1
@@ -185,6 +185,7 @@ Some actions you can take for improved security:
185 - right/ctrl/command click on toggle-all checkbox will invert each checkbox state
186 - Appending `?login=USER:PASSWORD` will automatically log in the browser
187 - Appending `?overwrite` on uploads, will try override the dont_overwrite_uploading configuration, provided you also have delete permission
188 +- Right-click on "check for updates" will let you input a URL of a version to install
189
190 ## Contribute
191
admin/src/HomePage.ts
+13 -16
@@ -3,24 +3,12 @@
3 import { createElement as h, ReactNode, useState } from 'react'
4 import { Box, Button, Card, CardContent, LinearProgress, Link } from '@mui/material'
5 import { apiCall, useApiEx, useApiList } from './api'
6 -import {
7 - Btn,
8 - dontBotherWithKeys,
9 - Flex,
10 - InLink,
11 - LinkBtn,
12 - objSameKeys,
13 - onlyTruthy,
14 - prefix,
15 - REPO_URL,
16 - wait,
17 - wikiLink,
18 - with_
19 -} from './misc'
6 +import { Btn, dontBotherWithKeys, Flex, InLink, LinkBtn, objSameKeys, onlyTruthy, prefix, REPO_URL,
7 + wait, wikiLink, with_ } from './misc'
8 import { BrowserUpdated as UpdateIcon, CheckCircle, Error, Info, Launch, OpenInNew, Warning } from '@mui/icons-material'
9 import md, { replaceStringToReact } from './md'
10 import { state, useSnapState } from './state'
23 -import { alertDialog, confirmDialog, toast } from './dialog'
11 +import { alertDialog, confirmDialog, promptDialog, toast } from './dialog'
12 import { isCertError, isKeyError, suggestMakingCert } from './OptionsPage'
13 import { VfsNode } from './VfsPage'
14 import { Account } from './AccountsPage'
@@ -113,7 +101,16 @@ export default function HomePage() {
101 onClick() {
102 setCheckPlugins(true)
103 return apiCall('check_update').then(x => setUpdates(x.options), alertDialog)
116 - }
104 + },
105 + async onContextMenu(ev) {
106 + ev.preventDefault()
107 + if (!status.updatePossible)
108 + return alertDialog("Automatic update is only for binary versions", 'warning')
109 + const res = await promptDialog("Enter a link to the zip to install")
110 + if (res)
111 + await update(res)
112 + },
113 + title: status.updatePossible && "Right-click if you want to install a zip",
114 }, "Check for updates")
115 : with_(_.find(updates, 'isNewer'), newer =>
116 !updates.length || !status.updatePossible && !newer ? entry('', "No update available")
src/update.ts
+7 -6
@@ -68,14 +68,15 @@ export function updateSupported() {
68 return IS_BINARY
69 }
70
71 -export async function update(tag: string='') {
71 +export async function update(tagOrUrl: string='') {
72 if (!updateSupported()) throw "only binary versions supports automatic update for now"
73 - let updateSource: Readable | false = await localUpdateAvailable() && createReadStream(LOCAL_UPDATE)
73 + let updateSource: Readable | false = tagOrUrl.includes('://') ? await httpStream(tagOrUrl)
74 + : await localUpdateAvailable() && createReadStream(LOCAL_UPDATE)
75 if (!updateSource) {
75 - if (/^\d/.test(tag)) // work even if the tag is passed without the initial 'v' (useful for console commands)
76 - tag = 'v' + tag
77 - const update = !tag ? (await getUpdates())[0]
78 - : await getRepoInfo(HFS_REPO + '/releases/tags/' + tag).catch(e => {
76 + if (/^\d/.test(tagOrUrl)) // work even if the tag is passed without the initial 'v' (useful for console commands)
77 + tagOrUrl = 'v' + tagOrUrl
78 + const update = !tagOrUrl ? (await getUpdates())[0]
79 + : await getRepoInfo(HFS_REPO + '/releases/tags/' + tagOrUrl).catch(e => {
80 if (e.message === '404') console.error("version not found")
81 else throw e
82 }) as Release | undefined