(wip): migrate ttp to mtp
Some checks failed
/ build-web (push) Failing after 3m4s
/ build-desktop (linux) (push) Failing after 3m15s
/ build-mobile (push) Failing after 9m7s
/ release (push) Has been skipped

This commit is contained in:
Alois 2026-07-02 21:05:50 +02:00
commit 20018f09a9
163 changed files with 8342 additions and 2609 deletions

View file

@ -12,9 +12,41 @@
"preview": "cd dist && nix-shell -p python3 --run 'python3 -m http.server 3000' && cd .."
},
"dependencies": {
"@base-ui/react": "^1.0.0",
"@base-ui/utils": "0.3.1",
"@babel/runtime": "^7.29.2",
"@fontsource-variable/inter": "^5.2.8",
"@fontsource-variable/public-sans": "^5.2.7",
"@floating-ui/core": "^1.7.0",
"@floating-ui/dom": "^1.7.0",
"@floating-ui/react-dom": "^2.1.8",
"@floating-ui/utils": "^0.2.11",
"@radix-ui/primitive": "^1.1.0",
"@radix-ui/react-compose-refs": "^1.1.1",
"@radix-ui/react-context": "^1.1.4",
"@radix-ui/react-dialog": "^1.1.6",
"@radix-ui/react-dismissable-layer": "^1.1.11",
"@radix-ui/react-focus-guards": "^1.1.4",
"@radix-ui/react-focus-scope": "^1.1.11",
"@radix-ui/react-id": "^1.1.0",
"@radix-ui/react-portal": "^1.1.13",
"@radix-ui/react-presence": "^1.1.6",
"@radix-ui/react-primitive": "^2.0.2",
"@radix-ui/react-slot": "^1.1.2",
"@radix-ui/react-use-callback-ref": "^1.1.1",
"@radix-ui/react-use-controllable-state": "^1.2.3",
"@radix-ui/react-use-effect-event": "^0.0.2",
"@radix-ui/react-use-layout-effect": "^1.1.0",
"@reduxjs/toolkit": "^2.0.0",
"@tailwindcss/vite": "^4.2.4",
"@tanstack/devtools-event-client": "^0.3.0",
"@tanstack/query-core": "^5.0.0",
"@tanstack/react-router": "^1.169.1",
"@tanstack/history": "1.162.0",
"@tanstack/react-store": "^0.9.3",
"@tanstack/router-core": "^1.169.1",
"@tanstack/store": "^0.9.3",
"@tanstack/virtual-core": "^3.13.24",
"@tanstack/react-virtual": "^3.13.24",
"@tauri-apps/api": "^2",
"@tensamin/call": "workspace:*",
@ -23,19 +55,75 @@
"@tensamin/shared": "workspace:*",
"@tensamin/storage": "workspace:*",
"@tensamin/tauri": "workspace:*",
"@tensamin/ttp": "workspace:*",
"@tensamin/mtp": "workspace:*",
"@tensamin/tauth": "workspace:*",
"@tensamin/markdown": "workspace:*",
"@tensamin/ui": "*",
"@tensamin/user": "workspace:*",
"@tensamin/notifications": "workspace:*",
"aria-hidden": "^1.2.4",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"cookie-es": "^3.0.0",
"d3-array": "^3.1.6",
"d3-color": "^3.1.0",
"d3-ease": "^3.0.1",
"d3-format": "^3.1.0",
"d3-interpolate": "^3.0.1",
"d3-path": "^3.0.1",
"d3-scale": "^4.0.2",
"d3-shape": "^3.1.0",
"d3-time": "^3.0.0",
"d3-time-format": "^4.1.0",
"d3-timer": "^3.0.1",
"date-fns": "^4.4.0",
"decimal.js-light": "^2.5.1",
"detect-node-es": "^1.1.0",
"dijkstrajs": "^1.0.1",
"embla-carousel": "8.6.0",
"embla-carousel-react": "^8.6.0",
"embla-carousel-reactive-utils": "8.6.0",
"es-toolkit": "^1.39.3",
"eventemitter3": "^5.0.1",
"get-nonce": "^1.0.1",
"immer": "^10.1.1",
"input-otp": "^1.4.2",
"internmap": "^2.0.3",
"tw-animate-css": "^1.4.0",
"lucide-react": "^1.14.0",
"next-themes": "^0.4.6",
"pngjs": "^5.0.0",
"qrcode": "^1.5.4",
"react": "^19.2.0",
"react-day-picker": "^10.0.1",
"react-dom": "^19.2.0",
"react-is": "^19.0.0",
"react-redux": "^9.0.0",
"react-remove-scroll": "^2.7.2",
"react-remove-scroll-bar": "^2.3.7",
"react-resizable-panels": "^4.11.2",
"react-style-singleton": "^2.2.3",
"recharts": "3.8.1",
"redux": "^5.0.0",
"redux-thunk": "^3.1.0",
"reselect": "5.1.1",
"scheduler": "^0.27.0",
"seroval": "^1.5.4",
"seroval-plugins": "^1.5.4",
"shadcn": "^4.11.0",
"sonner": "^2.0.7",
"tailwindcss": "^4.2.4",
"tailwind-merge": "^3.6.0",
"tailwind-scrollbar-hide": "^4.0.0",
"tiny-invariant": "^1.3.3",
"tslib": "^2.8.1",
"use-callback-ref": "^1.3.3",
"use-sidecar": "^1.1.3",
"use-sync-external-store": "^1.2.2",
"vaul": "^1.1.2",
"victory-vendor": "^37.0.2",
"yargs": "^15.3.1",
"zod": "^4.3.6"
},
"devDependencies": {

View file

@ -105,7 +105,7 @@ export default function Form() {
await save("user_id", parsed.userId);
await save("private_key", parsed.privateKey);
if (parsed.domain) {
await save("ttp_url", `https://${parsed.domain}/`);
await save("mtp_url", `https://${parsed.domain}/`);
}
location.href = "/";
@ -253,7 +253,7 @@ export default function Form() {
await save("user_id", user.user_id);
await save("private_key", inputParse.data.private_key);
if (domain) {
await save("ttp_url", `https://${domain}/`);
await save("mtp_url", `https://${domain}/`);
}
location.href = "/";
@ -287,7 +287,7 @@ export default function Form() {
await save("private_key", privateKey);
if (domain) {
await save("ttp_url", `https://${domain}/`);
await save("mtp_url", `https://${domain}/`);
}
location.href = "/";

View file

@ -37,11 +37,11 @@ import { Ellipsis, Check } from "lucide-react";
import { useState } from "react";
import type { User } from "@tensamin/user/context";
import type z from "zod";
import { ttp } from "@tensamin/shared/data";
import { useTTP } from "@tensamin/ttp";
import { mtp } from "@tensamin/shared/data";
import { useMTP } from "@tensamin/mtp";
type OnlineStatus = z.infer<
typeof ttp.get_user_data.response.shape.online_status
typeof mtp.get_user_data.response.shape.online_status
>;
const onlineStatusLabels: Record<OnlineStatus, string> = {
@ -73,7 +73,7 @@ function StatusDialog({
user: User;
open: boolean;
onOpenChange: (open: boolean) => void;
send: ReturnType<typeof useTTP>["send"];
send: ReturnType<typeof useMTP>["send"];
draftStatus: string;
setDraftStatus: (value: string) => void;
draftOnlineStatus: OnlineStatus;
@ -148,7 +148,7 @@ function StatusDialog({
};
const validation =
ttp.change_user_data.request.safeParse(payload);
mtp.change_user_data.request.safeParse(payload);
if (!validation.success) {
setSaveSucceeded(false);
@ -194,7 +194,7 @@ export default function Sidebar() {
const [statusErrorMessage, setStatusErrorMessage] = useState("");
const [statusSaveSucceeded, setStatusSaveSucceeded] = useState(false);
const { send } = useTTP();
const { send } = useMTP();
const content = (
<>

View file

@ -24,7 +24,7 @@ import Login from "@/routes/screens/login";
import CallPopout from "@tensamin/call/popout";
import ChatContext from "@tensamin/chat/context";
import { useInitializeCall } from "@tensamin/call/store";
import { Provider as TTPProvider } from "@tensamin/ttp";
import { Provider as MTPProvider } from "@tensamin/mtp";
import UserContext from "@tensamin/user/context";
import DeeplinkContext from "@tensamin/tauri/deeplinkHandler";
import NotificationsProvider from "@tensamin/notifications/context";
@ -177,59 +177,31 @@ function ThemeStorageBridge() {
]);
useEffect(() => {
if (!loadedRef.current) {
return;
}
save("theme_color", themeColor);
if (loadedRef.current) save("theme_color", themeColor);
}, [save, themeColor]);
useEffect(() => {
if (!loadedRef.current) {
return;
}
save("theme_palette", themePalette);
if (loadedRef.current) save("theme_palette", themePalette);
}, [save, themePalette]);
useEffect(() => {
if (!loadedRef.current) {
return;
}
save("theme_primary_color", themePrimaryColor);
if (loadedRef.current) save("theme_primary_color", themePrimaryColor);
}, [save, themePrimaryColor]);
useEffect(() => {
if (!loadedRef.current) {
return;
}
save("theme_polarity", themePolarity);
if (loadedRef.current) save("theme_polarity", themePolarity);
}, [save, themePolarity]);
useEffect(() => {
if (!loadedRef.current) {
return;
}
save("theme_tint", themeTint);
if (loadedRef.current) save("theme_tint", themeTint);
}, [save, themeTint]);
useEffect(() => {
if (!loadedRef.current) {
return;
}
save("theme_border_radius", themeBorderRadius);
if (loadedRef.current) save("theme_border_radius", themeBorderRadius);
}, [save, themeBorderRadius]);
useEffect(() => {
if (!loadedRef.current) {
return;
}
save("theme_custom_css", themeCustomCss);
if (loadedRef.current) save("theme_custom_css", themeCustomCss);
}, [save, themeCustomCss]);
return null;
@ -266,9 +238,19 @@ function RootShell() {
<LoginWrapper>
<LegalWrapper>
<Crypto>
<DesktopMediaProvider>
<Outlet />
</DesktopMediaProvider>
<MTPProvider>
<Session>
<UserContext>
<CallInit />
<CallPopout />
<TAuthWrapper>
<DesktopMediaProvider>
<Outlet />
</DesktopMediaProvider>
</TAuthWrapper>
</UserContext>
</Session>
</MTPProvider>
</Crypto>
</LegalWrapper>
</LoginWrapper>
@ -282,28 +264,19 @@ function RootShell() {
function AppShell() {
return (
<TTPProvider>
<Session>
<UserContext>
<CallInit />
<CallPopout />
<TAuthWrapper>
<AppLayout>
<ChatContext>
<NotificationsProvider>
<Outlet />
</NotificationsProvider>
</ChatContext>
</AppLayout>
</TAuthWrapper>
</UserContext>
</Session>
</TTPProvider>
<AppLayout>
<ChatContext>
<NotificationsProvider>
<Outlet />
</NotificationsProvider>
</ChatContext>
</AppLayout>
);
}
function CallInit() {
return useInitializeCall();
useInitializeCall();
return null;
}
const rootRoute = createRootRoute({

View file

@ -11,7 +11,7 @@ import {
useIsMobile,
} from "@tensamin/ui";
import z from "zod";
import { useTTP } from "@tensamin/ttp";
import { useMTP } from "@tensamin/mtp";
import { useState } from "react";
import { Loader2 } from "lucide-react";
import { isTauri } from "@tauri-apps/api/core";
@ -31,7 +31,7 @@ export default function Page() {
// Add Conversation Button Component
function AddConversationButton() {
const { send } = useTTP();
const { send } = useMTP();
const { contacts, insertContact } = useSession();
const [loading, setLoading] = useState(false);
const [open, setOpen] = useState(false);

View file

@ -11,8 +11,8 @@ import {
import { useUser, type User } from "@tensamin/user/context";
import { useEffect, useRef, useState } from "react";
import MDInput from "@tensamin/markdown/input";
import { ttp } from "@tensamin/shared/data";
import { useTTP } from "@tensamin/ttp";
import { mtp } from "@tensamin/shared/data";
import { useMTP } from "@tensamin/mtp";
import { Check } from "lucide-react";
async function prepImage(
@ -43,7 +43,7 @@ async function prepImage(
export default function Page() {
const { get } = useUser();
const { load } = useStorage();
const { send } = useTTP();
const { send } = useMTP();
const [currentUser, setCurrentUser] = useState<User | null>(null);
const [draftUser, setDraftUser] = useState<Partial<User>>({});
const [errorMessage, setErrorMessage] = useState("");
@ -178,7 +178,7 @@ export default function Page() {
: {}),
};
const validation = ttp.change_user_data.request.safeParse(payload);
const validation = mtp.change_user_data.request.safeParse(payload);
if (!validation.success) {
setSaveSucceeded(false);

View file

@ -59,7 +59,7 @@ function QrCodeLogin() {
setUserId(value);
}
});
load("ttp_url")
load("mtp_url")
.then((value) => {
if (value) {
const url = new URL(value);

View file

@ -6,6 +6,7 @@ import { fileURLToPath } from "node:url";
import { defineConfig, type Plugin } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
import { mtp } from "mtp/vite";
const host = process.env.TAURI_DEV_HOST;
const appDir = dirname(fileURLToPath(import.meta.url));
@ -74,6 +75,13 @@ export default defineConfig({
},
],
dedupe: [
"react",
"react-dom",
"react-redux",
"use-sync-external-store",
"@tensamin/crypto",
"@tensamin/storage",
"@tensamin/mtp",
"@codemirror/commands",
"@codemirror/lang-markdown",
"@codemirror/state",
@ -97,7 +105,16 @@ export default defineConfig({
},
envPrefix: ["VITE_", "TAURI_ENV_*"],
optimizeDeps: {
exclude: ["@tensamin/ttp-core"],
// Annoying Vite 8 stuff
include: [
"react-redux",
"use-sync-external-store/shim/with-selector",
"use-sync-external-store/with-selector",
"decimal.js-light",
"eventemitter3",
"react-is",
],
exclude: ["mtp", "mtp/raw", "mtp/type-map", "@tensamin/shared"],
},
build: {
minify: !process.env.TAURI_ENV_DEBUG ? "esbuild" : false,
@ -105,6 +122,7 @@ export default defineConfig({
},
plugins: [
deepFilterAssetHeaders(resolve(appDir, "public")),
mtp({ typeMaps: resolve(appDir, "../../type-maps.yaml") }),
react(),
tailwindcss(),
],