+4
-1
changelog
+4
-1
changelog
···
64
64
- Fixed world cache not being saved to the config file
65
65
66
66
v0.2.3:
67
-
- Finally replaced the awful render function in the frontend
67
+
- Finally replaced the awful render function in the frontend, ( should use less resources when app is open )
68
+
- Fixed photos not being lined up
69
+
- Fixed filters not updating photo list
70
+
- Fixed adding / removing photos not updating the photo list
68
71
69
72
Dev Stuff:
70
73
- Split frontend up into many smaller files for easier editing
+10
-9
src-tauri/src/main.rs
+10
-9
src-tauri/src/main.rs
···
12
12
use notify::{EventKind, RecursiveMode, Watcher};
13
13
use pngmeta::PNGImage;
14
14
use regex::Regex;
15
-
use util::cache::Cache;
15
+
use util::{cache::Cache, get_photo_path::get_photo_path};
16
16
use std::{env, fs, thread};
17
17
use tauri::{Emitter, Manager, State, WindowEvent};
18
18
use tauri_plugin_deep_link::DeepLinkExt;
···
92
92
// Listen for file updates, store each update in an mpsc channel and send to the frontend
93
93
let (sender, receiver) = std::sync::mpsc::channel();
94
94
let mut watcher = notify::recommended_watcher(move | res: Result<notify::Event, notify::Error> | {
95
-
// TODO: Fix this, why does it not work?? it does work???
96
95
match res {
97
-
Ok(event) => {
96
+
Ok(event) => {
98
97
match event.kind{
99
98
EventKind::Remove(_) => {
100
99
let path = event.paths.first().unwrap();
100
+
let name = path.file_name().unwrap().to_str().unwrap().to_owned();
101
101
102
102
let re1 = Regex::new(r"(?m)VRChat_[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}-[0-9]{2}-[0-9]{2}.[0-9]{3}_[0-9]{4}x[0-9]{4}.png").unwrap();
103
103
let re2 = Regex::new(r"(?m)/VRChat_[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}-[0-9]{2}-[0-9]{2}.[0-9]{3}_[0-9]{4}x[0-9]{4}_wrld_[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}.png/gm").unwrap();
104
104
105
105
if
106
-
re1.is_match(path.to_str().unwrap()) ||
107
-
re2.is_match(path.to_str().unwrap())
106
+
re1.is_match(&name) ||
107
+
re2.is_match(&name)
108
108
{
109
-
sender.send((2, path.clone().strip_prefix(util::get_photo_path::get_photo_path()).unwrap().to_path_buf())).unwrap();
109
+
sender.send((2, path.strip_prefix(get_photo_path()).unwrap().to_str().unwrap().to_owned())).unwrap();
110
110
}
111
111
},
112
112
EventKind::Create(_) => {
113
113
let path = event.paths.first().unwrap();
114
+
let name = path.file_name().unwrap().to_str().unwrap().to_owned();
114
115
115
116
let re1 = Regex::new(r"(?m)VRChat_[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}-[0-9]{2}-[0-9]{2}.[0-9]{3}_[0-9]{4}x[0-9]{4}.png").unwrap();
116
117
let re2 = Regex::new(r"(?m)/VRChat_[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}-[0-9]{2}-[0-9]{2}.[0-9]{3}_[0-9]{4}x[0-9]{4}_wrld_[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}.png/gm").unwrap();
117
118
118
119
if
119
-
re1.is_match(path.to_str().unwrap()) ||
120
-
re2.is_match(path.to_str().unwrap())
120
+
re1.is_match(&name) ||
121
+
re2.is_match(&name)
121
122
{
122
123
thread::sleep(time::Duration::from_millis(1000));
123
-
sender.send((1, path.clone().strip_prefix(util::get_photo_path::get_photo_path()).unwrap().to_path_buf())).unwrap();
124
+
sender.send((1, path.strip_prefix(get_photo_path()).unwrap().to_str().unwrap().to_owned())).unwrap();
124
125
}
125
126
},
126
127
_ => {}
+19
-8
src/Components/Managers/PhotoListRenderingManager.tsx
+19
-8
src/Components/Managers/PhotoListRenderingManager.tsx
···
7
7
8
8
export class PhotoListRenderingManager{
9
9
private _layout: PhotoListRow[] = [];
10
+
private _canvas!: HTMLCanvasElement;
10
11
11
12
constructor(){}
12
13
13
-
public ComputeLayout( canvas: HTMLCanvasElement ){
14
+
public SetCanvas( canvas: HTMLCanvasElement ){
15
+
this._canvas = canvas;
16
+
}
17
+
18
+
public ComputeLayout(){
19
+
this._layout = [];
20
+
14
21
let lastDateString = null;
15
22
let row = new PhotoListRow();
16
23
row.Height = 100;
···
36
43
37
44
// Check if the current row width plus another photo is too big to fit, push this row to the
38
45
// layout and add the photo to the next row instead
39
-
if(row.Width + photo.scaledWidth! + 10 > canvas.width - 100){
46
+
if(row.Width + photo.scaledWidth! + 10 > this._canvas.width - 100){
40
47
this._layout.push(row);
41
48
row = new PhotoListRow();
42
49
}
43
50
44
51
// We should now add this photo to the current row
45
52
row.Elements.push(new PhotoListPhoto(photo));
46
-
row.Width += photo.scaledWidth!;
53
+
row.Width += photo.scaledWidth! + 10;
47
54
}
48
55
49
56
this._layout.push(row);
···
81
88
currentY += row.Height + 10;
82
89
continue;
83
90
}
91
+
92
+
// === DEBUG ===
93
+
// ctx.strokeStyle = '#f00';
94
+
// ctx.strokeRect((canvas.width / 2) - row.Width / 2, currentY - 5 - scroll, row.Width, row.Height + 10);
84
95
85
96
// Loop through all elements in the row
86
-
let rowXPos = 0;
97
+
let rowXPos = 10;
87
98
for (let j = 0; j < row.Elements.length; j++) {
88
99
let el = row.Elements[j];
89
100
···
93
104
// and then render that text
94
105
95
106
// === DEBUG ===
96
-
ctx.strokeStyle = '#f00';
97
-
ctx.strokeRect(0, currentY - scroll, canvas.width, row.Height);
107
+
// ctx.strokeStyle = '#f00';
108
+
// ctx.strokeRect(0, currentY - scroll, canvas.width, row.Height);
98
109
99
110
ctx.textAlign = 'center';
100
111
ctx.textBaseline = 'middle';
···
108
119
let photo = (el as PhotoListPhoto).Photo;
109
120
110
121
// === DEBUG ===
111
-
ctx.strokeStyle = '#f00';
112
-
ctx.strokeRect((rowXPos - row.Width / 2) + canvas.width / 2, currentY - scroll, photo.scaledWidth!, row.Height);
122
+
// ctx.strokeStyle = '#f00';
123
+
// ctx.strokeRect((rowXPos - row.Width / 2) + canvas.width / 2, currentY - scroll, photo.scaledWidth!, row.Height);
113
124
114
125
if(!photo.loaded)
115
126
// If the photo is not loaded, start a new task and load it in that task
+21
-14
src/Components/Managers/PhotoManager.tsx
+21
-14
src/Components/Managers/PhotoManager.tsx
···
69
69
let data: PhotoMetadata = event.payload;
70
70
71
71
let photo = this.Photos.find(x => x.path === data.path);
72
-
if(!photo)return;
72
+
if(!photo)return console.error('Cannot find photo.', data);
73
73
74
74
photo.width = data.width;
75
75
photo.height = data.height;
···
84
84
85
85
photo.metaLoaded = true;
86
86
photo.onMetaLoaded();
87
-
88
-
// this.ReloadFilters();
89
-
90
-
console.log(this._amountLoaded, this.Photos.length);
91
-
if(this._amountLoaded === this.Photos.length && !this.HasFirstLoaded){
87
+
88
+
if(this._amountLoaded === this.Photos.length - 1 && !this.HasFirstLoaded){
92
89
this.FilteredPhotos = this.Photos;
93
90
this.HasFirstLoaded = true;
94
91
···
100
97
let photo = new Photo(event.payload);
101
98
102
99
this.Photos.splice(0, 0, photo);
100
+
101
+
photo.onMetaLoaded = () => this.ReloadFilters();
103
102
photo.loadMeta();
104
103
105
104
if(!window.SyncManager.IsSyncing() && window.AccountManager.Storage()?.isSyncing){
···
113
112
114
113
if(event.payload === window.PhotoViewerManager.CurrentPhoto()?.path)
115
114
window.PhotoViewerManager.Close()
115
+
116
+
this.ReloadFilters();
116
117
})
117
118
}
118
119
···
133
134
case FilterType.USER:
134
135
this.Photos.map(p => {
135
136
if(p.metadata){
136
-
let meta = JSON.parse(p.metadata);
137
-
let photo = meta.players.find(( y: any ) => y.displayName.toLowerCase().includes(this._filter) || y.id === this._filter);
138
-
139
-
if(photo)this.FilteredPhotos.push(p);
137
+
try{
138
+
let meta = JSON.parse(p.metadata);
139
+
let photo = meta.players.find(( y: any ) => y.displayName.toLowerCase().includes(this._filter) || y.id === this._filter);
140
+
141
+
if(photo)this.FilteredPhotos.push(p);
142
+
} catch(e){}
140
143
}
141
144
})
142
145
break;
143
146
case FilterType.WORLD:
144
147
this.Photos.map(p => {
145
148
if(p.metadata){
146
-
let meta = JSON.parse(p.metadata);
147
-
let photo = meta.world.name.toLowerCase().includes(this._filter) || meta.world.id === this._filter;
148
-
149
-
if(photo)this.FilteredPhotos.push(p);
149
+
try{
150
+
let meta = JSON.parse(p.metadata);
151
+
let photo = meta.world.name.toLowerCase().includes(this._filter) || meta.world.id === this._filter;
152
+
153
+
if(photo)this.FilteredPhotos.push(p);
154
+
} catch(e){}
150
155
}
151
156
})
152
157
break;
153
158
}
159
+
160
+
window.PhotoListRenderingManager.ComputeLayout();
154
161
}
155
162
156
163
public Load(){
+4
-2
src/Components/PhotoList.tsx
+4
-2
src/Components/PhotoList.tsx
···
129
129
easing: 'easeInOutQuad'
130
130
})
131
131
132
-
window.PhotoListRenderingManager.ComputeLayout(photoContainer!);
132
+
window.PhotoListRenderingManager.SetCanvas(photoContainer!);
133
+
window.PhotoListRenderingManager.ComputeLayout();
134
+
133
135
render();
134
136
});
135
137
···
163
165
photoContainerBG.width = window.innerWidth;
164
166
photoContainerBG.height = window.innerHeight;
165
167
166
-
window.PhotoListRenderingManager.ComputeLayout(photoContainer!);
168
+
window.PhotoListRenderingManager.ComputeLayout();
167
169
})
168
170
169
171
photoContainer.addEventListener('click', ( e: MouseEvent ) => {
+1
-1
src/Components/Structs/Photo.ts
+1
-1
src/Components/Structs/Photo.ts