@pipelab/asset-tauri 1.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +110 -0
- package/package.json +18 -0
- package/template/README.md +7 -0
- package/template/index.html +45 -0
- package/template/package.json +23 -0
- package/template/pnpm-lock.yaml +715 -0
- package/template/src-tauri/Cargo.lock +11191 -0
- package/template/src-tauri/Cargo.toml +40 -0
- package/template/src-tauri/build.rs +3 -0
- package/template/src-tauri/capabilities/default.json +7 -0
- package/template/src-tauri/icons/128x128.png +0 -0
- package/template/src-tauri/icons/128x128@2x.png +0 -0
- package/template/src-tauri/icons/32x32.png +0 -0
- package/template/src-tauri/icons/Square107x107Logo.png +0 -0
- package/template/src-tauri/icons/Square142x142Logo.png +0 -0
- package/template/src-tauri/icons/Square150x150Logo.png +0 -0
- package/template/src-tauri/icons/Square284x284Logo.png +0 -0
- package/template/src-tauri/icons/Square30x30Logo.png +0 -0
- package/template/src-tauri/icons/Square310x310Logo.png +0 -0
- package/template/src-tauri/icons/Square44x44Logo.png +0 -0
- package/template/src-tauri/icons/Square71x71Logo.png +0 -0
- package/template/src-tauri/icons/Square89x89Logo.png +0 -0
- package/template/src-tauri/icons/StoreLogo.png +0 -0
- package/template/src-tauri/icons/icon.icns +0 -0
- package/template/src-tauri/icons/icon.ico +0 -0
- package/template/src-tauri/icons/icon.png +0 -0
- package/template/src-tauri/src/lib copy 2.rs +438 -0
- package/template/src-tauri/src/lib copy.rs +449 -0
- package/template/src-tauri/src/lib.rs +616 -0
- package/template/src-tauri/src/lib_webview_screenshot.rs +430 -0
- package/template/src-tauri/src/main.rs +6 -0
- package/template/src-tauri/tauri.conf.json +36 -0
- package/template/tsconfig.json +23 -0
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
use futures_util::StreamExt;
|
|
2
|
+
use std::env;
|
|
3
|
+
use std::error::Error;
|
|
4
|
+
use std::net::SocketAddr;
|
|
5
|
+
use std::sync::Arc;
|
|
6
|
+
use std::{borrow::Cow, sync::Mutex, time::Instant};
|
|
7
|
+
use steamworks::AppId;
|
|
8
|
+
use steamworks::Client;
|
|
9
|
+
use steamworks::FriendFlags;
|
|
10
|
+
use steamworks::PersonaStateChange;
|
|
11
|
+
use tauri::WebviewWindow;
|
|
12
|
+
use tauri::{async_runtime, Emitter, Manager, RunEvent, WindowEvent};
|
|
13
|
+
use tokio::sync::mpsc::{Receiver, Sender};
|
|
14
|
+
use tokio::sync::oneshot;
|
|
15
|
+
use warp::Filter;
|
|
16
|
+
|
|
17
|
+
pub struct WgpuState<'win> {
|
|
18
|
+
pub queue: wgpu::Queue,
|
|
19
|
+
pub device: wgpu::Device,
|
|
20
|
+
pub surface: wgpu::Surface<'win>,
|
|
21
|
+
pub render_pipeline: wgpu::RenderPipeline,
|
|
22
|
+
pub config: Mutex<wgpu::SurfaceConfiguration>,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
impl WgpuState<'_> {
|
|
26
|
+
pub async fn new(window: WebviewWindow) -> Self {
|
|
27
|
+
let size = window.inner_size().unwrap();
|
|
28
|
+
let instance = wgpu::Instance::default();
|
|
29
|
+
let surface = instance.create_surface(window).unwrap();
|
|
30
|
+
let adapter = instance
|
|
31
|
+
.request_adapter(&wgpu::RequestAdapterOptions {
|
|
32
|
+
power_preference: wgpu::PowerPreference::default(),
|
|
33
|
+
force_fallback_adapter: false,
|
|
34
|
+
compatible_surface: Some(&surface),
|
|
35
|
+
})
|
|
36
|
+
.await
|
|
37
|
+
.expect("Failed to find an appropriate adapter");
|
|
38
|
+
|
|
39
|
+
let (device, queue) = adapter
|
|
40
|
+
.request_device(
|
|
41
|
+
&wgpu::DeviceDescriptor {
|
|
42
|
+
label: None,
|
|
43
|
+
required_features: wgpu::Features::empty(),
|
|
44
|
+
required_limits: wgpu::Limits::downlevel_webgl2_defaults()
|
|
45
|
+
.using_resolution(adapter.limits()),
|
|
46
|
+
},
|
|
47
|
+
None,
|
|
48
|
+
)
|
|
49
|
+
.await
|
|
50
|
+
.expect("Failed to create device");
|
|
51
|
+
|
|
52
|
+
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
|
53
|
+
label: None,
|
|
54
|
+
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(
|
|
55
|
+
r#"
|
|
56
|
+
@vertex
|
|
57
|
+
fn vs_main(@builtin(vertex_index) vertex_index: u32) -> @builtin(position) vec4<f32> {
|
|
58
|
+
var position: vec4<f32>;
|
|
59
|
+
switch (vertex_index) {
|
|
60
|
+
case 0u: {
|
|
61
|
+
position = vec4<f32>(-1.0, -1.0, 0.0, 1.0); // Bottom-left
|
|
62
|
+
}
|
|
63
|
+
case 1u: {
|
|
64
|
+
position = vec4<f32>( 1.0, -1.0, 0.0, 1.0); // Bottom-right
|
|
65
|
+
}
|
|
66
|
+
case 2u: {
|
|
67
|
+
position = vec4<f32>( 0.0, 1.0, 0.0, 1.0); // Top-center
|
|
68
|
+
}
|
|
69
|
+
default: {
|
|
70
|
+
position = vec4<f32>(0.0, 0.0, 0.0, 1.0); // Default case (should not be reached)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return position;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@fragment
|
|
77
|
+
fn fs_main() -> @location(0) vec4<f32> {
|
|
78
|
+
// Output a solid color
|
|
79
|
+
return vec4<f32>(0.0, 1.0, 0.0, 0.5); // Green
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
"#,
|
|
83
|
+
)),
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
|
87
|
+
label: None,
|
|
88
|
+
push_constant_ranges: &[],
|
|
89
|
+
bind_group_layouts: &[],
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
let swapchain_capabilities = surface.get_capabilities(&adapter);
|
|
93
|
+
println!("swapchain_capabilities {:?}", swapchain_capabilities);
|
|
94
|
+
let swapchain_format = swapchain_capabilities.formats[0];
|
|
95
|
+
|
|
96
|
+
let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
|
97
|
+
label: None,
|
|
98
|
+
layout: Some(&pipeline_layout),
|
|
99
|
+
vertex: wgpu::VertexState {
|
|
100
|
+
module: &shader,
|
|
101
|
+
entry_point: "vs_main",
|
|
102
|
+
buffers: &[],
|
|
103
|
+
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
|
104
|
+
},
|
|
105
|
+
fragment: Some(wgpu::FragmentState {
|
|
106
|
+
module: &shader,
|
|
107
|
+
entry_point: "fs_main",
|
|
108
|
+
targets: &[Some(wgpu::ColorTargetState {
|
|
109
|
+
format: swapchain_format,
|
|
110
|
+
blend: Some(wgpu::BlendState::ALPHA_BLENDING),
|
|
111
|
+
write_mask: wgpu::ColorWrites::ALL,
|
|
112
|
+
})],
|
|
113
|
+
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
|
114
|
+
}),
|
|
115
|
+
primitive: wgpu::PrimitiveState::default(),
|
|
116
|
+
depth_stencil: None,
|
|
117
|
+
multisample: wgpu::MultisampleState::default(),
|
|
118
|
+
multiview: None,
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
let alpha_mode = if swapchain_capabilities
|
|
122
|
+
.alpha_modes
|
|
123
|
+
.contains(&wgpu::CompositeAlphaMode::PreMultiplied)
|
|
124
|
+
{
|
|
125
|
+
wgpu::CompositeAlphaMode::PreMultiplied
|
|
126
|
+
} else {
|
|
127
|
+
swapchain_capabilities.alpha_modes[0]
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
let config = wgpu::SurfaceConfiguration {
|
|
131
|
+
width: size.width,
|
|
132
|
+
height: size.height,
|
|
133
|
+
format: swapchain_format,
|
|
134
|
+
usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::COPY_SRC,
|
|
135
|
+
present_mode: wgpu::PresentMode::Fifo,
|
|
136
|
+
alpha_mode,
|
|
137
|
+
view_formats: vec![],
|
|
138
|
+
desired_maximum_frame_latency: 2,
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
surface.configure(&device, &config);
|
|
142
|
+
|
|
143
|
+
Self {
|
|
144
|
+
device,
|
|
145
|
+
queue,
|
|
146
|
+
surface,
|
|
147
|
+
render_pipeline,
|
|
148
|
+
config: Mutex::new(config),
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
#[tauri::command]
|
|
154
|
+
fn showOverlay() {
|
|
155
|
+
println!("Showing overlay");
|
|
156
|
+
match Client::init_app(480) {
|
|
157
|
+
Ok((client, _single)) => {
|
|
158
|
+
println!("Client created");
|
|
159
|
+
client.friends().activate_game_overlay("hey");
|
|
160
|
+
println!("Overlay shown");
|
|
161
|
+
}
|
|
162
|
+
Err(e) => eprintln!("Failed to initialize Steam client: {:?}", e),
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async fn websocket_server(tx: Sender<String>, mut rx: Receiver<String>) {
|
|
167
|
+
let addr = SocketAddr::from(([127, 0, 0, 1], 31753));
|
|
168
|
+
|
|
169
|
+
// WebSocket upgrade
|
|
170
|
+
let ws_route = warp::path::end()
|
|
171
|
+
.and(warp::ws())
|
|
172
|
+
.map(move |ws: warp::ws::Ws| {
|
|
173
|
+
let tx = tx.clone();
|
|
174
|
+
ws.on_upgrade(move |websocket| async move {
|
|
175
|
+
let (mut ws_tx, mut ws_rx) = websocket.split();
|
|
176
|
+
|
|
177
|
+
// Forward messages to the sender
|
|
178
|
+
while let Some(result) = ws_rx.next().await {
|
|
179
|
+
if let Ok(msg) = result {
|
|
180
|
+
if let Ok(text) = msg.to_str() {
|
|
181
|
+
println!("Received WebSocket message: {}", text);
|
|
182
|
+
if tx.send(text.to_string()).await.is_err() {
|
|
183
|
+
eprintln!("Failed to send message to channel");
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
})
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
let routes = ws_route;
|
|
193
|
+
|
|
194
|
+
// Spawn HTTP server
|
|
195
|
+
tokio::spawn(warp::serve(routes).run(addr));
|
|
196
|
+
println!("WebSocket server running on ws://{}", addr);
|
|
197
|
+
|
|
198
|
+
// Process messages from the receiver
|
|
199
|
+
while let Some(message) = rx.recv().await {
|
|
200
|
+
println!("Processing message: {}", message);
|
|
201
|
+
// Handle messages as needed
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
fn setup_wgpu_overlay(app: &mut tauri::App) -> Result<(), Box<dyn std::error::Error>> {
|
|
206
|
+
println!("Webgpu rendering");
|
|
207
|
+
|
|
208
|
+
let window = app.get_webview_window("main").unwrap();
|
|
209
|
+
let size = window.inner_size()?;
|
|
210
|
+
|
|
211
|
+
// Create a WgpuState (containing the device, instance, adapter etc.)
|
|
212
|
+
// And store it in the state
|
|
213
|
+
let wgpu_state = async_runtime::block_on(WgpuState::new(window));
|
|
214
|
+
app.manage(Arc::new(wgpu_state));
|
|
215
|
+
|
|
216
|
+
let app_handle = app.app_handle().clone();
|
|
217
|
+
|
|
218
|
+
async_runtime::spawn(async move {
|
|
219
|
+
let wgpu_state = app_handle.state::<Arc<WgpuState>>();
|
|
220
|
+
|
|
221
|
+
while true {
|
|
222
|
+
let t = Instant::now();
|
|
223
|
+
|
|
224
|
+
let output = match wgpu_state.surface.get_current_texture() {
|
|
225
|
+
Ok(output) => output,
|
|
226
|
+
Err(wgpu::SurfaceError::Lost) => {
|
|
227
|
+
println!("Surface lost, recreating surface...");
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
Err(wgpu::SurfaceError::OutOfMemory) => {
|
|
231
|
+
eprintln!("Out of memory error");
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
Err(e) => {
|
|
235
|
+
eprintln!("Failed to acquire next swap chain texture: {:?}", e);
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
// let view = output
|
|
240
|
+
// .texture
|
|
241
|
+
// .create_view(&wgpu::TextureViewDescriptor::default());
|
|
242
|
+
|
|
243
|
+
// let mut encoder = wgpu_state
|
|
244
|
+
// .device
|
|
245
|
+
// .create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
|
246
|
+
// {
|
|
247
|
+
// let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
|
248
|
+
// label: None,
|
|
249
|
+
// color_attachments: &[Some(wgpu::RenderPassColorAttachment {
|
|
250
|
+
// view: &view,
|
|
251
|
+
// resolve_target: None,
|
|
252
|
+
// ops: wgpu::Operations {
|
|
253
|
+
// load: wgpu::LoadOp::Clear(wgpu::Color::GREEN),
|
|
254
|
+
// store: wgpu::StoreOp::Store,
|
|
255
|
+
// },
|
|
256
|
+
// })],
|
|
257
|
+
// depth_stencil_attachment: None,
|
|
258
|
+
// timestamp_writes: None,
|
|
259
|
+
// occlusion_query_set: None,
|
|
260
|
+
// });
|
|
261
|
+
// rpass.set_pipeline(&wgpu_state.render_pipeline);
|
|
262
|
+
// rpass.draw(0..3, 0..1);
|
|
263
|
+
// }
|
|
264
|
+
|
|
265
|
+
// wgpu_state.queue.submit(Some(encoder.finish()));
|
|
266
|
+
|
|
267
|
+
// Read the texture data before calling present
|
|
268
|
+
let width = output.texture.size().width as usize;
|
|
269
|
+
let height = output.texture.size().height as usize;
|
|
270
|
+
let bytes_per_pixel = 4; // RGBA8 format
|
|
271
|
+
let unaligned_bytes_per_row = width * bytes_per_pixel;
|
|
272
|
+
let aligned_bytes_per_row = ((unaligned_bytes_per_row + 255) / 256) * 256;
|
|
273
|
+
let buffer_size = aligned_bytes_per_row * output.texture.size().height as usize;
|
|
274
|
+
|
|
275
|
+
println!(
|
|
276
|
+
"Texture size: width={}, height={}",
|
|
277
|
+
output.texture.size().width,
|
|
278
|
+
output.texture.size().height
|
|
279
|
+
);
|
|
280
|
+
|
|
281
|
+
let buffer_desc = wgpu::BufferDescriptor {
|
|
282
|
+
label: Some("Staging Buffer"),
|
|
283
|
+
size: buffer_size as wgpu::BufferAddress,
|
|
284
|
+
usage: wgpu::BufferUsages::MAP_READ | wgpu::BufferUsages::COPY_DST,
|
|
285
|
+
mapped_at_creation: false,
|
|
286
|
+
};
|
|
287
|
+
let staging_buffer = wgpu_state.device.create_buffer(&buffer_desc);
|
|
288
|
+
|
|
289
|
+
let mut encoder = wgpu_state
|
|
290
|
+
.device
|
|
291
|
+
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
|
292
|
+
encoder.copy_texture_to_buffer(
|
|
293
|
+
wgpu::ImageCopyTexture {
|
|
294
|
+
texture: &output.texture,
|
|
295
|
+
mip_level: 0,
|
|
296
|
+
origin: wgpu::Origin3d::ZERO,
|
|
297
|
+
aspect: wgpu::TextureAspect::All,
|
|
298
|
+
},
|
|
299
|
+
wgpu::ImageCopyBuffer {
|
|
300
|
+
buffer: &staging_buffer,
|
|
301
|
+
layout: wgpu::ImageDataLayout {
|
|
302
|
+
offset: 0,
|
|
303
|
+
bytes_per_row: Some(aligned_bytes_per_row as u32),
|
|
304
|
+
rows_per_image: Some(output.texture.size().height),
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
wgpu::Extent3d {
|
|
308
|
+
width: output.texture.size().width,
|
|
309
|
+
height: output.texture.size().height,
|
|
310
|
+
depth_or_array_layers: 1,
|
|
311
|
+
},
|
|
312
|
+
);
|
|
313
|
+
wgpu_state.queue.submit(Some(encoder.finish()));
|
|
314
|
+
|
|
315
|
+
/** Export frame */
|
|
316
|
+
// Map the buffer to read the data
|
|
317
|
+
// println!("buffer {:?}", staging_buffer);
|
|
318
|
+
|
|
319
|
+
// Map the staging buffer to read the data
|
|
320
|
+
let buffer_slice = staging_buffer.slice(..);
|
|
321
|
+
let (sender, receiver) = futures::channel::oneshot::channel();
|
|
322
|
+
buffer_slice.map_async(wgpu::MapMode::Read, move |result| {
|
|
323
|
+
sender.send(result).unwrap();
|
|
324
|
+
});
|
|
325
|
+
wgpu_state.device.poll(wgpu::Maintain::Wait);
|
|
326
|
+
|
|
327
|
+
receiver.await;
|
|
328
|
+
|
|
329
|
+
let unaligned_width = output.texture.size().width as usize;
|
|
330
|
+
let height = output.texture.size().height as usize;
|
|
331
|
+
|
|
332
|
+
let data = buffer_slice.get_mapped_range();
|
|
333
|
+
let image_data = data.to_vec(); // Copy buffer data to a Vec<u8>.
|
|
334
|
+
drop(data); // Release the buffer mapping.
|
|
335
|
+
|
|
336
|
+
// println!("image_data {:?}", image_data);
|
|
337
|
+
|
|
338
|
+
let mut reconstructed_data = Vec::with_capacity(unaligned_bytes_per_row * height);
|
|
339
|
+
|
|
340
|
+
for row in 0..height {
|
|
341
|
+
let start = row * aligned_bytes_per_row;
|
|
342
|
+
let end = start + unaligned_bytes_per_row; // Only take the valid portion
|
|
343
|
+
reconstructed_data.extend_from_slice(&image_data[start..end]);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
assert_eq!(reconstructed_data.len(), unaligned_bytes_per_row * height);
|
|
347
|
+
println!("Reconstructed data size: {}", reconstructed_data.len());
|
|
348
|
+
|
|
349
|
+
// println!(
|
|
350
|
+
// "image_data {:?}, expected {:?}",
|
|
351
|
+
// image_data.len(),
|
|
352
|
+
// aligned_bytes_per_row * height
|
|
353
|
+
// );
|
|
354
|
+
// println!(
|
|
355
|
+
// "reconstructed_data {:?}, expected {:?}",
|
|
356
|
+
// reconstructed_data.len(),
|
|
357
|
+
// aligned_bytes_per_row * height
|
|
358
|
+
// );
|
|
359
|
+
// println!("Expected 1920000");
|
|
360
|
+
|
|
361
|
+
// Send the data to the webview
|
|
362
|
+
let window = app_handle.get_webview_window("main").unwrap();
|
|
363
|
+
if let Err(e) = window.emit("frame-data", reconstructed_data) {
|
|
364
|
+
eprintln!("Failed to emit data: {:?}", e);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/** End */
|
|
368
|
+
// Now call present
|
|
369
|
+
output.present();
|
|
370
|
+
|
|
371
|
+
println!("Frame rendered in: {}ms", t.elapsed().as_millis());
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
Ok(())
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
async fn setup_app<'a>(app: &'a mut tauri::App) -> Result<(), Box<dyn Error>> {
|
|
379
|
+
// Setup HTTP + WebSocket server
|
|
380
|
+
let (tx, rx) = tokio::sync::mpsc::channel::<String>(32);
|
|
381
|
+
|
|
382
|
+
tokio::spawn(async move {
|
|
383
|
+
websocket_server(tx, rx).await;
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
Ok(())
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
|
390
|
+
pub fn run() {
|
|
391
|
+
let init = match Client::init_app(480) {
|
|
392
|
+
Ok(val) => {
|
|
393
|
+
let (client, single) = val;
|
|
394
|
+
let _cb = client.register_callback(|p: PersonaStateChange| {
|
|
395
|
+
println!("Got callback: {:?}", p);
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
let utils = client.utils();
|
|
399
|
+
println!("Utils:");
|
|
400
|
+
println!("AppId: {:?}", utils.app_id());
|
|
401
|
+
println!("UI Language: {}", utils.ui_language());
|
|
402
|
+
|
|
403
|
+
let apps = client.apps();
|
|
404
|
+
println!("Apps");
|
|
405
|
+
println!("IsInstalled(480): {}", apps.is_app_installed(AppId(480)));
|
|
406
|
+
println!("InstallDir(480): {}", apps.app_install_dir(AppId(480)));
|
|
407
|
+
println!("BuildId: {}", apps.app_build_id());
|
|
408
|
+
println!("AppOwner: {:?}", apps.app_owner());
|
|
409
|
+
println!("Langs: {:?}", apps.available_game_languages());
|
|
410
|
+
println!("Lang: {}", apps.current_game_language());
|
|
411
|
+
println!("Beta: {:?}", apps.current_beta_name());
|
|
412
|
+
|
|
413
|
+
let friends = client.friends();
|
|
414
|
+
println!("Friends");
|
|
415
|
+
let list = friends.get_friends(FriendFlags::IMMEDIATE);
|
|
416
|
+
println!("{:?}", list);
|
|
417
|
+
for f in &list {
|
|
418
|
+
println!("Friend: {:?} - {}({:?})", f.id(), f.name(), f.state());
|
|
419
|
+
friends.request_user_information(f.id(), true);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
Err(err) => {
|
|
423
|
+
println!("Error {}", err);
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
tauri::Builder::default()
|
|
428
|
+
.plugin(tauri_plugin_fs::init())
|
|
429
|
+
.setup(move |app| {
|
|
430
|
+
println!("setup");
|
|
431
|
+
let _ = setup_wgpu_overlay(app);
|
|
432
|
+
setup_app(app);
|
|
433
|
+
Ok(())
|
|
434
|
+
})
|
|
435
|
+
.invoke_handler(tauri::generate_handler![showOverlay])
|
|
436
|
+
.build(tauri::generate_context!())
|
|
437
|
+
.expect("error while running tauri application")
|
|
438
|
+
.run(|app_handle, event| match event {
|
|
439
|
+
RunEvent::WindowEvent {
|
|
440
|
+
label: _,
|
|
441
|
+
event: WindowEvent::Resized(size),
|
|
442
|
+
..
|
|
443
|
+
} => {
|
|
444
|
+
//
|
|
445
|
+
}
|
|
446
|
+
RunEvent::MainEventsCleared => {}
|
|
447
|
+
_ => (),
|
|
448
|
+
});
|
|
449
|
+
}
|