fix: child webview is not reposition after scroll
This commit is contained in:
@@ -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,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
tab_spaces=2
|
|
||||||
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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())?)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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(())
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
Reference in New Issue
Block a user