Skip to content

Releases: LexicoON/Obinot

Obinot v2.1.1

Choose a tag to compare

@LexicoON LexicoON released this 04 Oct 01:34
aeaaf70

Obinot v2.1.1 — Changelog

Version: 2.1.1 (versionCode 4)


For Everyone

✨ Highlights

  • Website is live. The project now has a landing page at LexicoON.github.io/Obinot — hero, features, screenshots, Binot migration steps, all in one place. Served straight from the repo via GitHub Pages.
  • German is here. The app now ships in English, Spanish, and German, with a new language picker that shows each language in its own script plus a flag (Español 🇦🇷, Deutsch 🇩🇪, English 🇬🇧).
  • The native file picker is now the default. It shows your audio files and your exported .binot / .zip notes in one place, so importing feels the same whether you're on Record or in History.

🆕 New Features

  • Language selector in Onboarding, not just Settings — pick your language before you ever record anything.
  • Storage permission explainer in the picker's .binot tab: a one-time card that tells you why the app needs access and has a "Continue" button that fires the system prompt. Doesn't nag after the first time.

🐛 Bug Fixes

  • Shorter strings across the board. A bunch of EN/ES/DE messages were needlessly long and were getting truncated or wrapping awkwardly — trimmed ~80 entries.
  • Language switching is now data-driven. MainActivity reads from a supportedCodes set instead of a hardcoded when, so adding a language is a one-line change.
  • Existing users get the native picker enabled automatically on first launch after updating — no toggle hunting required.

For Developers

  • AppLanguage enum (ui/components/AppLanguage.kt) with DEVICE / ENGLISH / SPANISH / GERMAN, each carrying a localized display name, a native name, and a flag emoji. displayLabel() collapses duplicates ("English 🇬🇧") and shows both forms when they differ ("Inglés/English 🇬🇧").
  • values-de/strings.xml added (643 lines). locales_config.xml updated to advertise de.
  • Native picker migration: NATIVE_PICKER_MIGRATED_KEY + migrateNativePickerIfNeeded(), called from an app-scoped CoroutineScope in BinotApplication.onCreate so it never blocks UI startup. Idempotent; respects an explicit user opt-out afterwards.
  • BINOT_TAB_PERMISSION_PROMPTED_KEY tracks whether the one-time permission card has been shown.
  • Files: docs/index.html, docs/styles.css, docs/script.js, docs/assets/{icon,cover,features}.png.
  • Version: 2.1.1 / 4.

Obinot v2.1

Choose a tag to compare

@LexicoON LexicoON released this 20 Sep 22:11
a9211d2

Obinot v2.1 — Changelog

Version: 2.1.0 (versionCode 3)


For Everyone

✨ Highlights

  • Chat with AI about any note. Long-press the three-dot menu in the reader and a bottom sheet opens with a full conversation. Ask follow-ups, request rewrites, dig deeper — the chat is saved with the note and travels in your backups.
  • Edit AI summaries as raw Markdown. New "Edit Summary" action in the reader: toggle between raw Markdown and a live preview rendered with the same engine that displays your notes. The original processing metadata (language / task / format) is preserved on save.
  • Faster, smaller math rendering. KaTeX (WebView + ~1 MB of CSS/JS/fonts) is replaced by RaTeX, a native LaTeX renderer. Formulas paint immediately on the same line as your text, no first-WebView jank, no asset bloat.

🆕 New Features

  • AI chat persistence. Conversations are stored on each note (chatHistory field) and survive app restarts. A "Clear chat" button in the sheet header wipes it with a confirmation dialog.
  • Long-press the three-dot menu → jump straight into chat. One-time tooltip the first time you open the reader explains the gesture.
  • Markdown summary editor (SummaryEditorSheet) — plain-text editor on one side, live MarkdownText preview on the other.
  • Wavy audio progress bar in the reader — replaces the flat slider with a Material 3 Expressive wave that animates during playback.
  • License split. The original Binot codebase stays MIT; everything added by the fork (including the new chat, summary editor, and RaTeX integration) is now Apache 2.0 under LICENSE-OBINOT. The README explains which parts fall under which license, with credits for RaTeX, Mermaid, and the AndroidX/Kotlin stack.

