@samitouri / QOSami-HFS / commits / f39972de

comment command in file menu

Massimo Melina committed Sep 25, 2023 at 12:02 UTC f39972de4f07c000d0c89a0a3ebdc9593ce36c32
8 files changed +48 -16
frontend/src/fileMenu.ts
+14
@@ -10,6 +10,7 @@ import { fileShow, getShowType } from './show'
10 import { alertDialog, promptDialog } from './dialog'
11 import { apiCall, useApi } from '@hfs/shared/api'
12 import { navigate } from './App'
13 +import { inputComment } from './upload'
14
15 interface FileMenuEntry {
16 id?: string
@@ -25,6 +26,7 @@ export function openFileMenu(entry: DirEntry, ev: MouseEvent, addToMenu: (FileMe
26 const cantDownload = entry.cantOpen || isFolder && entry.p?.includes('r') // folders needs both list and read
27 const menu = [
28 !cantDownload && { id: 'download', label: t`Download`, href: uri + (isFolder ? '?get=zip' : '?dl'), icon: 'download' },
29 + state.can_upload && { id: 'comment', label: t`Comment`, icon: 'comment', onClick: () => editComment(entry) },
30 ...addToMenu.map(x => {
31 if (x === 'open') {
32 if (entry.cantOpen) return
@@ -131,4 +133,16 @@ async function rename(entry: DirEntry) {
133 catch(e: any) {
134 await alertDialog(e)
135 }
136 +}
137 +
138 +async function editComment(entry: DirEntry) {
139 + const res = await inputComment(entry.name, entry.comment)
140 + if (res === null) return
141 + await apiCall('comment', { uri: entry.uri, comment: res })
142 + updateEntry(entry, e => e.comment = res)
143 + alertDialog(t`Operation successful`)
144 +}
145 +
146 +function updateEntry(entry: DirEntry, cb: (e: DirEntry) => unknown) {
147 + cb(_.find(state.list, { n: entry.n })!)
148 }
\ No newline at end of file
frontend/src/state.ts
+1 -1
@@ -87,7 +87,7 @@ export class DirEntry {
87 public readonly c?: string
88 public readonly p?: string
89 public readonly icon?: string
90 - public readonly comment?: string
90 + public comment?: string
91 // we memoize these value for speed
92 public readonly name: string
93 public readonly uri: string
frontend/src/upload.ts
+6 -1
@@ -3,6 +3,7 @@
3 import { createElement as h, DragEvent, Fragment, useMemo } from 'react'
4 import { Checkbox, Flex, FlexV, iconBtn } from './components'
5 import {
6 + basename,
7 closeDialog,
8 formatBytes,
9 formatPerc,
@@ -147,7 +148,7 @@ export function showUpload() {
148 entries: adding,
149 actions: {
150 delete: rec => _.remove(uploadState.adding, { file: rec.file }),
150 - comment: rec => promptDialog(t('enter_comment', "Comment for this file"), { def: rec.comment, type: 'textarea' })
151 + comment: rec => inputComment(basename(rec.file.name), rec.comment)
152 .then(s => _.find(uploadState.adding, { file: rec.file })!.comment = s || undefined),
153 },
154 }),
@@ -435,4 +436,8 @@ async function createFolder() {
436 catch(e: any) {
437 await alertDialog(e.code === 409 ? t('folder_exists', "Folder with same name already exists") : e)
438 }
439 +}
440 +
441 +export function inputComment(filename: string, def?: string) {
442 + return promptDialog(t('enter_comment', "Comment for " + filename), { def, type: 'textarea' })
443 }
\ No newline at end of file
src/api.file_list.ts
+2 -2
@@ -76,7 +76,6 @@ export const get_file_list: ApiHandler = async ({ uri, offset, limit, search, c
76 const entry = await nodeToDirEntry(ctx, sub)
77 if (!entry)
78 continue
79 - entry.comment = await getCommentFor(sub.source)
79 const cbParams = { entry, ctx, listUri: uri, node: sub }
80 try {
81 const res = await Promise.all(onDirEntryHandlers.map(cb => cb(cbParams)))
@@ -126,7 +125,8 @@ export const get_file_list: ApiHandler = async ({ uri, offset, limit, search, c
125 c: ctime,
126 m: Math.abs(+mtime-+ctime) < 1000 ? undefined : mtime,
127 s: folder ? undefined : st.size,
129 - p: (pr + pl + pd) || undefined
128 + p: (pr + pl + pd) || undefined,
129 + comment: await getCommentFor(source),
130 }
131 }
132 catch {
src/frontEndApis.ts
+16 -7
@@ -7,18 +7,15 @@ import events from './events'
7 import Koa from 'koa'
8 import { dirTraversal, isValidFileName } from './util-files'
9 import {
10 - HTTP_BAD_REQUEST,
11 - HTTP_CONFLICT,
12 - HTTP_FORBIDDEN,
13 - HTTP_NOT_FOUND,
14 - HTTP_SERVER_ERROR,
15 - HTTP_UNAUTHORIZED
10 + HTTP_BAD_REQUEST, HTTP_CONFLICT, HTTP_FAILED_DEPENDENCY, HTTP_FORBIDDEN,
11 + HTTP_NOT_FOUND, HTTP_SERVER_ERROR, HTTP_UNAUTHORIZED
12 } from './const'
13 import { hasPermission, urlToNode } from './vfs'
14 import { mkdir, rename, rm } from 'fs/promises'
15 import { dirname, join } from 'path'
16 import { getUploadMeta } from './upload'
17 import { apiAssertTypes } from './misc'
18 +import { setCommentFor } from './comments'
19
20 export const frontEndApis: ApiHandlers = {
21 get_file_list,
@@ -108,8 +105,20 @@ export const frontEndApis: ApiHandlers = {
105 catch (e: any) {
106 throw new ApiError(HTTP_SERVER_ERROR, e)
107 }
111 - }
108 + },
109
110 + async comment({ uri, comment }, ctx) {
111 + apiAssertTypes({ string: { uri, comment } })
112 + const node = await urlToNode(uri, ctx)
113 + if (!node)
114 + throw new ApiError(HTTP_NOT_FOUND)
115 + if (!hasPermission(node, 'can_upload', ctx))
116 + throw new ApiError(HTTP_UNAUTHORIZED)
117 + if (!node.source)
118 + throw new ApiError(HTTP_FAILED_DEPENDENCY)
119 + await setCommentFor(node.source, comment)
120 + return {}
121 + },
122 }
123
124 export function notifyClient(ctx: Koa.Context, name: string, data: any) {
src/langs/hfs-lang-en.json
+2 -1
@@ -137,6 +137,7 @@
137 "showHelp_F_body": "full screen",
138 "Destination": "Destination",
139 "in_queue": "{n} in queue",
140 - "enter_comment": "Comment for this file"
140 + "enter_comment": "Comment for this file",
141 + "Comment": "Comment"
142 }
143 }
src/langs/hfs-lang-it.json
+1
@@ -130,6 +130,7 @@
130 "Destination": "Destinazione",
131 "in_queue": "{n} in coda",
132 "enter_comment": "Comment for this file",
133 + "Comment": "Comment",
134
135 "": "PLUGINS SECTION",
136 "": "PLUGIN thumbnails",
src/langs/hfs-lang-ru.json
+6 -4
@@ -1,7 +1,7 @@
1 {
2 "author": "Mefistofell, SanokKule",
3 - "version": 2.1,
4 - "hfs_version": "0.48.0",
3 + "version": 2.2,
4 + "hfs_version": "0.49.0",
5 "translate": {
6 "Select": "Выбор",
7 "n_files": "{n,plural, one{1 файл} few{# файла} other{# файлов}}",
@@ -137,10 +137,12 @@
137 "showHelp_F_body": "полноэкранный режим",
138 "Destination": "Назначение",
139 "in_queue": "{n} в очереди",
140 + "enter_comment": "Комментарий для файла",
141 + "Comment": "Комментировать",
142
143 "": "PLUGINS SECTION",
144 "": "PLUGIN thumbnails",
143 - "Enable tiles mode": "Просмотр в режиме плиток",
144 - "thumbnails_switchBack": "Изменить вид можно в настройках"
145 + "Enable tiles mode": "Просмотр в режиме плиток",
146 + "thumbnails_switchBack": "Изменить вид можно в настройках"
147 }
148 }