feat: sync and update with all changes from solar-punk-ltd fork (#730)
* fix: swap error caused by invalid id and batchcount * fix: enhance creation messages for admin drive and user drives * fix: identity and wallet creation * fix: asset preview types * fix: fm search unicode text * fix: feed identity and stamp usage * fix: ui display changes * fix: stamp buy and dilute * fix: vite polyfill warning for stream * fix: standard mode postage stamp purchase reserves incorrect size and duration * fix: add syncing message for Bee node and update page state handling * refactor: stamp depth and amount validation --------- Co-authored-by: Balint Ujvari <balint.ujvari@solarpunk.buzz> Co-authored-by: Bálint Ujvári <58116288+bosi95@users.noreply.github.com> Co-authored-by: rolandlor <33499567+rolandlor@users.noreply.github.com>
This commit is contained in:
@@ -179,7 +179,13 @@ export function AdminStatusBar({
|
||||
const isBusy = loading || isUpgrading || isCreationInProgress
|
||||
const blurCls = isBusy ? ' is-loading' : ''
|
||||
const statusVerb = isCreationInProgress ? 'Creating' : 'Loading'
|
||||
const statusText = statusVerb + ' admin drive, please do not reload'
|
||||
const statusText = (
|
||||
<>
|
||||
{statusVerb} admin drive — please do not reload the page.
|
||||
<br />
|
||||
This may take a few minutes.
|
||||
</>
|
||||
)
|
||||
|
||||
const renderModalsAndOverlays = () => {
|
||||
return (
|
||||
|
||||
@@ -15,7 +15,7 @@ interface ConfirmModalProps {
|
||||
onCancel?: () => void
|
||||
showFooter?: boolean
|
||||
isProgress?: boolean
|
||||
spinnerMessage?: string
|
||||
spinnerMessage?: React.ReactNode
|
||||
showMinimize?: boolean
|
||||
onMinimize?: () => void
|
||||
background?: boolean
|
||||
|
||||
+1
-2
@@ -3,8 +3,7 @@ import DownIcon from 'remixicon-react/ArrowDownSLineIcon'
|
||||
|
||||
import { BulkActionsResult } from '../../../hooks/useBulkActions'
|
||||
import { SortDir, SortKey } from '../../../hooks/useSorting'
|
||||
|
||||
import { capitalizeFirstLetter } from '@/modules/filemanager/utils/common'
|
||||
import { capitalizeFirstLetter } from '../../../utils/common'
|
||||
|
||||
interface FileBrowserHeaderProps {
|
||||
isSearchMode: boolean
|
||||
|
||||
@@ -3,6 +3,7 @@ import { ReactElement, useState } from 'react'
|
||||
import CheckDoubleLineIcon from 'remixicon-react/CheckDoubleLineIcon'
|
||||
import ClipboardIcon from 'remixicon-react/FileCopyLineIcon'
|
||||
|
||||
import { uuidV4 } from '../../../../utils'
|
||||
import { TOOLTIPS } from '../../constants/tooltips'
|
||||
import { getSigner, setSignerPk } from '../../utils/common'
|
||||
import { Button } from '../Button/Button'
|
||||
@@ -10,8 +11,6 @@ import { Tooltip } from '../Tooltip/Tooltip'
|
||||
|
||||
import './PrivateKeyModal.scss'
|
||||
|
||||
import { uuidV4 } from '@/utils'
|
||||
|
||||
type Props = { onSaved: () => void }
|
||||
|
||||
const generateNewPrivateKey = (): string => {
|
||||
|
||||
@@ -305,7 +305,11 @@ export function Sidebar({ setErrorMessage, loading }: SidebarProps): ReactElemen
|
||||
</div>
|
||||
|
||||
{isDriveCreationInProgress && (
|
||||
<div className="fm-sidebar-drive-creation">Creating drive, please do not reload</div>
|
||||
<div className="fm-sidebar-drive-creation">
|
||||
Creating drive — please do not reload the page.
|
||||
<br />
|
||||
This may take a few minutes.
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -26,7 +26,7 @@ interface UseFileFilteringReturn {
|
||||
export function useFileFiltering(props: UseFileFilteringProps): UseFileFilteringReturn {
|
||||
const { files, currentDrive, view, isSearchMode, query, scope, includeActive, includeTrashed } = props
|
||||
|
||||
const q = query.trim().toLowerCase()
|
||||
const q = query.trim().toLowerCase().normalize('NFC')
|
||||
|
||||
const statusIncluded = useCallback(
|
||||
(fi: FileInfo): boolean => {
|
||||
@@ -44,9 +44,11 @@ export function useFileFiltering(props: UseFileFilteringProps): UseFileFiltering
|
||||
const matchesQuery = useCallback(
|
||||
(fi: FileInfo): boolean => {
|
||||
if (!q) return true
|
||||
const name = fi.name.toLowerCase()
|
||||
const mime = (fi.customMetadata?.mime || '').toLowerCase()
|
||||
const topic = String(fi.topic ?? '').toLowerCase()
|
||||
const name = fi.name.toLowerCase().normalize('NFC')
|
||||
const mime = (fi.customMetadata?.mime || '').toLowerCase().normalize('NFC')
|
||||
const topic = String(fi.topic ?? '')
|
||||
.toLowerCase()
|
||||
.normalize('NFC')
|
||||
|
||||
return name.includes(q) || mime.includes(q) || topic.includes(q)
|
||||
},
|
||||
|
||||
@@ -2,7 +2,7 @@ import { ReactElement } from 'react'
|
||||
import FileIcon from 'remixicon-react/FileTextLineIcon'
|
||||
import ImageIcon from 'remixicon-react/Image2LineIcon'
|
||||
|
||||
import { guessMime } from './view'
|
||||
import { guessMime } from '../../../utils/file'
|
||||
|
||||
interface ContextMenuProps {
|
||||
name: string
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { FileInfo, FileManager } from '@solarpunkltd/file-manager-lib'
|
||||
|
||||
import { guessMime, VIEWERS } from '../../../utils/file'
|
||||
import { DownloadProgress, DownloadState } from '../constants/transfers'
|
||||
|
||||
import { AbortManager } from './abortManager'
|
||||
import { isDirectoryPickerSupported, isPickerSupported } from './fileOperations'
|
||||
import { guessMime, VIEWERS } from './view'
|
||||
|
||||
const DefaultDownloadFolder = 'downloads'
|
||||
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
const EXT_TO_MIME: Record<string, string> = {
|
||||
mp4: 'video/mp4',
|
||||
webm: 'video/webm',
|
||||
ogv: 'video/ogg',
|
||||
mp3: 'audio/mpeg',
|
||||
m4a: 'audio/mp4',
|
||||
aac: 'audio/aac',
|
||||
wav: 'audio/wav',
|
||||
ogg: 'audio/ogg',
|
||||
png: 'image/png',
|
||||
jpg: 'image/jpeg',
|
||||
jpeg: 'image/jpeg',
|
||||
gif: 'image/gif',
|
||||
webp: 'image/webp',
|
||||
avif: 'image/avif',
|
||||
svg: 'image/svg+xml',
|
||||
pdf: 'application/pdf',
|
||||
txt: 'text/plain',
|
||||
md: 'text/markdown',
|
||||
json: 'application/json',
|
||||
csv: 'text/csv',
|
||||
html: 'text/html',
|
||||
htm: 'text/html',
|
||||
}
|
||||
|
||||
export function getExtensionFromName(name: string): string {
|
||||
const ext = name.split('.').pop()?.toLowerCase() || ''
|
||||
const hasExtension = name.includes('.') && ext && ext !== name
|
||||
|
||||
return hasExtension ? ext : ''
|
||||
}
|
||||
|
||||
export function guessMime(name: string, mtdt?: Record<string, string> | undefined): { mime: string; ext: string } {
|
||||
const md = mtdt?.mimeType || mtdt?.mime || mtdt?.['content-type']
|
||||
const ext = getExtensionFromName(name)
|
||||
|
||||
if (md) return { mime: md, ext }
|
||||
|
||||
const mime = EXT_TO_MIME[ext] || 'application/octet-stream'
|
||||
|
||||
return { mime, ext }
|
||||
}
|
||||
|
||||
export type Viewer = {
|
||||
name: string
|
||||
test: (mime: string) => boolean
|
||||
render: (win: Window, url: string, mime: string, name: string) => void
|
||||
}
|
||||
|
||||
const VIDEO_HTML = (u: string, title: string) =>
|
||||
`<html><head><meta charset="utf-8"/><title>${title}</title></head><body style="margin:0;background:#000">
|
||||
<video controls autoplay style="width:100%;height:100%" src="${u}"></video>
|
||||
</body></html>`
|
||||
|
||||
const AUDIO_HTML = (u: string, title: string) =>
|
||||
`<html><head><meta charset="utf-8"/><title>${title}</title></head><body>
|
||||
<audio controls autoplay style="width:100%" src="${u}"></audio>
|
||||
</body></html>`
|
||||
|
||||
const IMAGE_HTML = (u: string, title: string) =>
|
||||
`<html><head><meta charset="utf-8"/><title>${title}</title></head><body style="margin:0;background:#111;display:grid;place-items:center;min-height:100vh">
|
||||
<img style="max-width:100%;max-height:100vh" src="${u}" />
|
||||
</body></html>`
|
||||
|
||||
export const VIEWERS: Viewer[] = [
|
||||
{
|
||||
name: 'video',
|
||||
test: m => m.startsWith('video/'),
|
||||
render: (w, url, mime, name) => {
|
||||
w.document.write(VIDEO_HTML(url, name))
|
||||
w.document.title = name
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'audio',
|
||||
test: m => m.startsWith('audio/'),
|
||||
render: (w, url, mime, name) => {
|
||||
w.document.write(AUDIO_HTML(url, name))
|
||||
w.document.title = name
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'image',
|
||||
test: m => m.startsWith('image/'),
|
||||
render: (w, url, mime, name) => {
|
||||
w.document.write(IMAGE_HTML(url, name))
|
||||
w.document.title = name
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'pdf',
|
||||
test: m => m === 'application/pdf',
|
||||
render: (w, url, mime, name) => {
|
||||
w.document.title = name
|
||||
w.location.href = url
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'html',
|
||||
test: m => m === 'text/html',
|
||||
render: (w, url, mime, name) => {
|
||||
w.document.title = name
|
||||
w.location.href = url
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'text-like',
|
||||
test: m => m.startsWith('text/') || m === 'application/json' || m === 'text/markdown',
|
||||
render: (w, url, mime, name) => {
|
||||
w.document.title = name
|
||||
w.location.href = url
|
||||
},
|
||||
},
|
||||
]
|
||||
Reference in New Issue
Block a user