+8
-1
changelog
+8
-1
changelog
···
69
- Fixed filters not updating photo list
70
- Fixed adding / removing photos not updating the photo list
71
72
+
Hotfix 1:
73
+
- Fixed new installations immediately crashing
74
+
75
Dev Stuff:
76
+
- Split frontend up into many smaller files for easier editing
77
+
78
+
v0.2.4:
79
+
- Refactor loading system to not load all photos at the start
80
+
(should help with large numbers of photos)
+1
-1
src-tauri/Cargo.lock
+1
-1
src-tauri/Cargo.lock
+1
-1
src-tauri/Cargo.toml
+1
-1
src-tauri/Cargo.toml
+1
-1
src-tauri/src/frontend_calls/close_splashscreen.rs
+1
-1
src-tauri/src/frontend_calls/close_splashscreen.rs
-2
src-tauri/src/util/get_photo_path.rs
-2
src-tauri/src/util/get_photo_path.rs
+5
src/Components/FilterMenu.tsx
+5
src/Components/FilterMenu.tsx
···
1
+
import { Show } from "solid-js";
2
import { FilterType } from "./Structs/FilterType";
3
4
let FilterMenu = () => {
···
11
12
return (
13
<>
14
+
<Show when={!window.PhotoManager.HasBeenIndexed()}>
15
+
<div>Your photos aren't indexed due to the large number, filters may take a while to load.</div>
16
+
<div style={{ height: '8px' }}></div>
17
+
</Show>
18
<div class="filter-type-select">
19
<div class="selected-filter" ref={( el ) => selectionButtons.push(el)} onClick={() => {
20
select(0);
+12
src/Components/Managers/PhotoListRenderingManager.tsx
+12
src/Components/Managers/PhotoListRenderingManager.tsx
···
9
private _layout: PhotoListRow[] = [];
10
private _canvas!: HTMLCanvasElement;
11
12
+
private _isLoading = false;
13
+
14
constructor(){}
15
16
public SetCanvas( canvas: HTMLCanvasElement ){
···
147
}
148
149
currentY += row.Height + 10;
150
+
}
151
+
152
+
if(!this._isLoading){
153
+
console.log('Loading more photos...');
154
+
this._isLoading = true;
155
+
156
+
window.PhotoManager.LoadSomeAndReloadFilters()
157
+
.then(() => {
158
+
this._isLoading = false;
159
+
});
160
}
161
}
162
}
+52
-7
src/Components/Managers/PhotoManager.tsx
+52
-7
src/Components/Managers/PhotoManager.tsx
···
20
21
private _filterType: FilterType = FilterType.USER;
22
private _filter: string = "";
23
24
constructor(){
25
let [ photoCount, setPhotoCount ] = createSignal(-1);
···
27
28
this.PhotoCount = photoCount;
29
this.PhotoSize = photoSize;
30
31
listen('photos_loaded', ( event: any ) => {
32
let photoPaths = event.payload.photos.reverse();
···
36
setPhotoSize(event.payload.size);
37
38
let doesHaveLegacy = false;
39
40
-
photoPaths.forEach(( path: string ) => {
41
let photo
42
43
if(path.slice(0, 9) === "legacy://"){
44
-
photo = new Photo(path.slice(9), true);
45
doesHaveLegacy = true;
46
} else
47
-
photo = new Photo(path, false);
48
49
this.Photos.push(photo);
50
-
photo.loadMeta();
51
})
52
53
if(doesHaveLegacy){
···
55
}
56
57
console.log(this.Photos.length + ' Photos found.');
58
-
if(this.Photos.length === 0){
59
console.log('No photos found, Skipping loading stage.');
60
61
this.FilteredPhotos = this.Photos;
···
63
64
this._finishedLoadingCallbacks.forEach(cb => cb());
65
}
66
});
67
68
listen('photo_meta_loaded', ( event: any ) => {
···
70
71
let photo = this.Photos.find(x => x.path === data.path);
72
if(!photo)return console.error('Cannot find photo.', data);
73
74
photo.width = data.width;
75
photo.height = data.height;
···
94
})
95
96
listen('photo_create', async ( event: any ) => {
97
-
let photo = new Photo(event.payload);
98
-
99
this.Photos.splice(0, 0, photo);
100
101
photo.onMetaLoaded = () => this.ReloadFilters();
···
124
125
public SetFilter( filter: string ){
126
this._filter = filter;
127
this.ReloadFilters();
128
}
129
···
20
21
private _filterType: FilterType = FilterType.USER;
22
private _filter: string = "";
23
+
24
+
private _lastLoaded: number = 0;
25
+
private _onLoadedMeta: any = {};
26
+
private _hasBeenIndexed: Accessor<boolean>;
27
28
constructor(){
29
let [ photoCount, setPhotoCount ] = createSignal(-1);
···
31
32
this.PhotoCount = photoCount;
33
this.PhotoSize = photoSize;
34
+
35
+
let setHasBeenIndexed;
36
+
[ this._hasBeenIndexed, setHasBeenIndexed ] = createSignal(false);
37
+
console.log(this._hasBeenIndexed())
38
39
listen('photos_loaded', ( event: any ) => {
40
let photoPaths = event.payload.photos.reverse();
···
44
setPhotoSize(event.payload.size);
45
46
let doesHaveLegacy = false;
47
+
48
+
if(photoPaths.length <= Vars.MAX_PHOTOS_BULK_LOAD)
49
+
setHasBeenIndexed(true);
50
51
+
photoPaths.forEach(( path: string, i: number ) => {
52
let photo
53
54
if(path.slice(0, 9) === "legacy://"){
55
+
photo = new Photo(path.slice(9), true, i);
56
doesHaveLegacy = true;
57
} else
58
+
photo = new Photo(path, false, i);
59
60
this.Photos.push(photo);
61
+
62
+
if(photoPaths.length <= Vars.MAX_PHOTOS_BULK_LOAD)
63
+
photo.loadMeta();
64
})
65
66
if(doesHaveLegacy){
···
68
}
69
70
console.log(this.Photos.length + ' Photos found.');
71
+
if(this.Photos.length === 0 || photoPaths.length > Vars.MAX_PHOTOS_BULK_LOAD){
72
console.log('No photos found, Skipping loading stage.');
73
74
this.FilteredPhotos = this.Photos;
···
76
77
this._finishedLoadingCallbacks.forEach(cb => cb());
78
}
79
+
80
+
console.log(this._hasBeenIndexed())
81
});
82
83
listen('photo_meta_loaded', ( event: any ) => {
···
85
86
let photo = this.Photos.find(x => x.path === data.path);
87
if(!photo)return console.error('Cannot find photo.', data);
88
+
89
+
this._lastLoaded = photo.index;
90
+
91
+
if(this._onLoadedMeta[photo.index]){
92
+
this._onLoadedMeta[photo.index]();
93
+
delete this._onLoadedMeta[photo.index];
94
+
}
95
96
photo.width = data.width;
97
photo.height = data.height;
···
116
})
117
118
listen('photo_create', async ( event: any ) => {
119
+
let photo = new Photo(event.payload, false, 0);
120
+
121
+
this.Photos.forEach(p => p.index++); // Probably a really dumb way of doing this
122
this.Photos.splice(0, 0, photo);
123
124
photo.onMetaLoaded = () => this.ReloadFilters();
···
147
148
public SetFilter( filter: string ){
149
this._filter = filter;
150
+
this.ReloadFilters();
151
+
}
152
+
153
+
public HasBeenIndexed(){
154
+
return this._hasBeenIndexed();
155
+
}
156
+
157
+
public LoadPhotoMetaAndWait( photo: Photo ){
158
+
return new Promise(res => {
159
+
photo.loadMeta();
160
+
this._onLoadedMeta[photo.index] = res;
161
+
})
162
+
}
163
+
164
+
public async LoadSomeAndReloadFilters(){
165
+
if(this.Photos.length < this._lastLoaded + 1)return;
166
+
167
+
for (let i = 1; i < 10; i++) {
168
+
if(!this.Photos[this._lastLoaded + 1])break;
169
+
await this.LoadPhotoMetaAndWait(this.Photos[this._lastLoaded + 1]);
170
+
}
171
+
172
this.ReloadFilters();
173
}
174
+4
-1
src/Components/PhotoList.tsx
+4
-1
src/Components/PhotoList.tsx
···
190
191
return (
192
<div class="photo-list">
193
+
<div ref={filterContainer!} class="filter-container" style={{
194
+
height: window.PhotoManager.HasBeenIndexed() ? '83px' : '110px',
195
+
width: window.PhotoManager.HasBeenIndexed() ? '600px' : '650px'
196
+
}}>
197
<FilterMenu />
198
</div>
199
+23
-4
src/Components/Structs/Photo.ts
+23
-4
src/Components/Structs/Photo.ts
···
27
date: Date;
28
29
legacy: boolean = false;
30
31
public onMetaLoaded: () => void = () => {};
32
33
-
constructor( path: string, isLegacy: boolean = false ){
34
this.path = path;
35
this.legacy = isLegacy;
36
37
if(this.legacy)
38
-
this.dateString = this.path.split('_')[2];
39
else
40
-
this.dateString = this.path.split('_')[1];
41
42
let splitDateString = this.dateString.split('-');
43
···
46
this.date.setFullYear(parseInt(splitDateString[0]));
47
this.date.setMonth(parseInt(splitDateString[1]));
48
this.date.setDate(parseInt(splitDateString[2]));
49
}
50
51
loadMeta(){
···
56
if(this.loading || this.loaded || imagesLoading >= Vars.MAX_IMAGE_LOAD)return;
57
58
// this.loadMeta();
59
-
if(!this.metaLoaded)return;
60
61
this.loading = true;
62
···
27
date: Date;
28
29
legacy: boolean = false;
30
+
index: number = 0;
31
32
public onMetaLoaded: () => void = () => {};
33
34
+
constructor( path: string, isLegacy: boolean = false, i: number ){
35
this.path = path;
36
this.legacy = isLegacy;
37
+
this.index = i;
38
+
39
+
let split = this.path.split('_');
40
41
if(this.legacy)
42
+
this.dateString = split[2];
43
else
44
+
this.dateString = split[1];
45
46
let splitDateString = this.dateString.split('-');
47
···
50
this.date.setFullYear(parseInt(splitDateString[0]));
51
this.date.setMonth(parseInt(splitDateString[1]));
52
this.date.setDate(parseInt(splitDateString[2]));
53
+
54
+
let resSplit = split[3].split('x');
55
+
56
+
let width = parseInt(resSplit[0]);
57
+
let height = parseInt(resSplit[1]);
58
+
59
+
if(!isNaN(width) || !isNaN(height)){
60
+
this.width = width;
61
+
this.height = height;
62
+
63
+
let scale = Vars.PHOTO_HEIGHT / this.height;
64
+
65
+
this.scaledWidth = this.width * scale;
66
+
this.scaledHeight = Vars.PHOTO_HEIGHT;
67
+
}
68
}
69
70
loadMeta(){
···
75
if(this.loading || this.loaded || imagesLoading >= Vars.MAX_IMAGE_LOAD)return;
76
77
// this.loadMeta();
78
+
if(!this.metaLoaded)return this.loadMeta();
79
80
this.loading = true;
81