| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- const api = window.dshDesktop
- async function main() {
- const locale = await api.locale()
- const messages = locale.messages
- const message = (key, values = {}) => messages[key].replaceAll(/\{([^{}]+)\}/gu, (placeholder, name) => values[name] ?? placeholder)
- document.documentElement.lang = locale.id
- document.querySelector('#page-title').textContent = messages.pluginManagerTitle
- document.querySelector('#title').textContent = messages.pluginManagerTitle
- document.querySelector('#description').textContent = messages.pluginManagerDescription
- document.querySelector('#refresh').textContent = messages.refresh
- document.querySelector('#package-label').textContent = messages.npmPackage
- document.querySelector('#install').textContent = messages.install
- document.querySelector('#installed-heading').textContent = messages.installed
- document.querySelector('#empty').textContent = messages.noPlugins
- const list = document.querySelector('#plugins')
- const empty = document.querySelector('#empty')
- const status = document.querySelector('#status')
- const form = document.querySelector('#install-form')
- const input = document.querySelector('#package-spec')
- const refresh = document.querySelector('#refresh')
- function setBusy(busy, statusMessage = '') {
- for (const control of document.querySelectorAll('button, input')) control.disabled = busy
- status.textContent = statusMessage
- }
- async function render() {
- const plugins = await api.plugins.list()
- list.replaceChildren(...plugins.map(plugin => {
- const item = document.createElement('li')
- const identity = document.createElement('span')
- const version = document.createElement('span')
- version.className = 'package-version'
- version.textContent = plugin.version
- identity.append(document.createTextNode(plugin.name), version)
- const remove = document.createElement('button')
- remove.type = 'button'
- remove.textContent = messages.remove
- remove.addEventListener('click', () => void run(
- () => api.plugins.remove(plugin.name),
- message('removing', { name: plugin.name }),
- ))
- const update = document.createElement('button')
- update.type = 'button'
- update.textContent = messages.update
- update.addEventListener('click', () => {
- const next = window.prompt(message('targetVersion', { name: plugin.name }), plugin.version)?.trim()
- if (next === undefined || next === '' || next === plugin.version) return
- void run(() => api.plugins.update(plugin.name, next), message('updating', { name: plugin.name }))
- })
- const actions = document.createElement('span')
- actions.className = 'package-actions'
- actions.append(update, remove)
- item.append(identity, actions)
- return item
- }))
- empty.hidden = plugins.length !== 0
- }
- async function run(operation, statusMessage) {
- setBusy(true, statusMessage)
- try {
- await operation()
- await render()
- status.textContent = messages.operationComplete
- } catch (error) {
- status.textContent = error instanceof Error ? error.message : String(error)
- } finally {
- setBusy(false, status.textContent)
- }
- }
- async function load(statusMessage, success) {
- setBusy(true, statusMessage)
- try {
- await render()
- status.textContent = success
- } catch (error) {
- status.textContent = error instanceof Error ? error.message : String(error)
- } finally {
- setBusy(false, status.textContent)
- }
- }
- form.addEventListener('submit', (event) => {
- event.preventDefault()
- const spec = input.value.trim()
- if (spec === '') return
- void run(async () => {
- await api.plugins.add(spec)
- input.value = ''
- }, message('installing', { spec }))
- })
- refresh.addEventListener('click', () => void load(messages.refreshing, messages.refreshed))
- await load(messages.loadingPlugins, '')
- }
- void main()
|