+2
-1
changelog
+2
-1
changelog
···
94
94
v0.2.5:
95
95
- Fixed the "Start with windows" button appearing on linux
96
96
- Fixed linux tray icon title
97
-
- Fixed build-release.sh script outputting the wrong names for windows builds
97
+
- Fixed build-release.sh script outputting the wrong names for windows builds
98
+
- Fixed clipboard on linux ( and speeded it up on windows )
+88
-6
src-tauri/Cargo.lock
+88
-6
src-tauri/Cargo.lock
···
6
6
name = "VRChatPhotoManager"
7
7
version = "0.2.5"
8
8
dependencies = [
9
+
"arboard",
9
10
"dirs 5.0.1",
10
11
"fast_image_resize",
11
12
"image",
···
101
102
checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
102
103
103
104
[[package]]
105
+
name = "arboard"
106
+
version = "3.6.0"
107
+
source = "registry+https://github.com/rust-lang/crates.io-index"
108
+
checksum = "55f533f8e0af236ffe5eb979b99381df3258853f00ba2e44b6e1955292c75227"
109
+
dependencies = [
110
+
"clipboard-win",
111
+
"image",
112
+
"log",
113
+
"objc2 0.6.1",
114
+
"objc2-app-kit",
115
+
"objc2-core-foundation",
116
+
"objc2-core-graphics",
117
+
"objc2-foundation 0.3.1",
118
+
"parking_lot",
119
+
"percent-encoding",
120
+
"windows-sys 0.59.0",
121
+
"x11rb",
122
+
]
123
+
124
+
[[package]]
104
125
name = "arg_enum_proc_macro"
105
126
version = "0.3.4"
106
127
source = "registry+https://github.com/rust-lang/crates.io-index"
···
179
200
"futures-lite",
180
201
"parking",
181
202
"polling",
182
-
"rustix",
203
+
"rustix 1.0.8",
183
204
"slab",
184
205
"windows-sys 0.60.2",
185
206
]
···
210
231
"cfg-if",
211
232
"event-listener",
212
233
"futures-lite",
213
-
"rustix",
234
+
"rustix 1.0.8",
214
235
]
215
236
216
237
[[package]]
···
236
257
"cfg-if",
237
258
"futures-core",
238
259
"futures-io",
239
-
"rustix",
260
+
"rustix 1.0.8",
240
261
"signal-hook-registry",
241
262
"slab",
242
263
"windows-sys 0.60.2",
···
599
620
"num-traits",
600
621
"serde",
601
622
"windows-link",
623
+
]
624
+
625
+
[[package]]
626
+
name = "clipboard-win"
627
+
version = "5.4.1"
628
+
source = "registry+https://github.com/rust-lang/crates.io-index"
629
+
checksum = "bde03770d3df201d4fb868f2c9c59e66a3e4e2bd06692a0fe701e7103c7e84d4"
630
+
dependencies = [
631
+
"error-code",
602
632
]
603
633
604
634
[[package]]
···
1176
1206
]
1177
1207
1178
1208
[[package]]
1209
+
name = "error-code"
1210
+
version = "3.3.2"
1211
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1212
+
checksum = "dea2df4cf52843e0452895c455a1a2cfbb842a1e7329671acf418fdc53ed4c59"
1213
+
1214
+
[[package]]
1179
1215
name = "event-listener"
1180
1216
version = "5.4.0"
1181
1217
source = "registry+https://github.com/rust-lang/crates.io-index"
···
1553
1589
]
1554
1590
1555
1591
[[package]]
1592
+
name = "gethostname"
1593
+
version = "0.4.3"
1594
+
source = "registry+https://github.com/rust-lang/crates.io-index"
1595
+
checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818"
1596
+
dependencies = [
1597
+
"libc",
1598
+
"windows-targets 0.48.5",
1599
+
]
1600
+
1601
+
[[package]]
1556
1602
name = "getrandom"
1557
1603
version = "0.1.16"
1558
1604
source = "registry+https://github.com/rust-lang/crates.io-index"
···
2473
2519
"libc",
2474
2520
"redox_syscall",
2475
2521
]
2522
+
2523
+
[[package]]
2524
+
name = "linux-raw-sys"
2525
+
version = "0.4.15"
2526
+
source = "registry+https://github.com/rust-lang/crates.io-index"
2527
+
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
2476
2528
2477
2529
[[package]]
2478
2530
name = "linux-raw-sys"
···
3438
3490
"concurrent-queue",
3439
3491
"hermit-abi",
3440
3492
"pin-project-lite",
3441
-
"rustix",
3493
+
"rustix 1.0.8",
3442
3494
"windows-sys 0.60.2",
3443
3495
]
3444
3496
···
4029
4081
4030
4082
[[package]]
4031
4083
name = "rustix"
4084
+
version = "0.38.44"
4085
+
source = "registry+https://github.com/rust-lang/crates.io-index"
4086
+
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
4087
+
dependencies = [
4088
+
"bitflags 2.9.1",
4089
+
"errno",
4090
+
"libc",
4091
+
"linux-raw-sys 0.4.15",
4092
+
"windows-sys 0.59.0",
4093
+
]
4094
+
4095
+
[[package]]
4096
+
name = "rustix"
4032
4097
version = "1.0.8"
4033
4098
source = "registry+https://github.com/rust-lang/crates.io-index"
4034
4099
checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8"
···
4036
4101
"bitflags 2.9.1",
4037
4102
"errno",
4038
4103
"libc",
4039
-
"linux-raw-sys",
4104
+
"linux-raw-sys 0.9.4",
4040
4105
"windows-sys 0.60.2",
4041
4106
]
4042
4107
···
5090
5155
"fastrand",
5091
5156
"getrandom 0.3.3",
5092
5157
"once_cell",
5093
-
"rustix",
5158
+
"rustix 1.0.8",
5094
5159
"windows-sys 0.59.0",
5095
5160
]
5096
5161
···
6458
6523
"once_cell",
6459
6524
"pkg-config",
6460
6525
]
6526
+
6527
+
[[package]]
6528
+
name = "x11rb"
6529
+
version = "0.13.1"
6530
+
source = "registry+https://github.com/rust-lang/crates.io-index"
6531
+
checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12"
6532
+
dependencies = [
6533
+
"gethostname",
6534
+
"rustix 0.38.44",
6535
+
"x11rb-protocol",
6536
+
]
6537
+
6538
+
[[package]]
6539
+
name = "x11rb-protocol"
6540
+
version = "0.13.1"
6541
+
source = "registry+https://github.com/rust-lang/crates.io-index"
6542
+
checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d"
6461
6543
6462
6544
[[package]]
6463
6545
name = "xdg-home"
+1
src-tauri/Cargo.toml
+1
src-tauri/Cargo.toml
+25
src-tauri/src/frontend_calls/copy_image.rs
+25
src-tauri/src/frontend_calls/copy_image.rs
···
1
+
use std::{borrow::Cow, fs::{self, File}, io::BufReader, sync::Mutex};
2
+
3
+
use arboard::{Clipboard, ImageData};
4
+
use image::{codecs::png::PngDecoder, EncodableLayout, GenericImageView, ImageDecoder};
5
+
use tauri::State;
6
+
7
+
use crate::{ frontend_calls::get_user_photos_path::get_user_photos_path, pngmeta::PNGImage, util::cache::Cache };
8
+
9
+
#[tauri::command]
10
+
pub fn copy_image( path: String, clipboard: State<Mutex<Clipboard>>, cache: State<Cache> ) {
11
+
let path = format!("{}/{}", get_user_photos_path(cache), path);
12
+
println!("Copying Image: {}", &path);
13
+
14
+
let img = image::open(path).unwrap();
15
+
let size = img.dimensions();
16
+
17
+
let img_data = ImageData {
18
+
width: size.0 as usize,
19
+
height: size.1 as usize,
20
+
bytes: Cow::from(img.into_rgba8().to_vec())
21
+
};
22
+
23
+
let mut lock = clipboard.lock().unwrap();
24
+
lock.set_image(img_data).unwrap();
25
+
}
+1
src-tauri/src/frontend_calls/mod.rs
+1
src-tauri/src/frontend_calls/mod.rs
+7
-2
src-tauri/src/main.rs
+7
-2
src-tauri/src/main.rs
···
7
7
mod worldscraper;
8
8
9
9
use core::time;
10
+
use arboard::Clipboard;
10
11
use frontend_calls::*;
11
12
12
13
use notify::{ EventKind, RecursiveMode, Watcher };
13
14
use pngmeta::PNGImage;
14
15
use regex::Regex;
15
16
use util::{ cache::Cache, get_photo_path::get_photo_path };
16
-
use std::{ env, fs, thread };
17
+
use std::{ env, fs, sync::Mutex, thread };
17
18
use tauri::{ Emitter, Manager, State, WindowEvent };
18
19
use tauri_plugin_deep_link::DeepLinkExt;
19
20
···
142
143
)
143
144
.unwrap();
144
145
146
+
let clipboard = Clipboard::new().unwrap();
147
+
145
148
tauri::Builder::default()
146
149
.plugin(tauri_plugin_single_instance::init(| app, argv, _cwd | {
147
150
app.get_webview_window("main").unwrap().show().unwrap();
···
163
166
_ => {}
164
167
})
165
168
.manage(cache)
169
+
.manage(Mutex::new(clipboard))
166
170
.setup(|app| {
167
171
let handle = app.handle();
168
172
···
209
213
config::get_config_value_string,
210
214
config::set_config_value_int,
211
215
config::get_config_value_int,
212
-
get_os::get_os
216
+
get_os::get_os,
217
+
copy_image::copy_image
213
218
])
214
219
.run(tauri::generate_context!())
215
220
.expect("error while running tauri application");
+9
-9
src-tauri/src/pngmeta.rs
+9
-9
src-tauri/src/pngmeta.rs
···
3
3
4
4
#[derive(Clone)]
5
5
pub struct PNGImage {
6
-
width: u32,
7
-
height: u32,
8
-
bit_depth: u8,
9
-
colour_type: u8,
10
-
compression_method: u8,
11
-
filter_method: u8,
12
-
interlace_method: u8,
13
-
metadata: String,
14
-
path: String,
6
+
pub width: u32,
7
+
pub height: u32,
8
+
pub bit_depth: u8,
9
+
pub colour_type: u8,
10
+
pub compression_method: u8,
11
+
pub filter_method: u8,
12
+
pub interlace_method: u8,
13
+
pub metadata: String,
14
+
pub path: String,
15
15
}
16
16
17
17
impl PNGImage {
+14
-29
src/Components/PhotoViewer.tsx
+14
-29
src/Components/PhotoViewer.tsx
···
84
84
}
85
85
86
86
let copyImage = () => {
87
-
let canvas = document.createElement('canvas');
88
-
let ctx = canvas.getContext('2d')!;
89
-
90
-
canvas.width = window.PhotoViewerManager.CurrentPhoto()?.width || 0;
91
-
canvas.height = window.PhotoViewerManager.CurrentPhoto()?.height || 0;
92
-
93
-
ctx.drawImage(imageViewer, 0, 0);
94
-
95
-
canvas.toBlob(( blob ) => {
96
-
navigator.clipboard.write([
97
-
new ClipboardItem({
98
-
'image/png': blob!
99
-
})
100
-
]);
101
-
102
-
canvas.remove();
103
-
104
-
anime.set('.copy-notif', { translateX: '-50%', translateY: '-100px' });
105
-
anime({
106
-
targets: '.copy-notif',
107
-
opacity: 1,
108
-
translateY: '0px'
109
-
});
110
-
111
-
setTimeout(() => {
87
+
invoke('copy_image', { path: window.PhotoViewerManager.CurrentPhoto()!.path })
88
+
.then(() => {
89
+
anime.set('.copy-notif', { translateX: '-50%', translateY: '-100px' });
112
90
anime({
113
91
targets: '.copy-notif',
114
-
opacity: 0,
115
-
translateY: '-100px'
92
+
opacity: 1,
93
+
translateY: '0px'
116
94
});
117
-
}, 2000);
118
-
});
95
+
96
+
setTimeout(() => {
97
+
anime({
98
+
targets: '.copy-notif',
99
+
opacity: 0,
100
+
translateY: '-100px'
101
+
});
102
+
}, 2000);
103
+
})
119
104
}
120
105
121
106
let closeTray = () => {