store filemanager state in localstorage
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
import React, {
|
import React, {
|
||||||
SyntheticEvent,
|
SyntheticEvent,
|
||||||
useEffect,
|
useEffect,
|
||||||
useMemo,
|
|
||||||
useState,
|
useState,
|
||||||
useCallback,
|
useCallback,
|
||||||
useRef,
|
useRef,
|
||||||
@@ -9,7 +8,7 @@ import React, {
|
|||||||
} from 'react'
|
} from 'react'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
import * as Tabs from '@radix-ui/react-tabs'
|
import * as Tabs from '@radix-ui/react-tabs'
|
||||||
import { useSetRecoilState } from 'recoil'
|
import { useRecoilState, useSetRecoilState } from 'recoil'
|
||||||
import PhotoAlbum from 'react-photo-album'
|
import PhotoAlbum from 'react-photo-album'
|
||||||
import { BarsArrowDownIcon, BarsArrowUpIcon } from '@heroicons/react/24/outline'
|
import { BarsArrowDownIcon, BarsArrowUpIcon } from '@heroicons/react/24/outline'
|
||||||
import { MagnifyingGlassIcon } from '@radix-ui/react-icons'
|
import { MagnifyingGlassIcon } from '@radix-ui/react-icons'
|
||||||
@@ -18,12 +17,18 @@ import { Id, Index, IndexSearchResult } from 'flexsearch'
|
|||||||
import * as ScrollArea from '@radix-ui/react-scroll-area'
|
import * as ScrollArea from '@radix-ui/react-scroll-area'
|
||||||
import Modal from '../shared/Modal'
|
import Modal from '../shared/Modal'
|
||||||
import Flex from '../shared/Layout'
|
import Flex from '../shared/Layout'
|
||||||
import { toastState } from '../../store/Atoms'
|
import {
|
||||||
|
fileManagerLayout,
|
||||||
|
fileManagerSortBy,
|
||||||
|
fileManagerSortOrder,
|
||||||
|
SortBy,
|
||||||
|
SortOrder,
|
||||||
|
toastState,
|
||||||
|
} from '../../store/Atoms'
|
||||||
import { getMedias } from '../../adapters/inpainting'
|
import { getMedias } from '../../adapters/inpainting'
|
||||||
import Selector from '../shared/Selector'
|
import Selector from '../shared/Selector'
|
||||||
import Button from '../shared/Button'
|
import Button from '../shared/Button'
|
||||||
import TextInput from '../shared/Input'
|
import TextInput from '../shared/Input'
|
||||||
import { useAsyncMemo } from '../../hooks/useAsyncMemo'
|
|
||||||
|
|
||||||
interface Photo {
|
interface Photo {
|
||||||
src: string
|
src: string
|
||||||
@@ -37,20 +42,12 @@ interface Filename {
|
|||||||
height: number
|
height: number
|
||||||
width: number
|
width: number
|
||||||
ctime: number
|
ctime: number
|
||||||
}
|
mtime: number
|
||||||
|
|
||||||
enum SortOrder {
|
|
||||||
DESCENDING = 'desc',
|
|
||||||
ASCENDING = 'asc',
|
|
||||||
}
|
|
||||||
|
|
||||||
enum SortBy {
|
|
||||||
NAME = 'name',
|
|
||||||
CTIME = 'ctime',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const SORT_BY_NAME = 'Name'
|
const SORT_BY_NAME = 'Name'
|
||||||
const SORT_BY_CREATED_TIME = 'Created time'
|
const SORT_BY_CREATED_TIME = 'Created time'
|
||||||
|
const SORT_BY_MODIFIED_TIME = 'Modified time'
|
||||||
|
|
||||||
const IMAGE_TAB = 'image'
|
const IMAGE_TAB = 'image'
|
||||||
const OUTPUT_TAB = 'output'
|
const OUTPUT_TAB = 'output'
|
||||||
@@ -58,6 +55,7 @@ const OUTPUT_TAB = 'output'
|
|||||||
const SortByMap = {
|
const SortByMap = {
|
||||||
[SortBy.NAME]: SORT_BY_NAME,
|
[SortBy.NAME]: SORT_BY_NAME,
|
||||||
[SortBy.CTIME]: SORT_BY_CREATED_TIME,
|
[SortBy.CTIME]: SORT_BY_CREATED_TIME,
|
||||||
|
[SortBy.MTIME]: SORT_BY_MODIFIED_TIME,
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -72,8 +70,11 @@ export default function FileManager(props: Props) {
|
|||||||
const [scrollTop, setScrollTop] = useState(0)
|
const [scrollTop, setScrollTop] = useState(0)
|
||||||
const [closeScrollTop, setCloseScrollTop] = useState(0)
|
const [closeScrollTop, setCloseScrollTop] = useState(0)
|
||||||
const setToastState = useSetRecoilState(toastState)
|
const setToastState = useSetRecoilState(toastState)
|
||||||
const [sortBy, setSortBy] = useState<SortBy>(SortBy.CTIME)
|
|
||||||
const [sortOrder, setSortOrder] = useState<SortOrder>(SortOrder.DESCENDING)
|
const [sortBy, setSortBy] = useRecoilState<SortBy>(fileManagerSortBy)
|
||||||
|
const [sortOrder, setSortOrder] = useRecoilState(fileManagerSortOrder)
|
||||||
|
const [layout, setLayout] = useRecoilState(fileManagerLayout)
|
||||||
|
|
||||||
const ref = useRef(null)
|
const ref = useRef(null)
|
||||||
const [searchText, setSearchText] = useState('')
|
const [searchText, setSearchText] = useState('')
|
||||||
const [debouncedSearchText, setDebouncedSearchText] = useState('')
|
const [debouncedSearchText, setDebouncedSearchText] = useState('')
|
||||||
@@ -165,6 +166,7 @@ export default function FileManager(props: Props) {
|
|||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
onClose={onClose}
|
onClose={onClose}
|
||||||
|
// TODO:layout switch 放到标题中
|
||||||
title={`Images (${photos.length})`}
|
title={`Images (${photos.length})`}
|
||||||
className="file-manager-modal"
|
className="file-manager-modal"
|
||||||
show={show}
|
show={show}
|
||||||
@@ -208,14 +210,22 @@ export default function FileManager(props: Props) {
|
|||||||
</Flex>
|
</Flex>
|
||||||
<Flex style={{ gap: 8 }}>
|
<Flex style={{ gap: 8 }}>
|
||||||
<Selector
|
<Selector
|
||||||
width={130}
|
width={140}
|
||||||
value={SortByMap[sortBy]}
|
value={SortByMap[sortBy]}
|
||||||
options={Object.values(SortByMap)}
|
options={Object.values(SortByMap)}
|
||||||
onChange={val => {
|
onChange={val => {
|
||||||
if (val === SORT_BY_CREATED_TIME) {
|
switch (val) {
|
||||||
setSortBy(SortBy.CTIME)
|
case SORT_BY_NAME:
|
||||||
} else {
|
|
||||||
setSortBy(SortBy.NAME)
|
setSortBy(SortBy.NAME)
|
||||||
|
break
|
||||||
|
case SORT_BY_CREATED_TIME:
|
||||||
|
setSortBy(SortBy.CTIME)
|
||||||
|
break
|
||||||
|
case SORT_BY_MODIFIED_TIME:
|
||||||
|
setSortBy(SortBy.MTIME)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
chevronDirection="down"
|
chevronDirection="down"
|
||||||
@@ -250,7 +260,7 @@ export default function FileManager(props: Props) {
|
|||||||
ref={onRefChange}
|
ref={onRefChange}
|
||||||
>
|
>
|
||||||
<PhotoAlbum
|
<PhotoAlbum
|
||||||
layout="masonry"
|
layout={layout}
|
||||||
photos={photos}
|
photos={photos}
|
||||||
spacing={8}
|
spacing={8}
|
||||||
padding={0}
|
padding={0}
|
||||||
|
|||||||
@@ -685,3 +685,59 @@ export const isDiffusionModelsState = selector({
|
|||||||
return isSD || isPaintByExample || isPix2Pix
|
return isSD || isPaintByExample || isPix2Pix
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export enum SortBy {
|
||||||
|
NAME = 'name',
|
||||||
|
CTIME = 'ctime',
|
||||||
|
MTIME = 'mtime',
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum SortOrder {
|
||||||
|
DESCENDING = 'desc',
|
||||||
|
ASCENDING = 'asc',
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FileManagerState {
|
||||||
|
sortBy: SortBy
|
||||||
|
sortOrder: SortOrder
|
||||||
|
layout: 'rows' | 'masonry'
|
||||||
|
}
|
||||||
|
|
||||||
|
const FILE_MANAGER_STATE_KEY = 'fileManagerState'
|
||||||
|
|
||||||
|
export const fileManagerState = atom<FileManagerState>({
|
||||||
|
key: FILE_MANAGER_STATE_KEY,
|
||||||
|
default: {
|
||||||
|
sortBy: SortBy.CTIME,
|
||||||
|
sortOrder: SortOrder.DESCENDING,
|
||||||
|
layout: 'masonry',
|
||||||
|
},
|
||||||
|
effects: [localStorageEffect(FILE_MANAGER_STATE_KEY)],
|
||||||
|
})
|
||||||
|
|
||||||
|
export const fileManagerSortBy = selector({
|
||||||
|
key: 'fileManagerSortBy',
|
||||||
|
get: ({ get }) => get(fileManagerState).sortBy,
|
||||||
|
set: ({ get, set }, newValue: any) => {
|
||||||
|
const val = get(fileManagerState)
|
||||||
|
set(fileManagerState, { ...val, sortBy: newValue })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const fileManagerSortOrder = selector({
|
||||||
|
key: 'fileManagerSortOrder',
|
||||||
|
get: ({ get }) => get(fileManagerState).sortOrder,
|
||||||
|
set: ({ get, set }, newValue: any) => {
|
||||||
|
const val = get(fileManagerState)
|
||||||
|
set(fileManagerState, { ...val, sortOrder: newValue })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
export const fileManagerLayout = selector({
|
||||||
|
key: 'fileManagerLayout',
|
||||||
|
get: ({ get }) => get(fileManagerState).layout,
|
||||||
|
set: ({ get, set }, newValue: any) => {
|
||||||
|
const val = get(fileManagerState)
|
||||||
|
set(fileManagerState, { ...val, layout: newValue })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ class FileManager(FileSystemEventHandler):
|
|||||||
"height": img.height,
|
"height": img.height,
|
||||||
"width": img.width,
|
"width": img.width,
|
||||||
"ctime": os.path.getctime(path),
|
"ctime": os.path.getctime(path),
|
||||||
|
"mtime": os.path.getmtime(path),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return res
|
return res
|
||||||
|
|||||||
Reference in New Issue
Block a user