Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions resources/style/outliner.scss
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,13 @@
input {
width: 100%;
}

&[data-watching='false'] {
SVG {
//color: var(--text-color-muted);
opacity: 0.63;
}
}
}

// ACTIONBAR
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const VirtualizedRenderer = observer(
padding,
}: IRendererProps) => {
const { uiStore, fileStore } = useStore();
const [, isMountedRef] = useMountState();
const [isMounted, isMountedRef] = useMountState();
const wrapperRef = useRef<HTMLDivElement>(null);
const scrollAnchor = useRef<HTMLDivElement>(null);
const [startRenderIndex, setStartRenderIndex] = useState(0);
Expand Down Expand Up @@ -149,7 +149,7 @@ const VirtualizedRenderer = observer(
// Call throttledRedetermine in case no scroll has been applied.
throttledRedetermine.current(numImages, overscan, false);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [layoutUpdateDate]);
}, [layoutUpdateDate, isMounted]);

// When selection changes, scroll to last selected image. Nice when using cursor keys for navigation
const fileSelectionSize = uiStore.fileSelection.size;
Expand Down
1 change: 1 addition & 0 deletions src/frontend/containers/Outliner/LocationsPanel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ const Location = observer(
return (
<div
className="tree-content-label"
data-watching={nodeData.isWatchingFiles}
onClick={handleClick}
onContextMenu={handleContextMenu}
draggable
Expand Down
12 changes: 10 additions & 2 deletions src/frontend/containers/Outliner/TagsPanel/TagsTree.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ const DnDHelper = createDragReorderHelper('tag-dnd-preview', DnDTagType);

const TagItem = observer((props: ITagItemProps) => {
const { nodeData, dispatch, expansion, isEditing, submit, pos, select } = props;
const { uiStore } = useStore();
const { uiStore, tagStore } = useStore();
const dndData = useTagDnD();

const show = useContextMenu();
Expand Down Expand Up @@ -327,7 +327,7 @@ const TagItem = observer((props: ITagItemProps) => {
onSubmit={submit}
tooltip={`${nodeData.path
.map((v) => (v.startsWith('#') ? '&nbsp;<b>' + v.slice(1) + '</b>&nbsp;' : v))
.join(' › ')} (${nodeData.fileCount})`}
.join(' › ')}${tagStore.fileCountsInitialized ? ` (${nodeData.fileCount})` : ''}`}
/>
{!isEditing && (
<SearchButton
Expand Down Expand Up @@ -800,6 +800,14 @@ const TagsTree = observer((props: Partial<MultiSplitPaneProps>) => {
}}
headerToolbar={
<Toolbar controls="tag-hierarchy" isCompact>
{!tagStore.fileCountsInitialized && (
<ToolbarButton
icon={IconSet.RELOAD_COMPACT}
text="Load Tag File Counts"
onClick={() => tagStore.initializeTagFileCounts()}
tooltip={'Load Tag File Counts'}
/>
)}
{uiStore.tagSelection.size > 0 ? (
<ToolbarButton
icon={IconSet.CLOSE}
Expand Down
13 changes: 13 additions & 0 deletions src/frontend/containers/Settings/StartupBehavior.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@ export const StartupBehavior = observer(() => {
>
Restore and query last submitted search query
</Toggle>
<Toggle
checked={uiStore.isLoadFileCountsStartupEnabled}
onChange={uiStore.toggleLoadFileCountsStartup}
>
Load Tag File Counts
</Toggle>
<Toggle
checked={uiStore.isRefreshLocationsStartupEnabled}
onChange={uiStore.toggleRefreshLocationStartup}
>
Refresh Non Auto-Synced Locations and Detect File Changes
</Toggle>
<br />
<Toggle checked={isAutoUpdateEnabled} onChange={toggleAutoUpdate}>
Check for updates
</Toggle>
Expand Down
33 changes: 22 additions & 11 deletions src/frontend/entities/Location.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export class ClientLocation {
_worker?: Worker;

// Whether the initial scan has been completed, and no watching setup is in process
@observable isSettingWatcher = false;
@observable isSettingWatcher;
// whether initialization has started or has been completed
@observable isInitialized = false;
// whether sub-locations are being refreshed
Expand Down Expand Up @@ -130,6 +130,7 @@ export class ClientLocation {
this.extensions = extensions;
this.index = index;
this.isWatchingFiles = isWatchingFiles;
this.isSettingWatcher = isWatchingFiles;

this.subLocations = observable(
subLocations
Expand Down Expand Up @@ -287,7 +288,6 @@ export class ClientLocation {
// Trigger loading icon
this.isRefreshing = true;

// TODO: Can also get this from watching
let rootItem;
if (rootDirectoryItem === undefined) {
const directoryTree = await getDirectoryTree(this.path);
Expand Down Expand Up @@ -450,13 +450,13 @@ export class ClientLocation {
return [filteredDiskFiles, rootItem];
}

@action async watch(): Promise<FileStats[] | undefined> {
@action async watch(): Promise<boolean> {
if (this.isBroken) {
console.error(
'Location watch error:',
'Cannot watch a location because it is broken or not initialized.',
);
return undefined;
return false;
}
this.setSettingWatcher(true);
const directory = this.path;
Expand Down Expand Up @@ -517,15 +517,26 @@ export class ClientLocation {
this._worker?.terminate();
this._worker = worker;
// Make a list of all files in this directory, which will be returned when all subdirs have been traversed
const initialFiles = await this.worker.watch(directory, this.extensions);
await fse.ensureDir(this.store.watcherSnapshotDirectory);
const snapshotFilePath = SysPath.join(
this.store.watcherSnapshotDirectory,
`${this.id}.snapshot.json`,
);
await this.worker.watch(
directory,
this.extensions,
snapshotFilePath,
this.store.PARCEL_WATCHER_BACKEND,
);

this.setSettingWatcher(false);
// Filter out images from excluded sub-locations
// TODO: Could also put them in the chokidar ignore property
return initialFiles?.filter(
({ absolutePath }) =>
!this.excludedPaths.some((subLoc) => absolutePath.startsWith(subLoc.path)),
);
return true;
}

// close and save snapshots of the watcher worker
@action async close(): Promise<void> {
await this.worker?.cancel();
await this.worker?.close();
}
}
interface IDirectoryTreeItem {
Expand Down
7 changes: 5 additions & 2 deletions src/frontend/stores/FileStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,7 @@ class FileStore {
file.setBroken(true);
this.rootStore.uiStore.deselectFile(file);
this.incrementNumMissingFiles();
if (file.tags.size === 0) {
if (file.tags.size === 0 && this.numUntaggedFiles > 0) {
this.decrementNumUntaggedFiles();
}
}
Expand Down Expand Up @@ -747,11 +747,14 @@ class FileStore {
this.setAverageFetchTime(end - start);
// continue if the current taskId is the same else abort the fetch
const currentFetchId = runInAction(() => this.fetchTaskIdPair[0]);
let promise = undefined;
if (start === currentFetchId) {
return this.updateFromBackend(fetchedFiles);
promise = this.updateFromBackend(fetchedFiles);
} else {
console.debug('FETCH All ABORTED');
}
this.rootStore.initStartupLoads(fetchedFiles);
return promise;
} catch (err) {
console.error('Could not load all files', err);
}
Expand Down
Loading
Loading