🐛 Bug Fixes

  • Math no longer blocks the entrance animation. With KaTeX gone, the first-paint jank when opening a note with formulas is gone too — formulas render at native speed.
  • "Share .binot" always reports what happened. The snackbar now fires whether the file was saved to Documents or only available via the share sheet. Previously, the snackbar only appeared when saving failed.
  • Shared-element transition on the reader works again. The sharedBounds modifier was on the wrong composable; moved to the content area so the History → Result handoff animates from the card's bounds.
  • Audio waveform amplitude was passing Dp where the API expects a number. wavelength and amplitude are now using the right units for the wavy slider.
  • Chat was reading from a StateFlow on Dispatchers.IO. Replaced with a synchronous snapshot before leaving the main thread.
  • MediaStore.Downloads.EXTERNAL_CONTENT_URI rejected on some OEMs. Switched to MediaStore.Files.getContentUri("external") for the Documents save flow.

For Developers

  • DB v10 with MIGRATION_9_10 adding notes.chatHistory (TEXT, nullable) for serialized [{role, content}, ...] JSON. Not indexed. Not included in single-note .binot exports (they use an explicit data.json); is included in .obinotbak backups because Moshi serializes NoteEntity whole.
  • NoteEntity gained chatHistory: String?. .binot export still excludes it; backup format picks it up automatically.
  • io.ratex.RaTeXView replaces android.webkit.WebView-based KaTeXWebView and KaTeXInlineWebView. Block + inline math both use the same native view (displayMode = true/false).
  • Removed: androidx.webkit:webkit:1.11.0 dependency, assets/katex/ directory (CSS, JS, all .ttf / .woff / .woff2 fonts). Net APK reduction: ~1 MB.
  • Removed: exportNoteToMarkdown() and exportMarkdownFile() — Markdown export is no longer wired up in the UI.
  • Removed: "AI Explain" selection menu (the 2.0 feature). Chat replaces it as the single conversational entry point.
  • ResultViewModel gained chatMessages, isChatSending, chatTooltipShown, plus sendChatMessage(...), clearChat(), loadChatHistory(). ChatMessage(role, content) is a new public type.
  • ImportExportHelper.shareBinotToDocuments now surfaces a boolean back to the screen, which switches the snackbar between "Saved to Documents and ready to share" and "Ready to share (couldn't save to Documents)". MediaStore.Files is used in place of MediaStore.Downloads for broader OEM compatibility. Comprehensive Log calls added on every failure path.
  • MermaidAssetCache is now three-tier: memory → disk (filesDir/mermaid_cached.js) → APK assets. First read decompresses and writes to disk; subsequent app launches skip the APK decompression, ~5× faster on low-end devices.
  • NoteDao.getNotesWithLabelSync(label) — SELECT * WHERE isTrashed = 0 AND label LIKE '%' || :label || '%' AND title != '[[BINOT_SYSTEM_LABELS]]'. Used by label rename/delete to avoid loading the full notes table.
  • ProGuard rules trimmed for the KaTeX removal (no more InlineTextContent / AndroidView / ViewFactoryHolder / WebView keep-rules); added -keep class io.github.erweixin.ratex.** for JNI calls.
  • ai_chat_tooltip_shown preference in DataStore, set after the first-time tooltip is dismissed.
  • CI: removed the "Inspect RaTeX AAR packages" diagnostic step from both build-dev.yml and release.yml once the real package name (io.ratex) was confirmed.
  • LICENSE-OBINOT added with the Apache 2.0 text and a NOTICE section preserving the original Binot attribution.
  • Version: 2.1.0 / 3.

Obinot v2.0

Choose a tag to compare

@LexicoON LexicoON released this 20 Sep 02:48
7135839

Obinot v2.0 — Changelog

Version: 2.0.0 (versionCode 1)

🚀 This is the release where Obinot becomes its own app. New package (com.obinot.app), new repo, new icon, new strings. The internal format and data portability are preserved, but from now on Obinot ships and updates independently from the original Binot.


For Everyone

