A photo manager for VRChat.

stuff

Changed files
+39 -26
src
Components
src-tauri
+4 -1
changelog
··· 51 51 52 52 v0.2.2: 53 53 - Use more linux friendly directories 54 - - Move away from localstorage and use the .config file 54 + - Move away from localstorage and use the .config file 55 + - Seems to be semi-stable on linux 56 + - Update deeplink library 57 + - Fix bugs with multiple screens displaying on frontend
+1 -1
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::handle_deeplink; 16 15 use std::{env, fs, thread}; 17 16 use tauri::{Emitter, Manager, WindowEvent}; 18 17 use tauri_plugin_deep_link::DeepLinkExt; ··· 124 123 } 125 124 }).unwrap(); 126 125 126 + println!("Watching dir: {:?}", util::get_photo_path::get_photo_path()); 127 127 watcher 128 128 .watch( 129 129 &util::get_photo_path::get_photo_path(),
+3 -3
src-tauri/src/photosync.rs
··· 14 14 pub fn sync_photos(token: String, path: path::PathBuf, window: tauri::Window) { 15 15 let sync_lock_path = dirs::config_dir() 16 16 .unwrap() 17 - .join("PhazeDev\\VRChatPhotoManager\\.sync_lock"); 17 + .join("PhazeDev/VRChatPhotoManager/.sync_lock"); 18 18 19 19 match fs::metadata(&sync_lock_path) { 20 20 Ok(_) => { ··· 207 207 folder_name.nth(0).unwrap() 208 208 ); 209 209 210 - let full_path = format!("{}\\{}\\{}", path.to_str().unwrap(), folder_name, photo); 210 + let full_path = format!("{}/{}/{}", path.to_str().unwrap(), folder_name, photo); 211 211 212 212 let res = client 213 213 .get(format!( ··· 221 221 222 222 match res { 223 223 Ok(res) => { 224 - let folder_path = format!("{}\\{}", path.to_str().unwrap(), folder_name); 224 + let folder_path = format!("{}/{}", path.to_str().unwrap(), folder_name); 225 225 match fs::metadata(&folder_path) { 226 226 Ok(_) => {} 227 227 Err(_) => {
+31 -21
src/Components/PhotoList.tsx
··· 372 372 }) 373 373 374 374 listen('show-window', () => { 375 - requestAnimationFrame(render); 375 + if(hasFirstLoaded) 376 + requestAnimationFrame(render); 376 377 }) 377 378 378 379 listen('photo_meta_loaded', ( event: any ) => { ··· 471 472 472 473 let loadPhotos = async () => { 473 474 photoPath = await invoke('get_user_photos_path') + '/'; 474 - invoke('load_photos') 475 475 476 476 listen('photos_loaded', ( event: any ) => { 477 477 let photoPaths = event.payload.photos.reverse(); ··· 482 482 483 483 let doesHaveLegacy = false; 484 484 485 - if(photoPaths.length === 0){ 485 + photoPaths.forEach(( path: string ) => { 486 + let photo 487 + 488 + if(path.slice(0, 9) === "legacy://"){ 489 + photo = new Photo(path.slice(9), true); 490 + doesHaveLegacy = true; 491 + } else 492 + photo = new Photo(path, false); 493 + 494 + photos.push(photo); 495 + photo.loadMeta(); 496 + }) 497 + 498 + if(doesHaveLegacy){ 499 + photos = photos.sort(( a, b ) => b.date.valueOf() - a.date.valueOf()); 500 + } 501 + 502 + console.log(photos.length + ' Photos found.'); 503 + if(photos.length === 0){ 504 + console.log('No photos found, Skipping loading stage.'); 505 + 506 + filteredPhotos = photos; 507 + hasFirstLoaded = true; 508 + 486 509 anime({ 487 510 targets: photoTreeLoadingContainer, 488 511 height: 0, ··· 493 516 photoTreeLoadingContainer.style.display = 'none'; 494 517 } 495 518 }) 496 - 519 + 497 520 anime({ 498 521 targets: '.reload-photos', 499 522 opacity: 1, 500 523 duration: 150, 501 524 easing: 'easeInOutQuad' 502 525 }) 503 - } 504 526 505 - photoPaths.forEach(( path: string ) => { 506 - let photo 507 - 508 - if(path.slice(0, 9) === "legacy://"){ 509 - photo = new Photo(path.slice(9), true); 510 - doesHaveLegacy = true; 511 - } else 512 - photo = new Photo(path, false); 513 - 514 - photos.push(photo); 515 - photo.loadMeta(); 516 - }) 517 - 518 - if(doesHaveLegacy){ 519 - photos = photos.sort(( a, b ) => b.date.valueOf() - a.date.valueOf()); 527 + render(); 520 528 } 521 - }) 529 + }); 530 + 531 + invoke('load_photos'); 522 532 } 523 533 524 534 onMount(() => {