* feat: bundled JSON release notes for 4.0, polished changelog sheet, remove IAP
- Move release-note content from ARB to assets/release_notes/<locale>.json
with locale-fallback repository and schema-checked validator
- Polish the release notes sheet (staggered reveal, version badge,
feature glyph bullets, action cards) and add the 4.0 note in 13 locales
- Prune pre-4.0 notes
- Remove in_app_purchase and the tip jar entirely; keep the Buy Me a
Coffee donation link on all platforms
* Refresh release notes sheet and localized copy
* Add release notes banner and native review support
* Redesign release announcement sheet
* Target release announcement to 4.0.1
* Address release announcement review feedback
* Tighten release note locale handling
* feat: add direct provider connections
* fix: harden direct connection workflows
* fix: stabilize direct connection state
* fix: ignore failed direct image attachments
* fix: serialize direct profile reloads
* fix: recheck queued media upload routes
* fix: prune stale direct models during refresh
* feat: polish adaptive backend onboarding
* fix: restore explicit backend onboarding back paths
Hermes and Direct onboarding are entered with replacement routes, so they cannot rely on an implicit navigator pop. Give both flows explicit destinations and align their setup screens with the adaptive auth shell.
* fix: harden direct onboarding state
Re-read profiles after asynchronous confirmation, guard discovery writes after disposal, and keep disabled segments unselected. Consolidate the shared onboarding shell and header-security resets to prevent drift.
* fix: keep local backends independent after logout
Logout intentionally retains OpenWebUI server state, so routing and model selection now key off resolved backend usability, terminal auth, trusted Direct bindings, and auth-session identity across loading, error, retained-value, cold-start, and backend-switch races.
* fix: preserve chat storage boundaries on recovery
Treat OpenWebUI cache reads as best-effort only when ownership is explicit, retain ambiguity and Direct-local failures instead of crossing providers, and contain asynchronous default-model cache write errors. Regression tests cover all three paths.
* fix: retain legacy OpenWebUI chat ownership
When the merged chat list is still loading, an explicitly OpenWebUI-scoped active summary now restores ownership for legacy raw IDs without trusting Direct-local or unannotated rows. This prevents same-ID local chats from making a valid OpenWebUI conversation ambiguous.
* feat: migrate direct providers to typed SDKs
* fix: isolate direct transport and reject blank streams
* fix: hide stale direct model bindings
* fix: apply CodeRabbit auto-fixes
* feat: support Hermes attachments via Responses API
* fix: address direct and Hermes review findings
* fix: avoid OpenWebUI settings load in direct composer
* fix: preserve images during direct regeneration
* fix: preserve repeated direct images across turns
* fix: settle direct reasoning and Android chrome
* fix: harden multi-backend streaming ownership
* fix: harden multi-backend recovery lifecycles
* fix: close adversarial multi-backend edge cases
* fix: separate Responses reasoning items
* fix: preserve streamed reasoning boundaries
* fix: address final multi-backend review findings
* fix: close remaining security review findings
* fix: address PR review findings
- Introduced `conduitUsesOpaqueGlassFallback` utility to determine button styles based on platform capabilities.
- Updated button styles in `ChatPage`, `ExpandedTextEditor`, `ModernChatInput`, and `NoteEditorPage` to utilize opaque glass fallback where necessary.
- Enhanced visual consistency by applying the new styling logic to various adaptive buttons throughout the chat and note editing interfaces.
- Added `ComposerTextInsertion` class and provider to manage text insertion requests in the chat interface.
- Integrated `composerTextInsertionTargetId` into relevant components, allowing for targeted text insertion.
- Enhanced `ModernChatInput` to handle text insertion at the current selection, improving user experience during message composition.
- Updated `StreamingMarkdownWidget` and `AssistantMessageWidget` to support the new text insertion feature, ensuring consistent behavior across chat components.
- Updated versions of several packages in pubspec.lock, including meta (1.18.0), test (1.31.0), test_api (0.7.11), and test_core (0.6.17).
- Cleaned up Podfile.lock by removing unused dependencies to streamline the project.
- Added FlutterGeneratedPluginSwiftPackage to the Xcode project for better integration with Flutter plugins.
- Introduced a pre-action script in the Xcode scheme to prepare the Flutter framework during build.
- Added terminal tab to the sidebar, allowing users to access terminal features directly.
- Implemented localization support for terminal-related labels and actions in multiple languages.
- Enhanced the sidebar's active tab management to accommodate the new terminal tab.
- Updated the `NativeSheetBridge` to support custom detent height for terminal sheets.
- Improved error handling and user feedback for terminal operations, including connection and file management.
- Refactored composer overflow menu to display localized messages for tool availability and loading errors.
- Refactored the adaptive toolbar in ChatPage to improve layout and responsiveness, replacing direct widget usage with utility functions for better maintainability.
- Introduced new action widgets for the adaptive toolbar, including temporary chat actions and overflow buttons, enhancing user interaction.
- Updated the conversation context menu to include additional SF symbols for improved icon representation, ensuring consistency across platforms.
- Enhanced the overall structure of the toolbar actions to streamline the addition of new features in the future.
- Updated entitlements and Info.plist files to use environment variables for app group ID and URL scheme, enhancing flexibility for different build configurations.
- Introduced a `WidgetDeepLink` enum in `ConduitWidget.swift` to streamline URL generation for widget actions.
- Refactored widget link destinations to utilize the new deep link structure, improving code maintainability.
- Added performance profiling to various components to monitor and optimize widget interactions.
- Introduced localized strings for error messages, dropdowns, and UI elements in NativeDropdownBridge, NativeSheetBridge, and AppDelegate.
- Updated API error handling to utilize localized messages for better user experience.
- Refactored chat and thread components to incorporate localized labels and placeholders, improving accessibility and consistency.
- Added support for multiple languages by integrating Localizable.strings files into the project structure.
- Eliminated the _prefetchConversations method from AuthStateManager to streamline the authentication process.
- Removed redundant calls to _prefetchConversations in various login flows, enhancing performance and clarity.
- Cleaned up whitespace and formatting in several files for improved readability and consistency.
- Added support for native sheets in the iOS app, enhancing user interactions in chat, navigation, and other features.
- Implemented native sheet presentations for options selectors, detail views, and share functionalities in multiple widgets.
- Updated the AppDelegate to configure new native sheet bridges for improved communication with the native layer.
- Refactored existing components to utilize native sheets, ensuring a consistent user experience across the application.
- Enhanced error handling and responsiveness for native sheet interactions, particularly on iOS.
- Changed the `flutter_driver` dependency from "direct dev" to "direct main" in `pubspec.lock` to align with the main dependency structure.
- Added `flutter_driver` as a direct dependency in `pubspec.yaml` to facilitate integration testing.
- Updated the main application entry point to disable the Flutter Driver extension by default, enhancing control over testing environments.
- Refactored various UI components to improve layout consistency and responsiveness, including replacing `AnimatedContainer` with `Container` for better performance.
- Introduced `flutter_driver` as a direct development dependency in `pubspec.yaml` to facilitate integration testing.
- Updated `pubspec.lock` to include new transitive dependencies such as `fuchsia_remote_debug_protocol`, `process`, `sync_http`, and `webdriver`, ensuring compatibility with the latest package versions.
- Enhanced the main application entry point to conditionally enable the Flutter Driver extension based on the environment variable, improving testing capabilities.
- Made minor adjustments to various components for better responsiveness and functionality, including the addition of keys for improved widget identification.
- Updated multiple instances of showDialog to ThemedDialogs.showCustom across various services and components to ensure a consistent dialog presentation.
- Enhanced the user experience by utilizing themed dialogs in error handling, accessibility, and chat functionalities.
- Removed deprecated dialog implementations in favor of the new themed approach, streamlining the codebase.
- Deleted `cupertino_context_menu_plus` dependency from `pubspec.yaml` and `pubspec.lock` to streamline package management.
- Refactored various components to utilize `AdaptiveRouteShell` instead of `AdaptiveScaffold` for improved layout consistency across the application.
- Replaced `InkWell` with `GestureDetector` in multiple files to enhance touch handling and responsiveness.
- Updated error boundary components to utilize the new adaptive route shell structure, ensuring better error handling and user experience.
- Introduced new routes for folder navigation, allowing users to access specific folders via the sidebar.
- Added functionality to retrieve the current folder ID from the navigation service.
- Enhanced sidebar search capabilities with a dedicated search field controller and focus management.
- Updated sidebar user pill to include search functionality and improved layout for better user experience.
- Refactored notes list page to utilize a primary circle button for creating new notes, aligning with the sidebar design.
- Added `cupertino_context_menu_plus` version 1.0.3 to dependencies in `pubspec.yaml`.
- Removed deprecated packages including `device_info_plus`, `super_context_menu`, and others from `pubspec.lock`.
- Updated `Podfile` to remove unnecessary patching for `super_native_extensions`.
- Introduced a new utility file `message_tree_utils.dart` for improved message handling in the API service.
- Refactored message processing logic in `api_service.dart` and `conversation_parsing.dart` to utilize the new utility functions.
- Enhanced channel management UI with new dialog components for creating and editing channels.
- Added the ability to share chat conversations via a new share button in the chat interface.
- Introduced a delete function for existing shared links, allowing users to manage shared conversations effectively.
- Updated localization files to support new share chat features in multiple languages.
- Enhanced the context menu with share options for better accessibility.
- Replaced various text styles in chat-related widgets with new centralized typography styles for improved consistency and readability.
- Updated styles in the composer overflow menu, model selector sheet, reasoning tile, tool call tile, and default model sheet to utilize the new typography settings.
- Enhanced the overall visual hierarchy and maintainability of the codebase by standardizing text styles across multiple components.
- Removed redundant snapshot creation for message versions and replaced it with a new _buildReplayVersions function to enhance clarity and maintainability.
- Updated the regeneration logic to directly use message IDs, simplifying the process of regenerating historical messages.
- Introduced utility functions for checking archived message variants and building version snapshots, improving code organization and readability.
- Adjusted UI components to ensure regeneration actions are only available when appropriate, enhancing user experience.
* feat: make drawer full-width on phones
* feat: add sidebar active tab provider with Hive persistence
* refactor: add AutomaticKeepAliveClientMixin to ChatsDrawer
* feat: add tabbed SidebarPage with Chats/Notes/Channels tabs
* feat: add localization strings for sidebar and channels
* feat: add Channel and ChannelMessage Freezed models
* feat: add NotesListTab to sidebar
* feat: add /channel/:id route and navigation helpers
* feat: add channel Riverpod providers
* feat: add ChannelListTab to sidebar
Implements the Channels tab in SidebarPage with search filtering,
pull-to-refresh, empty/error states, and a FAB for channel creation.
* feat: add ChannelPage with messaging, reactions, and menu actions
* feat: add real-time socket handler for channel events
* chore: final cleanup and build verification
Fix analyzer warnings: suppress false-positive invalid_annotation_target
in Freezed models, remove unused imports, and rename unnecessary underscores.
* fix: address code review findings
- Hide Notes tab when notesFeatureEnabledProvider is false (spec compliance)
- Add message deduplication in prependMessage to prevent socket + local dupes
- Wire unread badge to channel list tiles via channelUnreadCountProvider
- Dispose TextEditingControllers in create channel dialog
- Guard ref.read in ChannelPage.dispose with try/catch for safety
- Add platform-aware scrimColor to ChannelPage's ResponsiveDrawerLayout
* fix: use nanosecond epoch conversion for channel timestamps
Open WebUI returns nanosecond timestamps for channel/message created_at
and updated_at fields. The model was treating them as seconds and
multiplying by 1000, causing RangeError overflow. Follow the Note model
pattern: divide by 1000 to get microseconds and use
DateTime.fromMicrosecondsSinceEpoch.
* fix: don't dispose dialog-local TextEditingControllers eagerly
The dialog's exit animation may still reference the controllers after
showDialog returns. Disposing them synchronously causes
"TextEditingController was used after being disposed" errors.
Let GC handle cleanup when the dialog tree is fully torn down.
* feat: match channel input bar to compact chat composer design
Use the same visual tokens as ModernChatInput's compact composer:
rounded shell with surfaceContainerHighest fill, borderless text field
with chatMessageStyle, circular send button with arrow_up icon and
buttonPrimary background, screenPadding + viewPadding.bottom spacing.
* feat: UI refinements — adaptive search bars, FloatingAppBar, full composer
- Replace inline search TextFields in Notes and Channels tabs with
ConduitGlassSearchField (CupertinoSearchTextField on iOS, Material
on Android) wrapped in FloatingAppBarPill for consistent styling
- Replace sidebar close IconButton with FloatingAppBarIconButton
(adaptive glass pill matching hamburger menu style)
- Replace channel page AppBar with FloatingAppBar + FloatingAppBarTitle
(gradient background, pill-shaped elements matching profiles page)
- Upgrade channel input bar: adaptive CupertinoTextField on iOS,
blur shell on iOS / material container on others, plus button
opening ComposerOverflowSheet, circular send button via
_buildComposerIconButton with proper disabled state theming
- Add prompt command detection (/ and #) with PromptSuggestionOverlay
and keyboard navigation for arrow keys and escape
* feat: hamburger menu on all pages, sidebar pushes content aside
- Replace back button with hamburger menu on both channel page and
notes editor so swiping from the left edge or tapping the menu
opens the same sidebar from any page
- Wrap notes editor in ResponsiveDrawerLayout with SidebarPage drawer
- Enable pushContent on all three pages (chat, channel, notes editor)
so the sidebar slides the active page to the right instead of
overlaying on top
- Set maxFraction to 0.84 on phones so the pushed-aside page remains
partially visible behind the sidebar
* feat: full-width sidebar, remove close button, consistent tab styling
- Set maxFraction to 1.0 on all pages so the sidebar covers the full
screen width on phones (content is pushed entirely off-screen)
- Remove the close button from SidebarPage — users swipe right or
tap the hamburger menu on the underlying page to dismiss
- Restyle TabBar with conduitTheme tokens: textPrimary/textSecondary
label colors, bodySmallStyle typography, no divider line, ensuring
consistent appearance regardless of which page hosts the sidebar
* fix: notes editor drag opens sidebar instead of navigating back
- Change all note editor navigation from pushNamed to goNamed so
the route replaces rather than stacks — this eliminates the iOS
back-swipe gesture that was competing with the sidebar edge drag
- Remove PopScope wrapper (no longer needed since route is not pushed)
- After delete, navigate to /chat via go() instead of Navigator.pop()
* feat: inline add buttons, cross-page navigation, active tile highlighting
- Replace FABs with adaptive add buttons next to search bars in Notes,
Channels, and Chats tabs
- Fix sidebar navigation not switching pages when tapping items from a
different page (e.g. selecting a chat while on note editor)
- Add ValueKey to NoteEditorPage route for proper rebuild on note switch
- Highlight active note/channel tile with tinted background matching
the chat tile selected style
- Polish note tiles with card backgrounds, better typography hierarchy,
and increased spacing
- Restyle channel tiles with rounded card layout matching notes
* perf: optimize rebuilds and localize remaining hardcoded strings
Performance:
- Replace ListenableBuilder on router with targeted addListener that
only triggers setState when the active note/channel ID changes
- Hoist RegExp patterns to static final fields (route matchers, word
count, markdown bold/italic)
- Cache word count in _onContentChanged instead of recomputing on
every build
- Move ref.read(currentUserProvider) out of channel message itemBuilder
to ref.watch() resolved once before ListView.builder
- Mark channelUnreadCountProvider as keepAlive to prevent re-fetching
on tile recomposition
Localization:
- Add searchChannels, channelCreateError, channelMessageHint,
audioUploadError keys to app_en.arb
- Replace all hardcoded strings in notes_list_tab with l10n calls
(searchNotes, noNotesYet, noNotesFound, failedToLoadNotes, untitled)
- Replace hardcoded strings in channel_list_tab (searchChannels,
channelCreateError, retry)
- Localize channel message input hint and audio upload error
* feat: unify channel input with ModernChatInput, add @model mentions
- Replace channel page's custom composer with shared ModernChatInput
for consistent UX (CupertinoTextField, expand modal, keyboard
shortcuts, prompt overlays, glass shell, light-mode shadow)
- Add @model mention support: type @ to search/select AI models
inline, with styled mention tokens (MentionTextEditingController)
- Add ModelSuggestionOverlay with model avatars, descriptions, and
current-model checkmark
- Channel overflow button uses AdaptivePopupMenuButton with native
platform menus (File, Photo, Camera) wired to FileAttachmentService
- Add overflowButtonBuilder to ModernChatInput for custom overflow
- Add placeholder param to ModernChatInput (channel uses "Type here...")
- Show muted send button when no voice call callback and no text
* fix: remove minimum width constraint from model selector pill
* fix: add missing Channel model fields for OpenWebUI parity
* fix: update ChannelMessage model and reactions to match OpenWebUI format
* fix: correct all channel API paths, params, and body fields for OpenWebUI parity
* fix: correct socket event parsing to unwrap nested OpenWebUI data envelope
The OpenWebUI backend wraps channel events in a nested structure where
the event type and payload live under event['data']['type'] and
event['data']['data']. The handler was reading event['type'] and
event['data'] directly, which meant no socket events were processed.
Also adds handling for message:reply, message:reaction:add/remove,
and typing events, plus emitLastReadAt/emitTyping methods and a
public emit() on SocketService.
* fix: use skip/limit pagination and inline unread counts from OpenWebUI
* fix: update channel page for grouped reactions, tempId, and leave via member status
* fix: pass channel type on create for OpenWebUI compatibility
* feat: emit last_read_at via socket when entering channel
* feat: add inline message editing in channel page
* feat: add message pinning/unpinning in channel page
* feat: add typing indicators for channels
* feat: add reply-to message UI in channel page
* feat: add thread panel for channel message threads
* feat: add member list sheet for channels
* feat: display DM and group channels with appropriate icons and names
* fix: defer socket subscribe to post-frame to avoid provider modification during build
* fix: convert @model mentions to OpenWebUI wire format (<@M:id|label>)
MentionTextController now tracks entity metadata (idType, id, label)
alongside each mention range. On send, toWireFormat() replaces display
text like @GPT-4 with <@M:gpt-4|GPT-4> so the backend's
extract_mentions() regex can find them and trigger model responses.
* fix: move GestureDetector inside FloatingAppBarPill for full hit area on members button
* fix: strip mention markup in message display and show model name/avatar for model responses
- Parse <@M:id|label> tags in message content → display as @label
- Check message.meta.model_id to show model name and robot icon
instead of the human sender's name/avatar for model responses
* fix: extract mention utils, apply styled mentions and model identity to thread panel
- Extract stripMentions, isModelMessage, messageDisplayName,
buildMentionSpan to shared mention_utils.dart
- Thread panel parent and replies now show model name + robot icon
for model responses instead of the human sender
- All message content uses RichText with styled @mention highlights
instead of plain text with raw <@M:id|label> markup
* fix: filter parent message from thread replies to avoid duplicate
* fix: show thread replies at top (oldest first, not reversed)
* fix: match channel message text styles to chat page
- Username: 14pt w500 textSecondary (was 13pt w600 textPrimary)
- Content: 16pt via AppTypography.chatMessageStyle (was 14pt)
- Timestamp: AppTypography.labelSmall (was hardcoded 11)
- Applied same styles to thread panel
* feat: use ModelAvatar and UserAvatar for channel message avatars
Replace hand-rolled CircleAvatar with the app's ModelAvatar and
UserAvatar widgets that handle cached network images, data URIs,
auth headers, and proper fallback UI. Model messages use the
/api/v1/models/model/profile/image endpoint. User messages resolve
profile_image_url via the standard user avatar utils. Applied to
both the channel page and thread panel.
* fix: match reply count and pinned indicator style to chat's detail header
Use AppTypography.bodyMedium at 0.6 alpha with chevron_right icon,
matching the AssistantDetailHeader style used for "thought for N"
in the chat page.
* feat: group consecutive messages from same sender, show avatar/name only once
* fix: add sufficient padding between last message and text input
* fix: left-align channel name pill beside hamburger, circular members button
- Channel name pill now left-aligned next to hamburger like the model
selector in chat page (using balanceLeading: false + Align)
- Members button uses FloatingAppBarPill(isCircular: true) matching
the triple-dot menu style, showing just the count number
* fix: use people icon only in circular members pill, show count in sheet
* fix: increase channel name pill padding to match chat model selector
* fix: add top padding to reply banner so it doesn't eat the message gap
* fix: add spacer between message list and input area for consistent gap
* feat: pass attachment button builder to thread panel input
* fix: resolve user avatar from profileImageUrl directly instead of Freezed object
* refactor(ui): replace generic add icon with context-specific icons
Add new dedicated icons for creating chats, notes, and channels to improve UI clarity. Update all references to use the new specific icons instead of the generic addIcon. Also refactor note editor typography styling and remove unused notes feature toggle from the drawer.
* feat(l10n): translate 35 missing strings across all 9 non-English locales
Add translations for 28 new channel/sidebar keys and translate 7
temporary-chat keys that were left in English (de, es, fr, it, ko,
nl, ru, zh, zh_Hant).
* fix: preserve sidebar across navigation on tablets with ShellRoute
The sidebar/drawer was being destroyed and recreated on every route
change because each page independently wrapped itself with
ResponsiveDrawerLayout + SidebarPage. Introduced a DrawerShellPage
inside a ShellRoute so the drawer stays mounted when switching between
chat, channels, and notes. Also fixed a crash where the
AnimationController was lazily created during dispose() on tablets
(moved to initState), and made sidebar close only on mobile — not
tablets — matching the existing chats behavior.
* fix: auto-close thread panel on channel switch and fix close button visibility
Add didUpdateWidget to reset thread/reply state and resubscribe to the
new channel's socket when navigating between channels. The subscribe
call is deferred with Future() to avoid modifying provider state during
the build phase. Also add top padding to the thread panel so its header
and close button are not hidden behind the floating app bar on tablets.
* refactor(ui): align floating app bar with sidebar tabs and unify sidebar icons
Reduce FloatingAppBar height from kToolbarHeight (56) to
kTextTabBarHeight (48) so the floating pills align vertically with the
sidebar tab bar on tablets. Update all scroll offset and padding
calculations across chat, channel, note, profile, and customization
pages to match. Also replace context-specific sidebar action icons
(chat bubble, doc, tag) with uniform plus icons.
- Updated ThemedDialogs to utilize AdaptiveAlertDialog for confirmation and input dialogs.
- Introduced NativeChatInput for platform-specific chat input handling on iOS and Android.
- Added StreamingTitleText widget for animated title display in chat.
- Implemented NativeGlassContainer for iOS glass effect with Flutter overlay.
- Created GlassColors utility for native system colors on glass surfaces.
- Added native chat input view factory for better integration with platform views.
- Updated pubspec.yaml and pubspec.lock to include adaptive_platform_ui dependency.
feat(navigation): migrate to super_drag_and_drop for folder drag and drop
feat(ui): Add context menu preview builders for chat and notes
refactor(ui): Remove preview builders and simplify note card rendering
- Revised the quick actions description in multiple languages to clarify their purpose as "Quickpills in chat."
- Adjusted the layout of AppCustomizationPage by reintroducing the quick pills section for improved user interaction.
- Modified spacing between UI elements for better visual consistency and usability.
- Streamlined the component structure to enhance maintainability and readability.
- Replaced references to AppColorPalettes with TweakcnThemes across various files to standardize theme usage.
- Updated the AppTheme and AppColorTokens to utilize TweakcnThemeDefinition for improved theme management.
- Adjusted UI components in ChatPage, ChatsDrawer, AppCustomizationPage, and ProfilePage to align with the new theme structure, ensuring consistent styling and color application.
- Removed the deprecated color_palettes.dart file to streamline the theme architecture.
- Updated error handling in EnhancedErrorService to utilize context for color tokens, improving theme consistency.
- Refactored various components to use context-aware shadow and color properties, enhancing visual coherence.
- Replaced hardcoded color values with dynamic tokens in multiple widgets, ensuring better adaptability to theme changes.
- Improved overall code maintainability by centralizing theme-related logic and reducing direct dependencies on static theme values.
- Introduced a new method `refreshConversationsCache` to streamline the invalidation of the conversations provider and optionally the folders provider.
- Updated various components to utilize the new cache management method, enhancing code clarity and reducing redundancy.
- This refactor improves the efficiency of conversation and folder synchronization across the application.