✨ Highlights

  • Obinot is now its own app. New package com.obinot.app, new launcher icon, brand-new adaptive icon set, and appId distinct from Binot so both apps coexist side-by-side without collisions in the launcher, file associations, or future distributions (Play Store, F-Droid, etc.).
  • Full backup format (.obinotbak) — v2. Your backup now includes notes, audio, labels (with their colors), and your preferences (everything except API keys, which never leave the device). One file, complete restore.
  • Legacy backup (.binotbak) — Binot 1.x compatible. A second export option in Settings writes the exact format the original Binot expects. Useful if you need to roll back or share with someone still on Binot 1.x.
  • In-app language picker. English + Spanish out of the box, with a per-app locale on Android 13+. The system language is respected by default — pick yours in Settings → General.
  • Adaptive layouts for tablets and landscape. The History grid now uses 3 columns in landscape (was 2), and the Record screen layout reflows to make better use of wide displays.

🆕 New Features

  • Auto-process toggle. New switch in Settings → AI to disable automatic processing of every transcription. Useful when you just want to capture audio and decide later which notes to process.
  • Full-text search (FTS4). Instant prefix matching across every field of every note — title, transcript, summary, highlights. Replaces the old label-only filter for finding content.
  • Reading font preference. Pick between Sans (default), Serif, or Mono for the Markdown reader in Settings → Reading.
  • Math inline rendering. Write $E = mc^2$ in your notes and see it rendered as proper math next to your text, not just a code block. Display math with $$...$$ still works as before.
  • Crash screen with shareable log. If the app ever crashes, a dedicated screen catches it, lets you copy or share the stack trace, and exits cleanly. No more silent kills.
  • Color privacy & data-safety docs. New privacy_policy.md and data_safety.md in the repo for anyone planning to distribute.

🐛 Bug Fixes

  • Fixed a WebView memory leak in the Markdown reader — every opened/closed note used to leave ~2–5 MB behind. WebViews are now properly torn down on release.
  • Fixed inline math overflow that was scaling formulas down too aggressively; only formulas that genuinely overflow the line now get scaled.
  • Fixed first-paint jank when opening a note with diagrams or math — the WebView init (~500 ms) no longer blocks the entrance animation.
  • Fixed the getLatestRelease API endpoint pointing at the renamed repo (LexicoON/Binot-fix → LexicoON/Obinot) so in-app update checks work again.
  • Fixed backup restore on first install by detecting .obinotbak (v2) vs .binotbak (legacy) automatically — both formats restore correctly without user input.

