main
ts 75 lines 2.82 KB
Raw
1 import { createElement as h, Fragment } from 'react'
2 import { DirList, state, useSnapState } from './state'
3 import { Btn } from './components'
4 import { alertDialog, toast } from './dialog'
5 import { navigate } from './App'
6 import { apiCall } from '@hfs/shared/api'
7 import { reloadList, usePath } from './useFetchList'
8 import _ from 'lodash'
9 import { HTTP_MESSAGES, xlate, dirname, hfsEvent } from './misc'
10 import i18n from './i18n'
11 const { t, useI18N } = i18n
12
13 export function ClipBar() {
14 const { clip, props } = useSnapState()
15 const { t } = useI18N()
16 const here = usePath()
17 if (!clip.length)
18 return null
19 const there = dirname(clip[0].uri) + '/'
20 return h('div', { id: 'clipBar' },
21 h(Btn, { label: t('clipboard', { content: t('n_items', { n: clip.length }, "{n,plural, one{# item} other{# items}}"), }, `Clipboard ({content})`),
22 onClick: show, style: { flex: 1 } }),
23 h(Btn, { label: t`Paste`, icon: 'paste', onClick: paste, disabled: here === there || !props?.can_upload }),
24 h(Btn, { label: t`Cancel clipboard`, icon: 'close', onClick: emptyIt }),
25 h(Btn, { label: t('to_clipboard_source', "Back to source folder"), icon: 'parent', onClick: goBack, disabled: here === there,
26 tooltip: t('to_clipboard_source_tooltip', "Go to the folder where the clipboard contents are located"),
27 }),
28 )
29
30 function emptyIt() {
31 cut([])
32 }
33
34 function goBack() {
35 navigate(there)
36 }
37
38 function show() {
39 alertDialog(h('div', { id: 'clipboard-content' },
40 t('clipboard_list', "Items in clipboard:"),
41 clip.map(x => h('li', {}, x.name)),
42 ))
43 }
44
45 async function paste() {
46 if (hfsEvent('paste', { from: state.clip, to: here }).isDefaultPrevented()) return
47 if (await moveFiles(clip.map(x => x.uri), here))
48 emptyIt()
49 }
50 }
51
52 export function cut(files: DirList) {
53 state.clip = files
54 if (files.length)
55 return toast(t('after_cut', "Your selection is now in the clipboard.\nGo to destination folder to paste."), 'info')
56 }
57
58 export function moveFiles(uri_from: string[], uri_to: string) {
59 return apiCall('move_files', { uri_from, uri_to }).then(res => {
60 const bad = _.sumBy(res.errors, x => x ? 1 : 0)
61 const msg = t(['move_results', 'good_bad'], { bad, good: uri_from.length - bad }, "{good} moved{bad,plural, =0{} other{, # failed}}")
62 if (!bad)
63 toast(msg, 'success')
64 else
65 alertDialog(h(Fragment, {},
66 msg,
67 h('ul', {}, res.errors.map(((e: any, i: number) => {
68 e = xlate(e, HTTP_MESSAGES)
69 return e && h('li', {}, decodeURI(uri_from[i]) + ': ' + e)
70 }))),
71 ), 'warning')
72 reloadList()
73 return true
74 }, e => void alertDialog(e))
75 }