fix: child webview is not reposition after scroll

This commit is contained in:
reya
2024-07-19 13:10:29 +07:00
parent f3db010c74
commit 07ce253f5b
17 changed files with 2163 additions and 2161 deletions

View File

@@ -3,7 +3,7 @@ import type { LumeColumn } from "@lume/types";
import { invoke } from "@tauri-apps/api/core"; import { invoke } from "@tauri-apps/api/core";
import { listen } from "@tauri-apps/api/event"; import { listen } from "@tauri-apps/api/event";
import { Menu, MenuItem, PredefinedMenuItem } from "@tauri-apps/api/menu"; import { Menu, MenuItem, PredefinedMenuItem } from "@tauri-apps/api/menu";
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow"; import { getCurrentWindow } from "@tauri-apps/api/window";
import { memo, useCallback, useEffect, useRef, useState } from "react"; import { memo, useCallback, useEffect, useRef, useState } from "react";
type WindowEvent = { type WindowEvent = {
@@ -106,7 +106,7 @@ function Header({
const [isChanged, setIsChanged] = useState(false); const [isChanged, setIsChanged] = useState(false);
const saveNewTitle = async () => { const saveNewTitle = async () => {
const mainWindow = getCurrentWebviewWindow(); const mainWindow = getCurrentWindow();
await mainWindow.emit("columns", { type: "set_title", label, title }); await mainWindow.emit("columns", { type: "set_title", label, title });
// update search params // update search params
@@ -135,7 +135,7 @@ function Header({
MenuItem.new({ MenuItem.new({
text: "Move left", text: "Move left",
action: async () => { action: async () => {
await getCurrentWebviewWindow().emit("columns", { await getCurrentWindow().emit("columns", {
type: "move", type: "move",
label, label,
direction: "left", direction: "left",
@@ -145,7 +145,7 @@ function Header({
MenuItem.new({ MenuItem.new({
text: "Move right", text: "Move right",
action: async () => { action: async () => {
await getCurrentWebviewWindow().emit("columns", { await getCurrentWindow().emit("columns", {
type: "move", type: "move",
label, label,
direction: "right", direction: "right",
@@ -156,7 +156,7 @@ function Header({
MenuItem.new({ MenuItem.new({
text: "Close", text: "Close",
action: async () => { action: async () => {
await getCurrentWebviewWindow().emit("columns", { await getCurrentWindow().emit("columns", {
type: "remove", type: "remove",
label, label,
}); });

View File

@@ -30,11 +30,11 @@ function Screen() {
}); });
const scrollPrev = useCallback(() => { const scrollPrev = useCallback(() => {
if (emblaApi) emblaApi.scrollPrev(true); if (emblaApi) emblaApi.scrollPrev();
}, [emblaApi]); }, [emblaApi]);
const scrollNext = useCallback(() => { const scrollNext = useCallback(() => {
if (emblaApi) emblaApi.scrollNext(true); if (emblaApi) emblaApi.scrollNext();
}, [emblaApi]); }, [emblaApi]);
const emitScrollEvent = useCallback(() => { const emitScrollEvent = useCallback(() => {
@@ -101,10 +101,10 @@ function Screen() {
switch (event.code) { switch (event.code) {
case "ArrowLeft": case "ArrowLeft":
if (emblaApi) emblaApi.scrollPrev(true); if (emblaApi) emblaApi.scrollPrev();
break; break;
case "ArrowRight": case "ArrowRight":
if (emblaApi) emblaApi.scrollNext(true); if (emblaApi) emblaApi.scrollNext();
break; break;
default: default:
break; break;

View File

@@ -11,7 +11,6 @@ interface RouterContext {
export const Route = createRootRouteWithContext<RouterContext>()({ export const Route = createRootRouteWithContext<RouterContext>()({
component: () => <Outlet />, component: () => <Outlet />,
pendingComponent: Pending, pendingComponent: Pending,
wrapInSuspense: true,
}); });
function Pending() { function Pending() {

View File

@@ -21,6 +21,9 @@ import { type ReactNode, useCallback, useEffect, useRef } from "react";
import { Virtualizer } from "virtua"; import { Virtualizer } from "virtua";
export const Route = createFileRoute("/panel/$account")({ export const Route = createFileRoute("/panel/$account")({
beforeLoad: async ({ context }) => {
console.log(context);
},
component: Screen, component: Screen,
}); });
@@ -30,6 +33,7 @@ function Screen() {
const { isLoading, data } = useQuery({ const { isLoading, data } = useQuery({
queryKey: ["notification", account], queryKey: ["notification", account],
queryFn: async () => { queryFn: async () => {
console.log(queryClient);
const events = await NostrQuery.getNotifications(); const events = await NostrQuery.getNotifications();
return events; return events;
}, },

View File

@@ -1 +0,0 @@
tab_spaces=2

View File

@@ -248,7 +248,8 @@ pub fn open_main_window(app: tauri::AppHandle) {
let _ = window.set_focus(); let _ = window.set_focus();
}; };
} else { } else {
let window = WebviewWindowBuilder::from_config(&app, app.config().app.windows.first().unwrap()) let window =
WebviewWindowBuilder::from_config(&app, app.config().app.windows.first().unwrap())
.unwrap() .unwrap()
.build() .build()
.unwrap(); .unwrap();

View File

@@ -160,6 +160,19 @@ fn main() {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
main_window.set_traffic_lights_inset(8.0, 16.0).unwrap(); main_window.set_traffic_lights_inset(8.0, 16.0).unwrap();
#[cfg(target_os = "macos")]
let win = main_window.clone();
#[cfg(target_os = "macos")]
main_window.on_window_event(move |event| {
if let tauri::WindowEvent::ThemeChanged(_) = event {
win.set_traffic_lights_inset(8.0, 16.0).unwrap();
}
if let tauri::WindowEvent::Resized(_) = event {
win.set_traffic_lights_inset(8.0, 16.0).unwrap();
}
});
// Create data folder if not exist // Create data folder if not exist
let home_dir = app.path().home_dir().unwrap(); let home_dir = app.path().home_dir().unwrap();
let _ = fs::create_dir_all(home_dir.join("Lume/")); let _ = fs::create_dir_all(home_dir.join("Lume/"));
@@ -193,7 +206,10 @@ fn main() {
if let Some((relay, option)) = line.split_once(',') { if let Some((relay, option)) = line.split_once(',') {
match RelayMetadata::from_str(option) { match RelayMetadata::from_str(option) {
Ok(meta) => { Ok(meta) => {
println!("connecting to bootstrap relay...: {} - {}", relay, meta); println!(
"connecting to bootstrap relay...: {} - {}",
relay, meta
);
let opts = if meta == RelayMetadata::Read { let opts = if meta == RelayMetadata::Read {
RelayOptions::new().read(true).write(false) RelayOptions::new().read(true).write(false)
} else { } else {
@@ -224,20 +240,6 @@ fn main() {
Ok(()) Ok(())
}) })
.enable_macos_default_menu(false) .enable_macos_default_menu(false)
.on_window_event(move |window, event| {
#[cfg(target_os = "macos")]
if let tauri::WindowEvent::ThemeChanged(_) = event {
if let Some(webview) = window.get_webview_window(window.label()) {
webview.set_traffic_lights_inset(8.0, 16.0).unwrap();
}
}
#[cfg(target_os = "macos")]
if let tauri::WindowEvent::Resized(_) = event {
if let Some(webview) = window.get_webview_window(window.label()) {
webview.set_traffic_lights_inset(8.0, 16.0).unwrap();
}
}
})
.plugin(tauri_nspanel::init()) .plugin(tauri_nspanel::init())
.plugin(tauri_plugin_theme::init(ctx.config_mut())) .plugin(tauri_plugin_theme::init(ctx.config_mut()))
.plugin(tauri_plugin_decorum::init()) .plugin(tauri_plugin_decorum::init())
@@ -251,20 +253,7 @@ fn main() {
.plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_upload::init()) .plugin(tauri_plugin_upload::init())
.plugin(tauri_plugin_updater::Builder::new().build()) .plugin(tauri_plugin_updater::Builder::new().build())
.plugin(
tauri_plugin_window_state::Builder::new()
.with_denylist(&["panel"])
.build(),
)
.invoke_handler(invoke_handler) .invoke_handler(invoke_handler)
.build(ctx) .run(ctx)
.expect("error while running tauri application") .expect("error while running tauri application");
.run(|_, event| {
if let tauri::RunEvent::ExitRequested { api, .. } = event {
// Hide app icon on macOS
// let _ = app.set_activation_policy(tauri::ActivationPolicy::Accessory);
// Keep API running
api.prevent_exit();
}
});
} }

View File

@@ -192,7 +192,7 @@ pub async fn listen_event_reply(id: &str, state: State<'_, Nostr>) -> Result<(),
.since(Timestamp::now()); .since(Timestamp::now());
// Subscribe // Subscribe
client.subscribe_with_id(sub_id, vec![filter], None).await; let _ = client.subscribe_with_id(sub_id, vec![filter], None).await;
Ok(()) Ok(())
} }
@@ -308,7 +308,7 @@ pub async fn listen_local_event(label: &str, state: State<'_, Nostr>) -> Result<
.since(Timestamp::now()); .since(Timestamp::now());
// Subscribe // Subscribe
client.subscribe_with_id(sub_id, vec![filter], None).await; let _ = client.subscribe_with_id(sub_id, vec![filter], None).await;
Ok(()) Ok(())
} }
@@ -656,7 +656,8 @@ pub async fn user_to_bech32(user: &str, state: State<'_, Nostr>) -> Result<Strin
.into_iter() .into_iter()
.map(|i| i.0.to_string()) .map(|i| i.0.to_string())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let profile = Nip19Profile::new(public_key, relays).map_err(|err| err.to_string())?; let profile =
Nip19Profile::new(public_key, relays).map_err(|err| err.to_string())?;
Ok(profile.to_bech32().map_err(|err| err.to_string())?) Ok(profile.to_bech32().map_err(|err| err.to_string())?)
} }

View File

@@ -1,3 +1,7 @@
use crate::nostr::event::RichEvent;
use crate::nostr::internal::{get_user_settings, init_nip65};
use crate::nostr::utils::parse_event;
use crate::{Nostr, NEWSFEED_NEG_LIMIT, NOTIFICATION_NEG_LIMIT};
use keyring::Entry; use keyring::Entry;
use keyring_search::{Limit, List, Search}; use keyring_search::{Limit, List, Search};
use nostr_sdk::prelude::*; use nostr_sdk::prelude::*;
@@ -8,12 +12,6 @@ use std::time::Duration;
use tauri::{Emitter, EventTarget, Manager, State}; use tauri::{Emitter, EventTarget, Manager, State};
use tauri_plugin_notification::NotificationExt; use tauri_plugin_notification::NotificationExt;
use crate::commands::tray::create_tray_panel;
use crate::nostr::event::RichEvent;
use crate::nostr::internal::{get_user_settings, init_nip65};
use crate::nostr::utils::parse_event;
use crate::{Nostr, NEWSFEED_NEG_LIMIT, NOTIFICATION_NEG_LIMIT};
#[derive(Serialize, Type)] #[derive(Serialize, Type)]
pub struct Account { pub struct Account {
npub: String, npub: String,
@@ -174,11 +172,14 @@ pub async fn load_account(
match bunker { match bunker {
Some(uri) => { Some(uri) => {
let app_keys = Keys::parse(password).expect("Secret Key is modified, please check again."); let app_keys =
Keys::parse(password).expect("Secret Key is modified, please check again.");
match NostrConnectURI::parse(uri) { match NostrConnectURI::parse(uri) {
Ok(bunker_uri) => { Ok(bunker_uri) => {
match Nip46Signer::new(bunker_uri, app_keys, Duration::from_secs(30), None).await { match Nip46Signer::new(bunker_uri, app_keys, Duration::from_secs(30), None)
.await
{
Ok(signer) => client.set_signer(Some(signer.into())).await, Ok(signer) => client.set_signer(Some(signer.into())).await,
Err(err) => return Err(err.to_string()), Err(err) => return Err(err.to_string()),
} }
@@ -198,10 +199,6 @@ pub async fn load_account(
// Connect to user's relay (NIP-65) // Connect to user's relay (NIP-65)
init_nip65(client).await; init_nip65(client).await;
// Create tray (macOS)
#[cfg(target_os = "macos")]
create_tray_panel(npub, &handle);
// Get user's contact list // Get user's contact list
if let Ok(contacts) = client.get_contact_list(None).await { if let Ok(contacts) = client.get_contact_list(None).await {
*state.contact_list.lock().unwrap() = contacts *state.contact_list.lock().unwrap() = contacts
@@ -279,7 +276,7 @@ pub async fn load_account(
.since(Timestamp::now()); .since(Timestamp::now());
// Subscribing for new notification... // Subscribing for new notification...
client let _ = client
.subscribe_with_id(subscription_id, vec![subscription], None) .subscribe_with_id(subscription_id, vec![subscription], None)
.await; .await;
@@ -315,7 +312,11 @@ pub async fn load_account(
.notification() .notification()
.builder() .builder()
.body("Mentioned you in a thread.") .body("Mentioned you in a thread.")
.title(author.display_name.unwrap_or_else(|| "Lume".to_string())) .title(
author
.display_name
.unwrap_or_else(|| "Lume".to_string()),
)
.show() .show()
{ {
println!("Failed to show notification: {:?}", e); println!("Failed to show notification: {:?}", e);
@@ -326,7 +327,11 @@ pub async fn load_account(
.notification() .notification()
.builder() .builder()
.body("Reposted your note.") .body("Reposted your note.")
.title(author.display_name.unwrap_or_else(|| "Lume".to_string())) .title(
author
.display_name
.unwrap_or_else(|| "Lume".to_string()),
)
.show() .show()
{ {
println!("Failed to show notification: {:?}", e); println!("Failed to show notification: {:?}", e);
@@ -338,7 +343,11 @@ pub async fn load_account(
.notification() .notification()
.builder() .builder()
.body(content) .body(content)
.title(author.display_name.unwrap_or_else(|| "Lume".to_string())) .title(
author
.display_name
.unwrap_or_else(|| "Lume".to_string()),
)
.show() .show()
{ {
println!("Failed to show notification: {:?}", e); println!("Failed to show notification: {:?}", e);
@@ -349,7 +358,11 @@ pub async fn load_account(
.notification() .notification()
.builder() .builder()
.body("Zapped you.") .body("Zapped you.")
.title(author.display_name.unwrap_or_else(|| "Lume".to_string())) .title(
author
.display_name
.unwrap_or_else(|| "Lume".to_string()),
)
.show() .show()
{ {
println!("Failed to show notification: {:?}", e); println!("Failed to show notification: {:?}", e);

View File

@@ -449,7 +449,9 @@ pub async fn friend_to_friend(npub: &str, state: State<'_, Nostr>) -> Result<boo
.kind(Kind::ContactList) .kind(Kind::ContactList)
.limit(1); .limit(1);
if let Ok(contact_list_events) = client.get_events_of(vec![contact_list_filter], None).await { if let Ok(contact_list_events) =
client.get_events_of(vec![contact_list_filter], None).await
{
for event in contact_list_events.into_iter() { for event in contact_list_events.into_iter() {
for tag in event.into_iter_tags() { for tag in event.into_iter_tags() {
if let Some(TagStandard::PublicKey { if let Some(TagStandard::PublicKey {
@@ -575,7 +577,8 @@ pub async fn get_settings(state: State<'_, Nostr>) -> Result<Settings, ()> {
#[tauri::command] #[tauri::command]
#[specta::specta] #[specta::specta]
pub async fn set_new_settings(settings: &str, state: State<'_, Nostr>) -> Result<(), ()> { pub async fn set_new_settings(settings: &str, state: State<'_, Nostr>) -> Result<(), ()> {
let parsed: Settings = serde_json::from_str(settings).expect("Could not parse settings payload"); let parsed: Settings =
serde_json::from_str(settings).expect("Could not parse settings payload");
*state.settings.lock().unwrap() = parsed; *state.settings.lock().unwrap() = parsed;
Ok(()) Ok(())

View File

@@ -5,7 +5,6 @@
{ {
"title": "Lume", "title": "Lume",
"label": "main", "label": "main",
"titleBarStyle": "Overlay",
"width": 1045, "width": 1045,
"height": 800, "height": 800,
"minWidth": 480, "minWidth": 480,

View File

@@ -1,12 +1,6 @@
{ {
"$schema": "../node_modules/@tauri-apps/cli/schema.json", "$schema": "../node_modules/@tauri-apps/cli/schema.json",
"app": { "app": {
"trayIcon": {
"id": "main",
"iconPath": "./icons/tray.png",
"iconAsTemplate": true,
"menuOnLeftClick": false
},
"windows": [ "windows": [
{ {
"title": "Lume", "title": "Lume",