For Developers

  • New package namespace com.example → com.obinot.app across all 34 Kotlin files. Application ID switched from com.aistudio.binot.xrztp to com.obinot.app. versionCode reset to 1, versionName to 2.0.0 (independent app lifecycle).
  • NoteFtsEntity + MIGRATION_8_9 — Room FTS4 virtual table mirroring the notes columns for full-text search. New DAO queries: searchNotes(query, limit) with prefix matching.
  • SettingsRepository gained: appLanguageFlow, autoProcessFlow, readingFontFlow, all persisted via DataStore with first-class setters.
  • ImportExportHelper rewritten around two ZIP formats:
    • .obinotbak v2 — notes.json, audio/*, labels.json (name + colorHex), settings.json (no API keys), obinot_backup_meta.json.
    • .binotbak legacy — notes.json, audio/* only. Exact Binot 1.x format for cross-restore.
    • .binot v2 single-note export — added obinot_meta.json to carry label colors across apps.
  • ZIP helpers extracted to SettingsViewModel: writeBytesToZip (DEFLATED for JSON) and writeStoredFileToZip (STORED for audio, with CRC32 + size precomputed; reads ≤5 MB into RAM, streams larger files through a temp file).
  • Crash handler pipeline — CrashHandler registers a Thread.UncaughtExceptionHandler that writes the trace to a file and launches CrashActivity in a separate process (android:process=":crash") so a crash inside the crash handler can't recurse.
  • Per-app locale via AppCompatDelegate — MainActivity now extends AppCompatActivity and applies the persisted app_language preference before setContent(). locales_config.xml declared in the manifest for Android 13+ system-level locale support.
  • Inline math parser — splitInlineMath() splits a Markdown line on $...$ and $$...$$ with regex validation against false positives (prices like $100 are preserved as text).
  • WebView deferred mount — MarkdownText waits 200 ms after composition before mounting KaTeX/Mermaid WebViews, replacing them with shimmer skeletons during the delay to keep the entrance animation smooth.
  • Adaptive icon resources — generated ic_launcher_background.png, _foreground.png, and _monochrome.png for every density; the old ic_launcher_round.webp removed.
  • Release workflow — .github/workflows/release.yml now renames the built APK to Obinot-${TAG}.apk before uploading as an artifact and attaching to the GitHub release.
  • ProGuard rules — extended to keep the CrashHandler entry points and the new com.obinot.app model classes reachable in release builds.
  • Version: 2.0.0 / 1.

A quick word on how we got here

Obinot started life as Binot-fix, a community patch for the original Binot by @DENSLnetion, back when the AI providers retired the hardcoded model names and the app quietly stopped working. From there: a v1.1.x series that added Material 3 Expressive, colored labels, auto-compression, Mermaid + KaTeX offline, multi-provider AI, Mix Mode routing, and a hundred-and-thirty patches of polish — all while keeping the .binot format and database schema cross-compatible so nobody's notes ever got stranded.

This 2.0 is the release where we stop pretending otherwise: Obinot is its own app now, with its own identity, its own package, its own icon, and its own future. The format still opens in Binot 1.x, Binot 1.x backups still restore into Obinot, and the original Binot keeps living where it always has — we're a respectful fork, not a hostile takeover.


Thank you

A release like this doesn't happen alone, and this one was genuinely harder than it had any right to be — namespace migrations across 34 files, parallel format versions, crash-handler edge cases, and a full UI copy in two languages, all in one cycle. There were days it felt like the kind of refactor that breaks more than it fixes.

So a few honest thank-yous:

  • To @DENSLnetion, the original creator of Binot, for releasing it under MIT in the first place. Without that, none of this exists. Please go star the original repo — that's where the project truly lives.
  • To everyone who downloaded Binot-fix, opened an issue, sent a screenshot, or just said "hey, this worked for me" — small words, but they kept the project alive when the easy move would've been to drop it.

Here's to 2.0. Onwards.

— LexicoON

Binot v1.1.9

Choose a tag to compare

@LexicoON LexicoON released this 19 Sep 02:21
2a4163e

Obinot v1.1.9 — Changelog

Version: 1.1.9 (versionCode 20)

For Everyone

✨ Highlights

  • Smoother and lighter: the app no longer polls the database every 1.5 seconds in the background — it reacts to changes instantly and uses almost no CPU when idle.
  • New press behavior on buttons: filled and outlined buttons now grow outward when you press them (like the Record button) instead of shrinking. Icon buttons keep their squish.
  • File picker now paginates long lists and sorts server-side, so browsing large music/audio libraries stays fast.
  • Faster imports and exports: large .binot backups and audio imports now stream through buffers instead of loading everything into RAM at once.

🆕 New Features

  • Toggle groups have a bouncy press — Tidy Up / Summary / Analyze, Fast / Accurate, theme selector, and the sort row in History now respond with a squish on tap.
  • Animated Live Transcript reveal in Settings — the toggle slides in/out with a smooth spring instead of popping in.
  • Consistent Bouncy system across Onboarding, Settings, Result, History, and Trash, with a shared BouncyToggleButton.
  • Auto-mirrored icons for RTL support: arrows, sort, label, notes, and bullets now flip correctly on right-to-left locales.
  • A new "Warnings Audit" workflow on GitHub Actions (manual trigger) that builds the app with --warning-mode all and uploads the log as an artifact.

🐛 Bug Fixes

  • Fixed History with many notes getting slow because isAllPinned was doing a full list scan on every recomposition.
  • Fixed labels loading re-reading every note entity (raw text, summary, highlights) just to extract label strings.
  • Fixed ResultScreen search recomputing the full split and filter on every keystroke; it’s now cached.
  • Fixed ImportExportHelper reading large audio files twice during export, and unbuffered streams during import.
  • Fixed Bouncy buttons on fillMaxWidth looking wrong (they tried to grow when the width was already assigned).
  • Fixed AnimatedContent + BouncyButton measurement loop that could crash on long-press of “Check Update”.
  • Fixed wrong icon variants (Icons.Default.Label, Sort, etc.) that had AutoMirrored counterparts and were breaking RTL.
  • Fixed unchecked cast warnings in the file picker by branching per tab before calling the query.
  • Fixed redundant .toFloat() in the audio waveform.
  • Made fallbackToDestructiveMigration(dropAllTables = true) explicit so the app doesn’t crash on unknown schema versions.

For Developers

  • DB v8 with MIGRATION_7_8 adding composite indices: index_notes_isTrashed_isPinned_timestamp, index_notes_isTrashed_timestamp, index_notes_title. Declared in NoteEntity.indices.
  • New DAO queries: getRecentNotes(limit), getSystemNote(), getSystemNoteSync(), getAllLabelStrings() (projection — no entity hydration).
  • RecordViewModel: replaced pollJob loop (1.5s getAllNotesSync) with repository.getRecentNotes(16).stateIn(WhileSubscribed(5000)).
  • HistoryViewModel / ResultViewModel: uniqueLabels / allLabels now built with combine(getAllLabelStrings(), getSystemNote()) instead of loading all entities.
  • NoteEntity / LabelEntity: annotated @Immutable for better Compose skipping.
  • ObinotFilePickerSheet: paginated MediaStore reads via Bundle with QUERY_ARG_LIMIT / QUERY_ARG_OFFSET on API 26+, manual skip fallback on 24–25. Page size = 150. Sort pushed to SQL. Per-tab branching removes the unchecked casts.
  • ImportExportHelper: 64 KB buffered streams; writeStoredFile() reads ≤5 MB files into RAM (1 pass) and streams >5 MB through a temp file to compute CRC32/size before writing (avoids double-reading the source).
  • BouncyComponents.kt rewrite:
    • observeBouncyPress(interactionSource, scale, pressedScale) — squish scale, kept for FABs, cards, play buttons, icon buttons.
    • rememberBouncyExpand(interactionSource, enabled, target) — Animatable<Dp> for horizontal expansion with a snapTo on quick release.
    • BouncyButton / BouncyOutlinedButton: animate contentPadding (surface grows) — external Modifier.padding does not work because it only adds empty space. Default expandOnPress = 16.dp. Pass 0.dp when using fillMaxWidth / weight(1f) / align(End).
    • BouncyIconButton: kept as scale squish (M3’s IconButton has a fixed state layer and no exposed contentPadding).
    • BouncyCapsule / BouncyChip: animate padding after background/clip so the visible surface grows.
    • New BouncyToggleButton — scale squish wrapper around M3’s ToggleButton for weight(1f) groups.
  • Settings: AnimatedVisibility(expandVertically + fadeIn / shrinkVertically + fadeOut) replaces the hard if (recordMode == 1) for the Live Transcript block.
  • AudioWaveform: uses Kotlin’s sin(Float) overload; removed the trailing .toFloat().
  • fallbackToDestructiveMigration(dropAllTables = true) made explicit for the newer Room overload.
  • CI: added .github/workflows/warnings-audit.yml (workflow_dispatch, JDK 21, Gradle 9.7.1, --warning-mode all, uploads warnings_full.log and optional filtered log).
  • Version: 1.1.9 / 20.

Binot v1.1.8

Choose a tag to compare

@LexicoON LexicoON released this 18 Sep 22:59
9e4d31c

Obinot v1.1.8 — Changelog

Version: 1.1.8 (versionCode 20)

For Everyone

✨ Highlights

  • The app is now called Obinot (a fork of Binot) so it can coexist with the original on the same device. Existing notes, audio, and backups are 100% compatible.
  • 7 color palette styles to theme the whole app (Tonal Spot, Vibrant, Expressive, Fruit Salad, Neutral, Fidelity, Monochrome).
  • Colored labels — assign a color to each label so you can spot them at a glance in History and the reader.
  • Auto Compression — long recordings get shrunk automatically before being sent to AI providers that have a size limit.
  • Unified file picker (BETA) — one sheet that lists both device audio files and exported .binot notes.
  • Drag & drop import — drag audio files or .binot notes into the app from a file manager.

🆕 New Features

  • Rebranded to Obinot across the app, notifications, exports, and share messages.
  • Color palette selector in Settings, powered by MaterialKolor.
  • Label colors with a swatch picker (including a "Dynamic" option that follows the theme).
  • Auto Compression with three levels: Off, Balanced (24 MB target), Max (15 MB target).
  • Live Transcript toggle (BETA) — in Accurate mode you can now choose whether the phone’s recognizer runs alongside the recorder. Off by default because it fails on many devices.
  • Native Audio Picker (BETA) — Settings toggle to use Obinot’s own picker instead of the system file picker.
  • Unified picker with two tabs: Audio and .binot Notes, plus a "Browse files" fallback.
  • Drag & drop in both the Record and History screens, with a visual “Drop to import” overlay.
  • Enhanced Markdown reader — tables, code blocks, blockquotes, links, KaTeX, and Mermaid diagrams all render properly.
  • Per-task AI models — lighter models for titles/explanations, heavier models for transcription/processing.
  • Better background-recording notification with a native chronometer and no flicker.
  • Dynamic mode — the old “Mix” mode has been renamed for clarity (same feature).

🐛 Bug Fixes

  • Fixed color palette styles being ignored when the device supported wallpaper colors.
  • Fixed Fruit Salad/Rainbow behavior: the label now maps to a genuinely colorful palette.
  • Fixed Audio Compressor hanging on long recordings; rewritten to be reliable and to report progress.
  • Fixed compression stalls being reported as “Unknown error”; now they fail fast with a clear message.
  • Fixed buttons sometimes not bouncy on very quick taps; the squish is now forced when needed.
  • Fixed FAB shadow glitch while scrolling in History.
  • Fixed drag & drop rejecting valid files whose MIME type wasn’t audio/*.
  • Fixed labels rendering gray instead of using the theme color when no color was assigned.
  • Fixed Audio picker showing “no files” because the storage permission was never requested.
  • Fixed live transcript caption saying “disabled” even when it was running.
  • Fixed Markdown losing KaTeX/Mermaid renders while scrolling (no more “blank until re-render”).
  • Fixed several Material 3 Expressive build issues (DropdownMenu, AnimatedVisibility, ButtonGroup).
  • Fixed notification updating every second during background recording.

For Developers

  • Rebrand: app_name, Theme.Obinot, ObinotFilePickerSheet, share MIME text, and export filenames updated. DB schema and .binot format unchanged for compatibility.
  • New data layer: LabelEntity, LabelDao, LabelRepository; DB bumped to v7 with MIGRATION_6_7 for the labels table.
  • Theme: integrated MaterialKolor (DynamicMaterialExpressiveTheme); ColorStyle enum (7 values) mapped to PaletteStyle; wallpaper color now used only as seed.
  • AudioCompressor: rewritten from sync dequeue*Buffer loop to async MediaCodec.Callback with dedicated HandlerThreads, a bounded LinkedBlockingQueue for backpressure, stall detection, and hard timeout.
  • Live Transcript: new LIVE_TRANSCRIPT_KEY in SettingsRepository; AudioRecorderManager.startRecording(...) takes liveTranscriptEnabled; default OFF.
  • Native picker toggle: NATIVE_PICKER_KEY; ObinotFilePickerSheet replaces AudioFilePickerSheet (kept as alias).
  • Drag & drop wired via Modifier.dragAndDropTarget in RecordScreen and HistoryScreen; uses clipData only for URIs.
  • MarkdownText: migrated from LazyColumn to Column + verticalScroll to preserve WebView state; accepts optional SnapshotStateMap<Int, Int> for scroll-to-line.
  • Bouncy components: unified observeBouncyPress(...) helper; extracted from every Bouncy* composable.
  • Model routing: GeminiModels / GroqModels constants; per-task model selection; Dynamic mode routes by size/context with quota balancing.
  • Settings refactor: reusable SettingsSelectorRow + SettingsSelectionSheet + BetaBadge.
  • Manifest: READ_MEDIA_AUDIO (33+) and READ_EXTERNAL_STORAGE (≤32) added for the native picker.
  • Version: 1.1.8 / 20.

Binot v1.1.7

Choose a tag to compare

@LexicoON LexicoON released this 11 Sep 17:55
73829f8

Binot v1.1.7 — Changelog

Version: 1.1.7 (versionCode 19)

For Everyone

✨ Highlights

  • Big Material 3 Expressive visual refresh across the app.
  • New animated bottom navigation with haptic feedback.
  • History screen got a smoother, more playful swipe-to-delete experience.
  • Result side panel, settings toggles, chips, and FAB now feel more bouncy and modern.

🆕 New Features

  • Expressive bottom navigation with haptics when switching tabs.
  • History sort now uses clear toggle buttons.
  • Magnetic swipe-to-delete on notes, with Undo snackbar.
  • Import FAB morphs between icon-only and icon + label.
  • Redesigned Result side panel with sections for Labels, Find & Format, Reading Font, and Export & Media.
  • New bouncy label chips and improved audio/share capsules.
  • Settings now uses expressive toggle groups for AI task, format, provider, record mode, and theme.
  • Background recording switch shows a check indicator when enabled.
  • Predictive back gesture enabled on supported Android versions.
  • New onboarding loading indicator.

🐛 Bug Fixes

  • Fixed Monospace font selection typo in Reading Font.
  • Removed system/synthetic notes from appearing in recent recordings.
  • Fixed FAB shadow glitch while scrolling in History.
  • Improved quick-tap bounce so buttons always animate visibly.
  • Fixed several Material 3 Expressive build issues.

For Developers

  • Material3 bumped to 1.5.0-alpha28; switched to MaterialExpressiveTheme + MotionScheme.expressive().
  • Replaced NavigationBar with ShortNavigationBar; added HapticFeedbackType.LongPress.
  • History swipe replaced SwipeToDismissBox with custom draggable + shared MagneticSwipeState.
  • Settings/Result add ExpressiveToggleGroup, BouncyButton, BouncyChip, BouncyCapsule using Animatable.
  • CI updated: JDK 21, Gradle 9.7.1, newer GitHub Actions; added build-dev.yml.
  • Manifest: enableOnBackInvokedCallback="true". Version: 1.1.7 / 19.

Binot v1.1.6-hotfix

Choose a tag to compare

@LexicoON LexicoON released this 09 Sep 00:41
e3eca71

📋 Binot Changelog — v1.1.6 (versionCode 18)

A quick note from the developer: 🙏 I'm sorry it's been so many releases without a proper changelog — I was fully focused on fixing bugs and improving the app itself. Now here's the full changelog covering everything so far, all in one place!


👥 For Users (What's New & Fixed)

✨ New Features

  • 🎙️ Record in Background (the big one)
    • You can now keep recording with the screen off or while using other apps.
    • A persistent notification shows the live recording time (e.g., "05:23 elapsed"), and tapping it brings you right back into the app.
    • Enable it from Settings → Record in Background. On Android 13+, the app will ask for notification permission — you can deny it and the feature still works, you just won't see the notification.

🔧 Fixes & Improvements

  • Fixed the "fails only in Mix mode" bug 🐞

    • Some of you noticed processing worked fine with one AI provider but failed with 503 errors only when both were active at once. That race condition is fixed — tasks now run one after another instead of colliding.
  • Fixed notes losing their title or summary

    • Rarely, a note would end up missing its AI-generated title or summary because two background tasks were overwriting each other. They now run in a coordinated sequence.
  • Better AI responses

    • Each AI provider (Gemini and Groq/Llama) now gets its own fully tailored instructions instead of sharing a patched-up template. Diagrams, math (LaTeX), and translations should be more consistent now.
    • Updated to a newer Gemini model for content generation.
  • Polished visuals ✨

    • Smoother, more modern loading indicators and progress bars throughout the app (onboarding, recording, update download).
    • Smoother card animations when opening and closing notes.
  • App updates faster now — internal libraries were updated to their latest versions.

📦 Version History

Version What happened
1.1.4 Last public release before this one
1.1.5 Background recording introduced
1.1.5-hotfix Quick fix for a background-recording crash
1.1.6 This release — everything above combined 🎉

🛠️ For Developers (Technical Changelog)

Architecture & Features

  • Background recording via foreground service

    • New RecordingService (utils/RecordingService.kt), type microphone, started/stopped by RecordViewModel based on a new backgroundRecordingFlow preference in SettingsRepository (BACKGROUND_RECORDING_KEY).
    • Service does not own the MediaRecorder — AudioRecorderManager remains the app-wide singleton (via AppContainer); the service exists solely to hold the foreground service + notification while recording.
    • Manifest: added FOREGROUND_SERVICE, FOREGROUND_SERVICE_MICROPHONE permissions and service declaration (android:foregroundServiceType="microphone").
    • Settings UI toggle with POST_NOTIFICATIONS permission request (Android 13+), and a SettingsViewModel.saveBackgroundRecording() accessor.
    • Temp diagnostics: Toasts in onStartCommand/beginWatching and a try/catch around startForeground() to surface failures without logcat. ⚠️ Remove these before production.
  • Result processing race fixes (ResultViewModel)

    • generateTitleFromTranscript() now returns NoteEntity? and is awaited before summarization begins, eliminating the title-vs-summary stale-copy() overwrite race.
    • Title generation runs first; checkAndTriggerAutoProcess is launched after with the title-containing note — removes the simultaneous dual-provider 503 spike in Mix mode.
    • Fallback title path now updates state/repository from the main dispatcher.
  • Split system prompts per provider

    • Replaced single systemPrompt + Groq-only appended overrides with independent geminiSystemPrompt and groqSystemPrompt (Groq adds mermaid backtick allowance/enforcement + strict math isolation rules 7–9). No behavioral cross-contamination when editing either prompt.

Dependency & Build Updates

  • composeBom: 2024.09.00 → 2026.04.01
  • material3 pinned to 1.5.0-alpha27 (explicit version ref, overriding BOM) for Material 3 Expressive APIs
  • compileSdk 36 (minor 1) → 37
  • Migrated to Material 3 Expressive components:
    • CircularProgressIndicator → LoadingIndicator (Onboarding, Record, Settings)
    • LinearProgressIndicator → LinearWavyProgressIndicator (Settings download progress)
    • Added @file:OptIn(ExperimentalMaterial3ExpressiveApi::class) where needed

Fixes

  • SharedTransitionScope.ResizeMode.ScaleToBounds() → SharedTransitionScope.ResizeMode.scaleToBounds() (History, Record, Result screens) — API migration after BOM bump.
  • RecordingService notification icon: applicationInfo.icon → R.mipmap.ic_launcher_monochrome + missing R import fix.
  • MainActivity context fixes in RecordViewModel.provideFactory() — final: context.applicationContext (avoids leaking an Activity context into the service calls).
  • API endpoint change: gemini-flash-latest → gemini-3.5-flash-lite in GeminiApi.kt (⚠️ verify this model name — see note below).

Versioning

  • versionCode: 16 → 18 | versionName: 1.1.4 → 1.1.6

⚠️ Things to double-check before publishing

  1. Remove the diagnostic Toasts in RecordingService (patches 15) — they're debug-only.
  2. Verify gemini-3.5-flash-lite is the intended model name — the patch changes from gemini-flash-latest to an unusual slug; confirm it exists in the API docs or requests will 404.
  3. Foreground service permission on Android 14+: microphone type FGS requires the FOREGROUND_SERVICE_MICROPHONE permission (added ✅) — but also consider declaring the runtime mic rationale, since some OEMs kill type-restricted services aggressively.

Binot v1.1.6

Choose a tag to compare

@LexicoON LexicoON released this 08 Sep 23:55
c162e53
Update resizeMode to use ResizeMode.scaleToBounds

Binot v1.1.5-hotfix

Choose a tag to compare

@LexicoON LexicoON released this 08 Sep 02:49
ac61030
Bump version code and update version name for hotfix

Binot v1.1.5

Choose a tag to compare

@LexicoON LexicoON released this 08 Sep 01:48
8c0a906
Fix context reference in RecordViewModel factory