(qol): updated todos (fix): small px-2 that shouldn't be there (feat): turn focus reconnect into a continuous reconnect
This commit is contained in:
parent
1bc77fc146
commit
30722b6168
14 changed files with 93 additions and 9 deletions
13
apps/tauri/src-tauri/Cargo.lock
generated
13
apps/tauri/src-tauri/Cargo.lock
generated
|
|
@ -4573,6 +4573,18 @@ dependencies = [
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tauri-plugin-app-events"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4e625f35abcfc422c7c4af8b348d2069cdf387a39c12429fdce570137d02f069"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"tauri",
|
||||||
|
"tauri-plugin",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tauri-plugin-barcode-scanner"
|
name = "tauri-plugin-barcode-scanner"
|
||||||
version = "2.4.4"
|
version = "2.4.4"
|
||||||
|
|
@ -4834,6 +4846,7 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tauri",
|
"tauri",
|
||||||
"tauri-build 2.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"tauri-build 2.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tauri-plugin-app-events",
|
||||||
"tauri-plugin-barcode-scanner",
|
"tauri-plugin-barcode-scanner",
|
||||||
"tauri-plugin-deep-link",
|
"tauri-plugin-deep-link",
|
||||||
"tauri-plugin-opener",
|
"tauri-plugin-opener",
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ default-features = false
|
||||||
|
|
||||||
[target.'cfg(any(target_os = "android", target_os = "ios"))'.dependencies]
|
[target.'cfg(any(target_os = "android", target_os = "ios"))'.dependencies]
|
||||||
tauri-plugin-barcode-scanner = "2"
|
tauri-plugin-barcode-scanner = "2"
|
||||||
|
tauri-plugin-app-events = "0.2"
|
||||||
|
|
||||||
[patch.crates-io.tauri]
|
[patch.crates-io.tauri]
|
||||||
git = "https://github.com/tauri-apps/tauri"
|
git = "https://github.com/tauri-apps/tauri"
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
],
|
],
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"deep-link:default",
|
"deep-link:default",
|
||||||
|
"app-events:default",
|
||||||
"barcode-scanner:default",
|
"barcode-scanner:default",
|
||||||
"barcode-scanner:allow-scan",
|
"barcode-scanner:allow-scan",
|
||||||
"barcode-scanner:allow-cancel"
|
"barcode-scanner:allow-cancel"
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import com.android.build.gradle.LibraryExtension
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
|
|
@ -16,7 +18,16 @@ allprojects {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
subprojects {
|
||||||
|
afterEvaluate {
|
||||||
|
plugins.withId("com.android.library") {
|
||||||
|
extensions.configure<LibraryExtension>("android") {
|
||||||
|
compileSdk = 36
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tasks.register("clean").configure {
|
tasks.register("clean").configure {
|
||||||
delete("build")
|
delete("build")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,9 @@ pub fn run() {
|
||||||
#[cfg(any(target_os = "ios", target_os = "android"))]
|
#[cfg(any(target_os = "ios", target_os = "android"))]
|
||||||
let builder = builder.plugin(tauri_plugin_barcode_scanner::init());
|
let builder = builder.plugin(tauri_plugin_barcode_scanner::init());
|
||||||
|
|
||||||
|
#[cfg(any(target_os = "ios", target_os = "android"))]
|
||||||
|
let builder = builder.plugin(tauri_plugin_app_events::init());
|
||||||
|
|
||||||
if let Err(error) = builder
|
if let Err(error) = builder
|
||||||
.setup(|_app| {
|
.setup(|_app| {
|
||||||
#[cfg(any(target_os = "linux", windows))]
|
#[cfg(any(target_os = "linux", windows))]
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,7 @@
|
||||||
"tailwind-merge": "^3.5.0",
|
"tailwind-merge": "^3.5.0",
|
||||||
"tailwind-scrollbar-hide": "^4.0.0",
|
"tailwind-scrollbar-hide": "^4.0.0",
|
||||||
"tailwindcss": "^4.2.4",
|
"tailwindcss": "^4.2.4",
|
||||||
|
"tauri-plugin-app-events-api": "^0.2.0",
|
||||||
"tw-animate-css": "^1.4.0",
|
"tw-animate-css": "^1.4.0",
|
||||||
"zod": "^4.3.6"
|
"zod": "^4.3.6"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
5
bun.lock
5
bun.lock
|
|
@ -76,6 +76,7 @@
|
||||||
"tailwind-merge": "^3.5.0",
|
"tailwind-merge": "^3.5.0",
|
||||||
"tailwind-scrollbar-hide": "^4.0.0",
|
"tailwind-scrollbar-hide": "^4.0.0",
|
||||||
"tailwindcss": "^4.2.4",
|
"tailwindcss": "^4.2.4",
|
||||||
|
"tauri-plugin-app-events-api": "^0.2.0",
|
||||||
"tw-animate-css": "^1.4.0",
|
"tw-animate-css": "^1.4.0",
|
||||||
"zod": "^4.3.6",
|
"zod": "^4.3.6",
|
||||||
},
|
},
|
||||||
|
|
@ -228,6 +229,7 @@
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@tanstack/react-router": "^1.0.0",
|
"@tanstack/react-router": "^1.0.0",
|
||||||
|
"@tauri-apps/api": "^2",
|
||||||
"@tensamin/crypto": "workspace:*",
|
"@tensamin/crypto": "workspace:*",
|
||||||
"@tensamin/shared": "workspace:*",
|
"@tensamin/shared": "workspace:*",
|
||||||
"@tensamin/storage": "workspace:*",
|
"@tensamin/storage": "workspace:*",
|
||||||
|
|
@ -235,6 +237,7 @@
|
||||||
"@tensamin/ui": "*",
|
"@tensamin/ui": "*",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.0",
|
"react-dom": "^19.2.0",
|
||||||
|
"tauri-plugin-app-events-api": "^0.2.0",
|
||||||
"zod": "^4.3.6",
|
"zod": "^4.3.6",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
@ -1497,6 +1500,8 @@
|
||||||
|
|
||||||
"tapable": ["tapable@2.3.3", "", {}, "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A=="],
|
"tapable": ["tapable@2.3.3", "", {}, "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A=="],
|
||||||
|
|
||||||
|
"tauri-plugin-app-events-api": ["tauri-plugin-app-events-api@0.2.0", "", { "dependencies": { "@tauri-apps/api": "^2.0.3" } }, "sha512-CnlAeucWhT+Rgx6CCsqUpq2D3pqgx0fhjSPKomH7O2t1rGVu5kGLMkYvaCX6gqVTUYpIWX5BLV7LGY2DRri0QA=="],
|
||||||
|
|
||||||
"tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],
|
"tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],
|
||||||
|
|
||||||
"tinyexec": ["tinyexec@1.1.2", "", {}, "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA=="],
|
"tinyexec": ["tinyexec@1.1.2", "", {}, "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA=="],
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,8 @@
|
||||||
"dev:mobile": "cd apps/tauri && bun dev:mobile",
|
"dev:mobile": "cd apps/tauri && bun dev:mobile",
|
||||||
"build:mobile": "cd apps/tauri && bun run build:mobile",
|
"build:mobile": "cd apps/tauri && bun run build:mobile",
|
||||||
"dev:desktop": "cd apps/tauri && bun dev:desktop",
|
"dev:desktop": "cd apps/tauri && bun dev:desktop",
|
||||||
"build:desktop": "cd apps/tauri && bun run build:desktop"
|
"build:desktop": "cd apps/tauri && bun run build:desktop",
|
||||||
|
"delete:mobile": "cd apps/tauri && nix develop --command adb uninstall net.tensamin.client"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eslint/js": "^10.0.1",
|
"@eslint/js": "^10.0.1",
|
||||||
|
|
|
||||||
|
|
@ -431,7 +431,7 @@ export default function Screen() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative flex h-full min-h-0 w-full flex-col overflow-hidden px-2">
|
<div className="relative flex h-full min-h-0 w-full flex-col overflow-hidden">
|
||||||
<div
|
<div
|
||||||
ref={scrollRef}
|
ref={scrollRef}
|
||||||
id="chat_container"
|
id="chat_container"
|
||||||
|
|
|
||||||
1
packages/markdown/todo.md
Normal file
1
packages/markdown/todo.md
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
- Improve the Input box
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
- Add `notifications: number` to contacts
|
- Add `notifications: number` to contacts
|
||||||
|
- Store private key in a device bound session
|
||||||
|
|
|
||||||
1
packages/tauth/todo.md
Normal file
1
packages/tauth/todo.md
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
- Finish TAuth SDK
|
||||||
|
|
@ -18,8 +18,10 @@
|
||||||
"@tensamin/storage": "workspace:*",
|
"@tensamin/storage": "workspace:*",
|
||||||
"@tensamin/shared": "workspace:*",
|
"@tensamin/shared": "workspace:*",
|
||||||
"@tensamin/ui": "*",
|
"@tensamin/ui": "*",
|
||||||
|
"@tauri-apps/api": "^2",
|
||||||
"react": "^19.2.0",
|
"react": "^19.2.0",
|
||||||
"react-dom": "^19.2.0",
|
"react-dom": "^19.2.0",
|
||||||
|
"tauri-plugin-app-events-api": "^0.2.0",
|
||||||
"zod": "^4.3.6"
|
"zod": "^4.3.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ import {
|
||||||
READY_STATE,
|
READY_STATE,
|
||||||
type BoundSendFn,
|
type BoundSendFn,
|
||||||
} from "@tensamin/ttp-core";
|
} from "@tensamin/ttp-core";
|
||||||
|
import { isTauri } from "@tauri-apps/api/core";
|
||||||
|
import { onResume } from "tauri-plugin-app-events-api";
|
||||||
import type { PushHandler } from "@tensamin/ttp-core";
|
import type { PushHandler } from "@tensamin/ttp-core";
|
||||||
import {
|
import {
|
||||||
PING_INTERVAL,
|
PING_INTERVAL,
|
||||||
|
|
@ -141,6 +143,10 @@ function getProtocolErrorDetails(error: unknown) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isTauriMobile() {
|
||||||
|
return isTauri() && /Android|iPhone|iPad|iPod/.test(navigator.userAgent);
|
||||||
|
}
|
||||||
|
|
||||||
type ContextType = {
|
type ContextType = {
|
||||||
send: BoundSendFn<Schemas>;
|
send: BoundSendFn<Schemas>;
|
||||||
subscribePush: (handler: PushHandler) => () => void;
|
subscribePush: (handler: PushHandler) => () => void;
|
||||||
|
|
@ -186,7 +192,6 @@ export function Provider(props: {
|
||||||
typeof createTransportClient<Schemas>
|
typeof createTransportClient<Schemas>
|
||||||
> | null>(null);
|
> | null>(null);
|
||||||
const identificationStartedRef = useRef(false);
|
const identificationStartedRef = useRef(false);
|
||||||
const reconnectExhaustedRef = useRef(false);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends typed protocol messages through the active transport client.
|
* Sends typed protocol messages through the active transport client.
|
||||||
|
|
@ -266,6 +271,8 @@ export function Provider(props: {
|
||||||
let reconnectResetTimer: ReturnType<typeof setTimeout> | null = null;
|
let reconnectResetTimer: ReturnType<typeof setTimeout> | null = null;
|
||||||
let reconnectScheduled = false;
|
let reconnectScheduled = false;
|
||||||
let disposed = false;
|
let disposed = false;
|
||||||
|
let resumeListenerRegistered = false;
|
||||||
|
let currentReadyState: number = READY_STATE.CLOSED;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears any scheduled reconnect timeout and resets scheduling flags.
|
* Clears any scheduled reconnect timeout and resets scheduling flags.
|
||||||
|
|
@ -316,14 +323,12 @@ export function Provider(props: {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reconnectExhaustedRef.current || attempts >= RECONNECT_TRIES) {
|
if (attempts >= RECONNECT_TRIES) {
|
||||||
reconnectExhaustedRef.current = true;
|
|
||||||
setError("Connection Failed");
|
setError("Connection Failed");
|
||||||
setErrorDescription(
|
setErrorDescription(
|
||||||
"Unable to connect to the server after multiple attempts. Please check your internet connection or try again later.",
|
"Unable to connect to the server after multiple attempts. Please check your internet connection or try again later.",
|
||||||
);
|
);
|
||||||
log(0, "ttp", "red", "Reconnection attempts exhausted", reason);
|
log(0, "ttp", "red", "Reconnection attempts exhausted", reason);
|
||||||
void transportClient?.close("reconnect-exhausted");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -340,12 +345,12 @@ export function Provider(props: {
|
||||||
? createTransportClient(schemas, {
|
? createTransportClient(schemas, {
|
||||||
url: TRANSPORT_URL,
|
url: TRANSPORT_URL,
|
||||||
onReadyStateChange: (state) => {
|
onReadyStateChange: (state) => {
|
||||||
|
currentReadyState = state;
|
||||||
setReadyState(state);
|
setReadyState(state);
|
||||||
|
|
||||||
if (state === READY_STATE.OPEN) {
|
if (state === READY_STATE.OPEN) {
|
||||||
clearReconnectTimer();
|
clearReconnectTimer();
|
||||||
scheduleReconnectReset();
|
scheduleReconnectReset();
|
||||||
reconnectExhaustedRef.current = false;
|
|
||||||
identificationStartedRef.current = false;
|
identificationStartedRef.current = false;
|
||||||
setConnected(true);
|
setConnected(true);
|
||||||
setIdentified(false);
|
setIdentified(false);
|
||||||
|
|
@ -383,7 +388,7 @@ export function Provider(props: {
|
||||||
* @returns Promise that resolves after one connection attempt.
|
* @returns Promise that resolves after one connection attempt.
|
||||||
*/
|
*/
|
||||||
async function connect() {
|
async function connect() {
|
||||||
if (disposed || reconnectExhaustedRef.current) {
|
if (disposed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -399,18 +404,56 @@ export function Provider(props: {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a reconnect after resume only when the transport is disconnected.
|
||||||
|
* @returns Promise that resolves after any needed resume reconnect starts.
|
||||||
|
*/
|
||||||
|
async function reconnectAfterResume() {
|
||||||
|
if (disposed || !transportClient) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
currentReadyState === READY_STATE.OPEN ||
|
||||||
|
currentReadyState === READY_STATE.CONNECTING
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clearReconnectTimer();
|
||||||
|
clearReconnectResetTimer();
|
||||||
|
attempts = 0;
|
||||||
|
reconnectScheduled = false;
|
||||||
|
setError("");
|
||||||
|
setErrorDescription("");
|
||||||
|
|
||||||
|
await connect();
|
||||||
|
}
|
||||||
|
|
||||||
void connect();
|
void connect();
|
||||||
|
|
||||||
|
if (!props.blockConnection && isTauriMobile()) {
|
||||||
|
resumeListenerRegistered = true;
|
||||||
|
onResume(() => {
|
||||||
|
void reconnectAfterResume();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
disposed = true;
|
disposed = true;
|
||||||
clearReconnectTimer();
|
clearReconnectTimer();
|
||||||
clearReconnectResetTimer();
|
clearReconnectResetTimer();
|
||||||
|
|
||||||
|
if (resumeListenerRegistered) {
|
||||||
|
onResume();
|
||||||
|
}
|
||||||
|
|
||||||
if (clientRef.current === transportClient) {
|
if (clientRef.current === transportClient) {
|
||||||
clientRef.current = null;
|
clientRef.current = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void transportClient?.close("context-dispose");
|
void transportClient?.close("context-dispose");
|
||||||
|
currentReadyState = READY_STATE.CLOSED;
|
||||||
setReadyState(READY_STATE.CLOSED);
|
setReadyState(READY_STATE.CLOSED);
|
||||||
setConnected(false);
|
setConnected(false);
|
||||||
setIdentified(false);
|
setIdentified(false);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue