TypeScript check and typing corrections.
This commit is contained in:
@@ -38,10 +38,10 @@ interface Path {
|
|||||||
const store = useMainStore()
|
const store = useMainStore()
|
||||||
const path: ComputedRef<Path> = computed(() => {
|
const path: ComputedRef<Path> = computed(() => {
|
||||||
const p = decodeURIComponent(Router.currentRoute.value.path).split('//')
|
const p = decodeURIComponent(Router.currentRoute.value.path).split('//')
|
||||||
const pathList = p[0].split('/').filter(value => value !== '')
|
const pathList = (p[0] ?? '').split('/').filter(value => value !== '')
|
||||||
const query = p.slice(1).join('//')
|
const query = p.slice(1).join('//')
|
||||||
return {
|
return {
|
||||||
path: p[0],
|
path: p[0] ?? '',
|
||||||
pathList,
|
pathList,
|
||||||
query
|
query
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ const isCurrent = (index: number) => index == props.path.length ? 'location' : u
|
|||||||
const focusCurrent = () => {
|
const focusCurrent = () => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
const index = props.path.length
|
const index = props.path.length
|
||||||
if (index < links.length) links[index].focus()
|
if (index < links.length) links[index]!.focus()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ const navigate = (index: number) => {
|
|||||||
if (!link) throw Error(`No link at index ${index} (path: ${props.path})`)
|
if (!link) throw Error(`No link at index ${index} (path: ${props.path})`)
|
||||||
const url = index ? `/${longest.value.slice(0, index).join('/')}/` : '/'
|
const url = index ? `/${longest.value.slice(0, index).join('/')}/` : '/'
|
||||||
const long = longest.value.length ? `/${longest.value.join('/')}/` : '/'
|
const long = longest.value.length ? `/${longest.value.join('/')}/` : '/'
|
||||||
const browser = decodeURIComponent(location.hash.slice(1).split('//')[0])
|
const browser = decodeURIComponent(location.hash.slice(1).split('//')[0] ?? '')
|
||||||
const u = url.replaceAll('?', '%3F').replaceAll('#', '%23')
|
const u = url.replaceAll('?', '%3F').replaceAll('#', '%23')
|
||||||
// Clicking on current link clears the rest of the path and adds new history
|
// Clicking on current link clears the rest of the path and adds new history
|
||||||
if (isCurrent(index)) { longest.value.splice(index); router.push(u) }
|
if (isCurrent(index)) { longest.value.splice(index); router.push(u) }
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ const download = async () => {
|
|||||||
if (files.length === 1) {
|
if (files.length === 1) {
|
||||||
store.selected.clear()
|
store.selected.clear()
|
||||||
store.error = "Single file via browser downloads"
|
store.error = "Single file via browser downloads"
|
||||||
return linkdl(`/files/${files[0][1]}`)
|
return linkdl(`/files/${files[0]![1]}`)
|
||||||
}
|
}
|
||||||
// Use FileSystem API if multiple files and the browser supports it
|
// Use FileSystem API if multiple files and the browser supports it
|
||||||
if ('showDirectoryPicker' in window) {
|
if ('showDirectoryPicker' in window) {
|
||||||
@@ -164,7 +164,7 @@ const download = async () => {
|
|||||||
}
|
}
|
||||||
// Otherwise, zip and download
|
// Otherwise, zip and download
|
||||||
console.log("Falling back to zip download")
|
console.log("Falling back to zip download")
|
||||||
const name = sel.keys.length === 1 ? sel.docs[sel.keys[0]].name : 'download'
|
const name = sel.keys.length === 1 ? sel.docs[sel.keys[0]!]!.name : 'download'
|
||||||
linkdl(`/zip/${Array.from(sel.keys).join('+')}/${name}.zip`)
|
linkdl(`/zip/${Array.from(sel.keys).join('+')}/${name}.zip`)
|
||||||
store.error = "Downloading as ZIP via browser downloads"
|
store.error = "Downloading as ZIP via browser downloads"
|
||||||
store.selected.clear()
|
store.selected.clear()
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ defineExpose({
|
|||||||
let [begin, end] = d > 0 ? [index, moveto] : [moveto, index]
|
let [begin, end] = d > 0 ? [index, moveto] : [moveto, index]
|
||||||
for (let p = begin; p !== end; p = increment(p, 1)) {
|
for (let p = begin; p !== end; p = increment(p, 1)) {
|
||||||
if (p === N) continue
|
if (p === N) continue
|
||||||
const key = docs[p].key
|
const key = docs[p]!.key
|
||||||
if (store.selected.has(key)) store.selected.delete(key)
|
if (store.selected.has(key)) store.selected.delete(key)
|
||||||
else store.selected.add(key)
|
else store.selected.add(key)
|
||||||
}
|
}
|
||||||
@@ -255,8 +255,8 @@ const mkdir = (doc: Doc, name: string) => {
|
|||||||
}
|
}
|
||||||
const showFolderBreadcrumb = (i: number) => {
|
const showFolderBreadcrumb = (i: number) => {
|
||||||
const docs = props.documents
|
const docs = props.documents
|
||||||
const docloc = docs[i].loc
|
const docloc = docs[i]!.loc
|
||||||
return i === 0 ? docloc !== loc.value : docloc !== docs[i - 1].loc
|
return i === 0 ? docloc !== loc.value : docloc !== docs[i - 1]!.loc
|
||||||
}
|
}
|
||||||
const selectionIndeterminate = computed({
|
const selectionIndeterminate = computed({
|
||||||
get: () => {
|
get: () => {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { Doc } from '@/repositories/Document'
|
|||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
|
|
||||||
const sizeClass = computed(() => {
|
const sizeClass = computed(() => {
|
||||||
const unit = props.doc.sizedisp.split('\u202F').slice(-1)[0]
|
const unit = props.doc.sizedisp.split('\u202F').slice(-1)[0]!
|
||||||
return +unit ? "bytes" : unit
|
return +unit ? "bytes" : unit
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ defineExpose({
|
|||||||
let [begin, end] = d > 0 ? [index, moveto] : [moveto, index]
|
let [begin, end] = d > 0 ? [index, moveto] : [moveto, index]
|
||||||
for (let p = begin; p !== end; p = increment(p, 1)) {
|
for (let p = begin; p !== end; p = increment(p, 1)) {
|
||||||
if (p === N) continue
|
if (p === N) continue
|
||||||
const key = docs[p].key
|
const key = docs[p]!.key
|
||||||
if (store.selected.has(key)) store.selected.delete(key)
|
if (store.selected.has(key)) store.selected.delete(key)
|
||||||
else store.selected.add(key)
|
else store.selected.add(key)
|
||||||
}
|
}
|
||||||
@@ -209,8 +209,8 @@ const mkdir = (doc: Doc, name: string) => {
|
|||||||
}
|
}
|
||||||
const showFolderBreadcrumb = (i: number) => {
|
const showFolderBreadcrumb = (i: number) => {
|
||||||
const docs = props.documents
|
const docs = props.documents
|
||||||
const docloc = docs[i].loc
|
const docloc = docs[i]!.loc
|
||||||
return i === 0 ? docloc !== loc.value : docloc !== docs[i - 1].loc
|
return i === 0 ? docloc !== loc.value : docloc !== docs[i - 1]!.loc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ const op = (op: string, dst?: string) => {
|
|||||||
const msg = {
|
const msg = {
|
||||||
op,
|
op,
|
||||||
sel: sel.keys.map(key => {
|
sel: sel.keys.map(key => {
|
||||||
const doc = sel.docs[key]
|
const doc = sel.docs[key]!
|
||||||
return doc.loc ? `${doc.loc}/${doc.name}` : doc.name
|
return doc.loc ? `${doc.loc}/${doc.name}` : doc.name
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ const next = () => {
|
|||||||
let el: HTMLAudioElement | HTMLVideoElement | null = null
|
let el: HTMLAudioElement | HTMLVideoElement | null = null
|
||||||
for (const i in medias) {
|
for (const i in medias) {
|
||||||
if (medias[i] === (fscurrent || media.value)) {
|
if (medias[i] === (fscurrent || media.value)) {
|
||||||
el = medias[+i + 1] || medias[0]
|
el = medias[+i + 1] ?? medias[0] ?? null
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ const WSCreate = async () => await new Promise<WebSocket>(resolve => {
|
|||||||
const worker = async () => {
|
const worker = async () => {
|
||||||
const ws = await WSCreate()
|
const ws = await WSCreate()
|
||||||
while (upqueue.length) {
|
while (upqueue.length) {
|
||||||
const f = upqueue[0]
|
const f = upqueue[0]!
|
||||||
const start = f.cloudPos
|
const start = f.cloudPos
|
||||||
const end = Math.min(f.file.size, start + (1<<20))
|
const end = Math.min(f.file.size, start + (1<<20))
|
||||||
const control = { name: f.cloudName, size: f.file.size, start, end }
|
const control = { name: f.cloudName, size: f.file.size, start, end }
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ const deleteUserAction = async (username: string) => {
|
|||||||
const copySuccess = async (isButtonClick: boolean = false) => {
|
const copySuccess = async (isButtonClick: boolean = false) => {
|
||||||
const passwordMatch = success.value.match(/(?:Password|New password): (.+)/)
|
const passwordMatch = success.value.match(/(?:Password|New password): (.+)/)
|
||||||
if (passwordMatch) {
|
if (passwordMatch) {
|
||||||
await navigator.clipboard.writeText(passwordMatch[1])
|
await navigator.clipboard.writeText(passwordMatch[1]!)
|
||||||
if (isButtonClick) {
|
if (isButtonClick) {
|
||||||
// Show "Copied!" indication on button
|
// Show "Copied!" indication on button
|
||||||
copyButtonText.value = '✅ Copied!'
|
copyButtonText.value = '✅ Copied!'
|
||||||
|
|||||||
@@ -12,15 +12,20 @@ export type DocProps = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class Doc {
|
export class Doc {
|
||||||
private _name: string = ""
|
|
||||||
public loc: string = ""
|
public loc: string = ""
|
||||||
public key: FUID = ""
|
public key: FUID = ""
|
||||||
public size: number = 0
|
public size: number = 0
|
||||||
public mtime: number = 0
|
public mtime: number = 0
|
||||||
public haystack: string = ""
|
public haystack: string = ""
|
||||||
public dir: boolean = false
|
public dir: boolean = false
|
||||||
|
/** @internal Use the name getter/setter instead */
|
||||||
|
public _name: string = ""
|
||||||
|
|
||||||
constructor(props: Partial<DocProps> = {}) { Object.assign(this, props) }
|
constructor(props: Partial<DocProps> = {}) {
|
||||||
|
const { name, ...rest } = props
|
||||||
|
Object.assign(this, rest)
|
||||||
|
if (name) this.name = name // Use setter for validation
|
||||||
|
}
|
||||||
get name() { return this._name }
|
get name() { return this._name }
|
||||||
set name(name: string) {
|
set name(name: string) {
|
||||||
if (name.includes('/') || name.startsWith('.')) throw Error(`Invalid name: ${name}`)
|
if (name.includes('/') || name.startsWith('.')) throw Error(`Invalid name: ${name}`)
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ export const useMainStore = defineStore('main', {
|
|||||||
ret.recursive.push([rel, full, doc])
|
ret.recursive.push([rel, full, doc])
|
||||||
}
|
}
|
||||||
for (const key of ret.keys) {
|
for (const key of ret.keys) {
|
||||||
const base = ret.docs[key]
|
const base = ret.docs[key]!
|
||||||
const basepath = base.loc ? `${base.loc}/${base.name}` : base.name
|
const basepath = base.loc ? `${base.loc}/${base.name}` : base.name
|
||||||
const nremove = base.loc.length
|
const nremove = base.loc.length
|
||||||
add(base.name, basepath, base)
|
add(base.name, basepath, base)
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export const sortedGrouped = (documents: Doc[], order: SortOrder) => {
|
|||||||
// Find the "best" item in each folder (first after sorting = best according to criteria)
|
// Find the "best" item in each folder (first after sorting = best according to criteria)
|
||||||
const folderBest = new Map<string, Doc>()
|
const folderBest = new Map<string, Doc>()
|
||||||
for (const [folder, docs] of byFolder) {
|
for (const [folder, docs] of byFolder) {
|
||||||
folderBest.set(folder, docs[0])
|
folderBest.set(folder, docs[0]!)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort folders: by path for name sort, by best item for modified/size
|
// Sort folders: by path for name sort, by best item for modified/size
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export function getFileType(name: string): string {
|
|||||||
const dotIndex = name.lastIndexOf('.')
|
const dotIndex = name.lastIndexOf('.')
|
||||||
if (dotIndex === -1 || dotIndex === name.length - 1) return 'unknown'
|
if (dotIndex === -1 || dotIndex === name.length - 1) return 'unknown'
|
||||||
const ext = name.slice(dotIndex + 1).toLowerCase()
|
const ext = name.slice(dotIndex + 1).toLowerCase()
|
||||||
return Object.keys(filetypes).find(type => filetypes[type].includes(ext)) || 'unknown'
|
return Object.keys(filetypes).find(type => filetypes[type]!.includes(ext)) || 'unknown'
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prebuilt for fast & consistent sorting
|
// Prebuilt for fast & consistent sorting
|
||||||
|
|||||||
Reference in New Issue
Block a user