Compare commits

..
Author SHA1 Message Date
1838bbec83 chore(deps): update dependency gradle to v9
Some checks failed
renovate/stability-days Updates have met minimum release age requirement
Dependency builds / Build web (pull_request) Failing after 7m25s
Dependency builds / Build desktop (pull_request) Failing after 5m45s
Dependency builds / Build mobile (pull_request) Failing after 8m44s
2026-08-12 03:00:36 +02:00
6e977bca7e
feat(mobile): use drawer for gif picker
Some checks failed
/ build-desktop (linux) (push) Failing after 6m36s
/ build-web (push) Failing after 7m7s
/ build-mobile (push) Failing after 9m21s
/ release (push) Has been skipped
fix(mobile): some ui bugs
fix(mobile): disable pinch zooming
2026-08-12 02:16:56 +02:00
9 changed files with 436 additions and 259 deletions

View file

@ -5298,7 +5298,7 @@ dependencies = [
[[package]] [[package]]
name = "tensamin" name = "tensamin"
version = "0.0.11" version = "0.0.0"
dependencies = [ dependencies = [
"base64 0.22.1", "base64 0.22.1",
"jni 0.22.4", "jni 0.22.4",

View file

@ -5,6 +5,7 @@ import android.app.Activity
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.media.projection.MediaProjectionManager import android.media.projection.MediaProjectionManager
import android.os.Bundle import android.os.Bundle
import android.view.MotionEvent
import android.view.ViewTreeObserver import android.view.ViewTreeObserver
import android.view.WindowManager import android.view.WindowManager
import android.webkit.JavascriptInterface import android.webkit.JavascriptInterface
@ -54,6 +55,32 @@ class MainActivity : TauriActivity() {
} }
override fun onWebViewCreate(webView: WebView) { override fun onWebViewCreate(webView: WebView) {
webView.settings.apply {
setSupportZoom(false)
builtInZoomControls = false
displayZoomControls = false
}
var blockingMultiTouch = false
webView.setOnTouchListener { _, event ->
val shouldBlock = blockingMultiTouch || event.pointerCount > 1
when (event.actionMasked) {
MotionEvent.ACTION_POINTER_DOWN -> {
// Cancel the one-finger gesture before consuming the rest of the pinch.
MotionEvent.obtain(event).let { cancelEvent ->
cancelEvent.action = MotionEvent.ACTION_CANCEL
webView.onTouchEvent(cancelEvent)
cancelEvent.recycle()
}
blockingMultiTouch = true
}
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> blockingMultiTouch = false
}
shouldBlock
}
NativeAccessibilityBridge.attach(webView) NativeAccessibilityBridge.attach(webView)
mediaWebView = webView mediaWebView = webView
MobileMediaEvents.attach(webView) MobileMediaEvents.attach(webView)

View file

@ -3,7 +3,10 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" href="./favicon.ico" /> <link rel="icon" href="./favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta
name="viewport"
content="width=device-width, initial-scale=1.0, viewport-fit=cover"
/>
<title>Tensamin</title> <title>Tensamin</title>
</head> </head>
<body> <body>

View file

@ -27,7 +27,6 @@ import {
SelectContent, SelectContent,
SelectItem, SelectItem,
} from "@methanium/ui"; } from "@methanium/ui";
import { isTauri } from "@tauri-apps/api/core";
import { useIsMobile } from "@methanium/ui"; import { useIsMobile } from "@methanium/ui";
import { MobileNavbar } from "./navbar"; import { MobileNavbar } from "./navbar";
@ -194,11 +193,7 @@ export default function Sidebar() {
const content = ( const content = (
<> <>
<SidebarContent <SidebarContent className="pt-2">
className={
isTauri() && isMobile ? "pt-[env(safe-area-inset-top)]" : "pt-2"
}
>
<div className="h-full w-full flex flex-col gap-3 p-2 pt-0!"> <div className="h-full w-full flex flex-col gap-3 p-2 pt-0!">
<div> <div>
<Wrapper <Wrapper
@ -309,7 +304,7 @@ export default function Sidebar() {
data-sidebar="sidebar" data-sidebar="sidebar"
data-slot="sidebar" data-slot="sidebar"
data-mobile="true" data-mobile="true"
className="fixed inset-y-0 left-0 z-50 w-screen bg-sidebar p-0 text-sidebar-foreground" className="fixed inset-y-0 left-0 z-50 w-screen bg-sidebar pt-[var(--ui-safe-area-top)] pr-[var(--ui-safe-area-right)] pl-[var(--ui-safe-area-left)] text-sidebar-foreground"
style={{ style={{
transform: openMobile ? "translateX(0)" : "translateX(-100%)", transform: openMobile ? "translateX(0)" : "translateX(-100%)",
opacity: openMobile ? 1 : 0, opacity: openMobile ? 1 : 0,

View file

@ -48,7 +48,6 @@ import CacheSync from "@tensamin/cache/sync";
import { useStorage } from "@tensamin/storage/context"; import { useStorage } from "@tensamin/storage/context";
import { useLocation, useNavigate } from "@tanstack/react-router"; import { useLocation, useNavigate } from "@tanstack/react-router";
import { useIsMobile, Toaster, TooltipProvider } from "@methanium/ui"; import { useIsMobile, Toaster, TooltipProvider } from "@methanium/ui";
import { isTauri } from "@tauri-apps/api/core";
import { HotkeysProvider } from "@tensamin/hotkeys"; import { HotkeysProvider } from "@tensamin/hotkeys";
const wrapper = document.getElementById("root"); const wrapper = document.getElementById("root");
@ -255,16 +254,7 @@ function RootShell() {
designStorageKey={null} designStorageKey={null}
> >
<div className="w-screen h-dvh overflow-hidden"> <div className="w-screen h-dvh overflow-hidden">
<Toaster <Toaster position={isMobile ? "top-center" : "bottom-right"} />
position={isMobile ? "top-center" : "bottom-right"}
{...(isTauri() && isMobile
? {
mobileOffset: {
top: "env(safe-area-inset-top)",
},
}
: {})}
/>
<TooltipProvider> <TooltipProvider>
<Storage> <Storage>
<HotkeysProvider> <HotkeysProvider>

View file

@ -2,6 +2,11 @@ import { Input, type InputController } from "@methanium/ui/markdown";
import { import {
Card, Card,
CardHeader, CardHeader,
Drawer,
DrawerContent,
DrawerDescription,
DrawerTitle,
DrawerTrigger,
Popover, Popover,
PopoverContent, PopoverContent,
PopoverTrigger, PopoverTrigger,
@ -331,11 +336,33 @@ export default function InputComponent({
/> />
</PopoverContent> </PopoverContent>
</Popover> </Popover>
{isMobile ? (
<Drawer open={gifPopoverOpen} onOpenChange={setGifPopoverOpen}>
<DrawerTrigger asChild>
<div>
<Button className="w-9 h-9! p-0" variant="ghost">
<FileVideo size={20} />
</Button>
</div>
</DrawerTrigger>
<DrawerContent className="h-[80dvh]">
<div className="min-h-0 flex-1 p-3">
<GifPicker
onSelect={(url) => {
void handleSubmit(url, true);
setGifPopoverOpen(false);
}}
/>
</div>
</DrawerContent>
</Drawer>
) : (
<Popover open={gifPopoverOpen} onOpenChange={setGifPopoverOpen}> <Popover open={gifPopoverOpen} onOpenChange={setGifPopoverOpen}>
<PopoverTrigger <PopoverTrigger
render={({ onClick }) => ( render={({ onClick }) => (
<Button <Button
onClick={onClick} onClick={onClick}
aria-label="Open GIF picker"
className="w-9 h-9! p-0" className="w-9 h-9! p-0"
variant="ghost" variant="ghost"
> >
@ -367,6 +394,7 @@ export default function InputComponent({
/> />
</PopoverContent> </PopoverContent>
</Popover> </Popover>
)}
</div> </div>
</div> </div>
</CardHeader> </CardHeader>

View file

@ -166,9 +166,9 @@ export default function Media({
<DialogContent <DialogContent
showCloseButton={false} showCloseButton={false}
onWheel={handleWheel} onWheel={handleWheel}
className="bg-black/50 border-0! w-screen! h-screen! max-w-screen! rounded-none! p-0!" className="inset-0! h-dvh! w-screen! max-h-none! max-w-none! translate-none! overflow-hidden! rounded-none! border-0! bg-black/50 p-0!"
> >
<div className="relative z-10 flex w-full h-full justify-between p-7 items-start pointer-events-none"> <div className="pointer-events-none relative z-10 flex h-full w-full items-start justify-between pt-[max(1.75rem,var(--ui-safe-area-top))] pr-[max(1.75rem,var(--ui-safe-area-right))] pb-[max(1.75rem,var(--ui-safe-area-bottom))] pl-[max(1.75rem,var(--ui-safe-area-left))]">
<div <div
className={`flex gap-2 items-center transition-opacity duration-200 ${zoomLevel === 0 ? "opacity-100" : "pointer-events-none opacity-0"}`} className={`flex gap-2 items-center transition-opacity duration-200 ${zoomLevel === 0 ? "opacity-100" : "pointer-events-none opacity-0"}`}
inert={zoomLevel !== 0} inert={zoomLevel !== 0}

538
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -6,5 +6,5 @@ allowBuilds:
electron-winstaller: true electron-winstaller: true
esbuild: true esbuild: true
overrides: overrides:
"@methanium/ui": "https://git.methanium.net/methanium/ui/releases/download/0.0.28/methanium-ui.tgz" "@methanium/ui": "https://git.methanium.net/methanium/ui/releases/download/0.0.29/methanium-ui.tgz"
mtp: "https://git.methanium.net/methanium/mtp/releases/download/0.2.0-dev-a692bed/mtp-0.2.0.tgz" mtp: "https://git.methanium.net/methanium/mtp/releases/download/0.2.0-dev-a692bed/mtp-0.2.0.tgz"