From b3a42fbcb7e1e150d2fe131eac8830ca8de633e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9=20=D0=95=D0=BB?= =?UTF-8?q?=D0=B8=D1=81=D0=B5=D0=B5=D0=B2?= Date: Tue, 26 May 2026 13:11:31 +0600 Subject: [PATCH 01/14] feat: update keyboard contoller lib and components --- apps/mobile/app/(main)/chat/[id].tsx | 87 +++++++++--------- .../chat/features/chat/src/lib/component.tsx | 88 +++++++++---------- .../chat-bottom-button/component.tsx | 2 +- .../components/messages-list/component.tsx | 15 ++-- libs/mobile/shared/ui/ui-kit/src/index.ts | 2 + .../keyboard-chat-scroll-view/component.tsx | 34 +++++++ .../src/keyboard-chat-scroll-view/index.ts | 1 + .../src/keyboard-sticky-view/component.tsx | 27 ++++++ .../ui-kit/src/keyboard-sticky-view/index.ts | 1 + 9 files changed, 157 insertions(+), 100 deletions(-) create mode 100644 libs/mobile/shared/ui/ui-kit/src/keyboard-chat-scroll-view/component.tsx create mode 100644 libs/mobile/shared/ui/ui-kit/src/keyboard-chat-scroll-view/index.ts create mode 100644 libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/component.tsx create mode 100644 libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/index.ts diff --git a/apps/mobile/app/(main)/chat/[id].tsx b/apps/mobile/app/(main)/chat/[id].tsx index 57ea1f5..b42b239 100644 --- a/apps/mobile/app/(main)/chat/[id].tsx +++ b/apps/mobile/app/(main)/chat/[id].tsx @@ -14,7 +14,6 @@ import { AppText, Icon, FullScreenSearchModal, - AppKeyboardControllerView, IconButton, } from '@open-webui-react-native/mobile/shared/ui/ui-kit'; import { @@ -65,50 +64,48 @@ export default function ChatScreen(): ReactElement { ); return ( - - - ) - } - onGoBack={handleGoBackPress} - accessoryRight={ - { - if (!chat) return; - chatActionsSheetRef.current?.present(chat); - }} + - } - /> - } - scrollDisabled> - - - - - + ) + } + onGoBack={handleGoBackPress} + accessoryRight={ + { + if (!chat) return; + chatActionsSheetRef.current?.present(chat); + }} + /> + } + /> + } + scrollDisabled> + + + + ); } diff --git a/libs/mobile/chat/features/chat/src/lib/component.tsx b/libs/mobile/chat/features/chat/src/lib/component.tsx index 1813a60..1c885f5 100644 --- a/libs/mobile/chat/features/chat/src/lib/component.tsx +++ b/libs/mobile/chat/features/chat/src/lib/component.tsx @@ -1,5 +1,4 @@ import { useSelector } from '@legendapp/state/react'; -import { useKeyboard } from '@react-native-community/hooks'; import { useTranslation } from '@ronas-it/react-native-common-modules/i18n'; import dayjs from 'dayjs'; import { delay } from 'lodash-es'; @@ -14,9 +13,8 @@ import { useSendMessage } from '@open-webui-react-native/mobile/chat/features/us import { useSuggestChange } from '@open-webui-react-native/mobile/chat/features/use-suggest-change'; import { useAttachedFiles } from '@open-webui-react-native/mobile/shared/features/use-attached-files'; import { cn } from '@open-webui-react-native/mobile/shared/ui/styles'; -import { AppSpinner, View } from '@open-webui-react-native/mobile/shared/ui/ui-kit'; +import { AppKeyboardStickyView, AppSpinner, View } from '@open-webui-react-native/mobile/shared/ui/ui-kit'; import { FormValues } from '@open-webui-react-native/mobile/shared/utils/form'; -import { useBottomInset } from '@open-webui-react-native/mobile/shared/utils/use-bottom-inset'; import { chatApi, ChatGenerationOption, chatQueriesKeys } from '@open-webui-react-native/shared/data-access/api'; import { Role } from '@open-webui-react-native/shared/data-access/common'; import { useSubscribeToQueryCache } from '@open-webui-react-native/shared/data-access/query-client'; @@ -38,8 +36,6 @@ interface ChatProps { export function Chat({ chatId, selectedModelId, isNewChat, resetToChatsList }: ChatProps): ReactElement { const translate = useTranslation('CHAT.CHAT'); const translateRegeneratePrompt = useTranslation('CHAT.AI_MESSAGE_ACTIONS.REGENERATE_MESSAGE_ACTION_SHEET'); - const bottomInset = useBottomInset(); - const { keyboardShown } = useKeyboard(); const [isInputFocusing, setIsInputFocusing] = useState(false); //NOTE: Needs to avoid ChatBottomButton jumping when auto-scrolling after focus @@ -225,47 +221,47 @@ export function Chat({ chatId, selectedModelId, isNewChat, resetToChatsList }: C /> )} - - {activeInputMode === ActiveInputMode.EDIT && editingMessageId ? ( - - ) : activeInputMode === ActiveInputMode.SUGGEST && suggestingMessageId ? ( - - ) : ( - - )} - + + + {activeInputMode === ActiveInputMode.EDIT && editingMessageId ? ( + + ) : activeInputMode === ActiveInputMode.SUGGEST && suggestingMessageId ? ( + + ) : ( + + )} + + ); } diff --git a/libs/mobile/chat/features/chat/src/lib/components/chat-bottom-button/component.tsx b/libs/mobile/chat/features/chat/src/lib/components/chat-bottom-button/component.tsx index 2ff66de..b3b71d9 100644 --- a/libs/mobile/chat/features/chat/src/lib/components/chat-bottom-button/component.tsx +++ b/libs/mobile/chat/features/chat/src/lib/components/chat-bottom-button/component.tsx @@ -13,7 +13,7 @@ export default function ChatBottomButton({ isVisible, onPress }: ChatBottomButto })); return ( - + , []); + const handleContentSizeChange = (): void => { //NOTE: Needs to wait until the initial scroll to the bottom or content generation finished and not show the ChatBottomButton before isScrollToBottomAvailable.current = false; @@ -89,11 +91,7 @@ export default function ChatMessagesList({ if (!isMessagesListLoaded && listRef.current && messages?.length > 0) { delay(() => { - listRef.current?.scrollToIndex({ - index: messages.length - 1, - animated: false, - viewPosition: 1, - }); + listRef.current?.scrollToEnd({ animated: false }); delay(onLayout, 125); }, 125); } @@ -261,7 +259,7 @@ export default function ChatMessagesList({ ref={listRef} - contentContainerClassName='pb-16 px-16' + contentContainerClassName='pb-[125] px-16' showsVerticalScrollIndicator={false} drawDistance={1500} //NOTE: Needs to avoid image jumping (while rerendering) when scrolling keyExtractor={(item) => item.id} @@ -272,6 +270,7 @@ export default function ChatMessagesList({ maintainVisibleContentPosition={{ startRenderingFromBottom: true, }} + renderScrollComponent={renderScrollComponent} onContentSizeChange={handleContentSizeChange} onScroll={handleScroll} onTouchStart={handleTouchStart} diff --git a/libs/mobile/shared/ui/ui-kit/src/index.ts b/libs/mobile/shared/ui/ui-kit/src/index.ts index 0e4305f..79bf826 100644 --- a/libs/mobile/shared/ui/ui-kit/src/index.ts +++ b/libs/mobile/shared/ui/ui-kit/src/index.ts @@ -39,6 +39,8 @@ export * from './header'; export * from './full-screen-modal'; export * from './sheet-header'; export * from './keyboard-aware-scroll-view'; +export * from './keyboard-chat-scroll-view'; +export * from './keyboard-sticky-view'; export * from './pressable-search-input'; export * from './full-screen-search-modal'; export * from './gesture-pressable-icon-button'; diff --git a/libs/mobile/shared/ui/ui-kit/src/keyboard-chat-scroll-view/component.tsx b/libs/mobile/shared/ui/ui-kit/src/keyboard-chat-scroll-view/component.tsx new file mode 100644 index 0000000..37ae2b7 --- /dev/null +++ b/libs/mobile/shared/ui/ui-kit/src/keyboard-chat-scroll-view/component.tsx @@ -0,0 +1,34 @@ +import { cssInterop } from 'nativewind'; +import { ReactElement } from 'react'; +import { KeyboardChatScrollView, KeyboardChatScrollViewProps } from 'react-native-keyboard-controller'; +import { cn } from '@open-webui-react-native/mobile/shared/ui/styles'; + +const CustomizedKeyboardChatScrollView = cssInterop(KeyboardChatScrollView, { + className: 'style', + contentContainerClassName: 'contentContainerStyle', +}); + +type AppKeyboardChatScrollViewProps = KeyboardChatScrollViewProps & { + className?: string; + contentContainerClassName?: string; +}; + +export function AppKeyboardChatScrollView({ + className, + contentContainerClassName, + offset = 20, + automaticallyAdjustContentInsets = false, + contentInsetAdjustmentBehavior = 'never', + ...restProps +}: AppKeyboardChatScrollViewProps): ReactElement { + return ( + + ); +} diff --git a/libs/mobile/shared/ui/ui-kit/src/keyboard-chat-scroll-view/index.ts b/libs/mobile/shared/ui/ui-kit/src/keyboard-chat-scroll-view/index.ts new file mode 100644 index 0000000..bb82484 --- /dev/null +++ b/libs/mobile/shared/ui/ui-kit/src/keyboard-chat-scroll-view/index.ts @@ -0,0 +1 @@ +export * from './component'; diff --git a/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/component.tsx b/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/component.tsx new file mode 100644 index 0000000..dc47a3e --- /dev/null +++ b/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/component.tsx @@ -0,0 +1,27 @@ +import { AppSafeAreaView } from '@ronas-it/react-native-common-modules/safe-area-view'; +import { PropsWithChildren, ReactElement } from 'react'; +import { KeyboardStickyView, KeyboardStickyViewProps } from 'react-native-keyboard-controller'; +import { cn } from '@open-webui-react-native/mobile/shared/ui/styles'; + +type AppKeyboardStickyViewProps = PropsWithChildren< + KeyboardStickyViewProps & { + className?: string; + } +>; + +export function AppKeyboardStickyView({ + className, + offset = { opened: 20, closed: 0 }, + style, + children, + ...restProps +}: AppKeyboardStickyViewProps): ReactElement { + return ( + + {children} + + ); +} diff --git a/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/index.ts b/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/index.ts new file mode 100644 index 0000000..bb82484 --- /dev/null +++ b/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/index.ts @@ -0,0 +1 @@ +export * from './component'; From dcb615ec8dbf27afa6bbd9512545a4b5dcf93dcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9=20=D0=95=D0=BB?= =?UTF-8?q?=D0=B8=D1=81=D0=B5=D0=B5=D0=B2?= Date: Tue, 26 May 2026 14:16:18 +0600 Subject: [PATCH 02/14] refactor: refactor app-keyboard-sticky-view --- .../chat/src/lib/components/messages-list/component.tsx | 2 +- .../shared/ui/ui-kit/src/keyboard-sticky-view/component.tsx | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libs/mobile/chat/features/chat/src/lib/components/messages-list/component.tsx b/libs/mobile/chat/features/chat/src/lib/components/messages-list/component.tsx index 7c023dd..deba083 100644 --- a/libs/mobile/chat/features/chat/src/lib/components/messages-list/component.tsx +++ b/libs/mobile/chat/features/chat/src/lib/components/messages-list/component.tsx @@ -259,7 +259,7 @@ export default function ChatMessagesList({ ref={listRef} - contentContainerClassName='pb-[125] px-16' + contentContainerClassName='pb-[135] px-16' showsVerticalScrollIndicator={false} drawDistance={1500} //NOTE: Needs to avoid image jumping (while rerendering) when scrolling keyExtractor={(item) => item.id} diff --git a/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/component.tsx b/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/component.tsx index dc47a3e..82cd983 100644 --- a/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/component.tsx +++ b/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/component.tsx @@ -1,11 +1,13 @@ import { AppSafeAreaView } from '@ronas-it/react-native-common-modules/safe-area-view'; import { PropsWithChildren, ReactElement } from 'react'; import { KeyboardStickyView, KeyboardStickyViewProps } from 'react-native-keyboard-controller'; +import { Edge } from 'react-native-safe-area-context'; import { cn } from '@open-webui-react-native/mobile/shared/ui/styles'; type AppKeyboardStickyViewProps = PropsWithChildren< KeyboardStickyViewProps & { className?: string; + safeAreaEdges: Array; } >; @@ -14,6 +16,7 @@ export function AppKeyboardStickyView({ offset = { opened: 20, closed: 0 }, style, children, + safeAreaEdges = ['bottom'], ...restProps }: AppKeyboardStickyViewProps): ReactElement { return ( @@ -21,7 +24,7 @@ export function AppKeyboardStickyView({ offset={offset} className={cn('absolute bottom-0 left-0 right-0 w-full', className)} {...restProps}> - {children} + {children} ); } From ee37841e7c01493a95e58b03e98192a2e35f6d15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9=20=D0=95=D0=BB?= =?UTF-8?q?=D0=B8=D1=81=D0=B5=D0=B5=D0=B2?= Date: Tue, 26 May 2026 16:43:44 +0600 Subject: [PATCH 03/14] fix: fix lint error --- .../shared/ui/ui-kit/src/keyboard-sticky-view/component.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/component.tsx b/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/component.tsx index 82cd983..c5a2860 100644 --- a/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/component.tsx +++ b/libs/mobile/shared/ui/ui-kit/src/keyboard-sticky-view/component.tsx @@ -7,7 +7,7 @@ import { cn } from '@open-webui-react-native/mobile/shared/ui/styles'; type AppKeyboardStickyViewProps = PropsWithChildren< KeyboardStickyViewProps & { className?: string; - safeAreaEdges: Array; + safeAreaEdges?: Array; } >; From 84dd77714b099dde3e34d21d88bb0f7387509685 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9=20=D0=95=D0=BB?= =?UTF-8?q?=D0=B8=D1=81=D0=B5=D0=B5=D0=B2?= Date: Tue, 26 May 2026 16:48:10 +0600 Subject: [PATCH 04/14] fix: fix react-native-keyboard-controller version --- apps/mobile/package.json | 2 +- package-lock.json | 10 +++++----- package.json | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/apps/mobile/package.json b/apps/mobile/package.json index a994a1a..dda6470 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -71,7 +71,7 @@ "react-native-compressor": "^1.12.0", "react-native-extended-stylesheet": "^0.12.0", "react-native-gesture-handler": "~2.28.0", - "react-native-keyboard-controller": "1.18.5", + "react-native-keyboard-controller": "1.21.8", "react-native-mmkv": "^3.2.0", "react-native-modal": "^14.0.0-rc.1", "react-native-reanimated": "~4.1.1", diff --git a/package-lock.json b/package-lock.json index bfdd980..bacde44 100644 --- a/package-lock.json +++ b/package-lock.json @@ -80,7 +80,7 @@ "react-native-compressor": "^1.12.0", "react-native-extended-stylesheet": "^0.12.0", "react-native-gesture-handler": "~2.28.0", - "react-native-keyboard-controller": "1.18.5", + "react-native-keyboard-controller": "1.21.8", "react-native-markdown-display": "^7.0.2", "react-native-mathjax-svg": "^0.9.9", "react-native-mmkv": "^3.2.0", @@ -208,7 +208,7 @@ "react-native-compressor": "^1.12.0", "react-native-extended-stylesheet": "^0.12.0", "react-native-gesture-handler": "~2.28.0", - "react-native-keyboard-controller": "1.18.5", + "react-native-keyboard-controller": "1.21.8", "react-native-mmkv": "^3.2.0", "react-native-modal": "^14.0.0-rc.1", "react-native-reanimated": "~4.1.1", @@ -27309,9 +27309,9 @@ } }, "node_modules/react-native-keyboard-controller": { - "version": "1.18.5", - "resolved": "https://registry.npmjs.org/react-native-keyboard-controller/-/react-native-keyboard-controller-1.18.5.tgz", - "integrity": "sha512-wbYN6Tcu3G5a05dhRYBgjgd74KqoYWuUmroLpigRg9cXy5uYo7prTMIvMgvLtARQtUF7BOtFggUnzgoBOgk0TQ==", + "version": "1.21.8", + "resolved": "https://registry.npmjs.org/react-native-keyboard-controller/-/react-native-keyboard-controller-1.21.8.tgz", + "integrity": "sha512-fPpRb1DkG0mgjNdsVvwKTeEqbTdUymZ7ZEqe5kXPEhEjnvo+3BX3p4CBhg3dEzfonL/hGGSS1dBDMDjiQbAkBQ==", "license": "MIT", "dependencies": { "react-native-is-edge-to-edge": "^1.2.1" diff --git a/package.json b/package.json index ce71fd6..a5b795e 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "react-native-compressor": "^1.12.0", "react-native-extended-stylesheet": "^0.12.0", "react-native-gesture-handler": "~2.28.0", - "react-native-keyboard-controller": "1.18.5", + "react-native-keyboard-controller": "1.21.8", "react-native-markdown-display": "^7.0.2", "react-native-mathjax-svg": "^0.9.9", "react-native-mmkv": "^3.2.0", From decf6be0725b22d6df2a3d48153dc43a2bf911b7 Mon Sep 17 00:00:00 2001 From: Ilya Pakhomov Date: Mon, 1 Jun 2026 22:04:23 +0600 Subject: [PATCH 05/14] docs: updated issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 35 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 26 +++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..55a8d38 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,35 @@ +--- +name: Bug report +about: Create a report to help us improve Open MobileUI +title: "[BUG]" +labels: bug, for review +assignees: ipakhomov + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Press on '....' +3. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Versions** + - Open MobileUI app version: [e.g. v1.5.0] + - Open WebUI API version: [e.g. v0.7.2] + +**Platform** + - Device: [e.g. iPhone 15] + - OS: [e.g. iOS 26.1] + + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..b138634 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,26 @@ +--- +name: Feature request +about: Suggest an idea to enhance Open MobileUI +title: "[FEATURE]" +labels: enhancement, for review +assignees: ipakhomov + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Does this feature available in Open WebUI?** +Describe whether there is an existing feature in Open WebUI for web. + +**Why is this feature important to you?** +Describe, how much would it enhance your experience. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From aa8a43d98b7b9734d933416f3c935bbbaee707ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9=20=D0=95=D0=BB?= =?UTF-8?q?=D0=B8=D1=81=D0=B5=D0=B5=D0=B2?= Date: Tue, 2 Jun 2026 10:18:09 +0600 Subject: [PATCH 06/14] feat: add contributing.md --- CONTRIBUTING.md | 99 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 96 +---------------------------------------------- 2 files changed, 101 insertions(+), 94 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..34e9481 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,99 @@ +# Contributing to Open MobileUI + +Thanks for your interest in improving Open MobileUI! Bug fixes, new features, documentation, UI/UX polish, performance work, and translations are all welcome. + +## Ways to contribute + +- 🐛 **Bug fixes** — help us squash bugs and improve stability +- ✨ **Features** — propose and build new functionality +- 📝 **Documentation** — improve docs, add examples, fix typos +- 🎨 **UI/UX** — refine the mobile experience +- ⚡ **Performance** — optimize rendering and app responsiveness +- 🌍 **Internationalization** — add translations for new languages + +## Reporting issues + +Before opening an issue, please [search existing issues](https://github.com/RonasIT/open-webui-react-native/issues) to avoid duplicates. + +When [filing a new issue](https://github.com/RonasIT/open-webui-react-native/issues/new), include as much as applies: + +- **What happened** vs. **what you expected** +- **Steps to reproduce** (the more precise, the better) +- **Environment** — app version, device + OS version, and your Open WebUI version +- **Screenshots or logs** where relevant + +For feature requests, describe the use case and the problem it solves — not just the proposed solution. + +## Development setup + +### Prerequisites + +- **Node.js** 18+ and npm +- **iOS:** Xcode 14+ (macOS only) +- **Android:** Android Studio with the Android SDK + +### Clone and install + +```bash +git clone https://github.com/RonasIT/open-webui-react-native.git +cd open-webui-react-native +npm install +``` + +### Run the app + +```bash +# Start the Metro bundler (development env) +npx nx start mobile + +# Or run directly on a device/emulator (from apps/mobile) +npm run android +npm run ios +``` + +Running on a device/emulator requires a **development build**. Follow the +[Expo development builds guide](https://docs.expo.dev/develop/development-builds/create-a-build/) +to create one (a one-time setup), then start the bundler as above. + +### Configure your own Expo project (for builds) + +To create your own builds you'll need an Expo project of your own: + +1. Create an account at [expo.dev](https://expo.dev/) and a new project. +2. Note your project `slug`, `owner`, and `project ID`. +3. Provide your project details via environment variables / app config used by + [`apps/mobile/app.config.ts`](apps/mobile/app.config.ts) (e.g. `EXPO_PUBLIC_APP_NAME`, + `EXPO_PUBLIC_APP_SLUG`, `EXPO_PUBLIC_APP_OWNER`, `EXPO_PUBLIC_PROJECT_ID`). +4. For production builds, configure [`eas.json`](eas.json) following the + [EAS configuration guide](https://docs.expo.dev/eas/json/). + +### Common commands + +```bash +npm run lint # tsc + eslint +npm run format # prettier + eslint --fix +npx nx test mobile # run the mobile test suite +``` + +See the root [CLAUDE.md](CLAUDE.md) and `README.md` for more on the monorepo architecture and library structure. + +## Submitting a pull request + +1. **Fork** the repository and create a feature branch off `main`. +2. Make your changes, keeping commits focused and following the existing code style. +3. **Run `npm run lint`** and the relevant tests — make sure everything passes. +4. **Open a pull request** against `main` with a clear description of _what_ changed and _why_. Link any related issue. +5. Be ready to iterate on review feedback. + +For larger changes, please open an issue to discuss the approach first — it saves everyone time. + +## Helpful resources + +- 📖 [Expo development builds](https://docs.expo.dev/develop/development-builds/create-a-build/) +- 📦 [EAS Build documentation](https://docs.expo.dev/build/setup/) +- ⚙️ [Expo configuration reference](https://docs.expo.dev/workflow/configuration/) +- 🏗️ [Nx documentation](https://nx.dev/getting-started/intro) + +--- + +By contributing, you agree that your contributions will be licensed under the project's [GPL v3 license](LICENSE). diff --git a/README.md b/README.md index 39581fb..e5c3c98 100644 --- a/README.md +++ b/README.md @@ -147,105 +147,13 @@ The codebase follows a modular, scalable architecture: ### Building from Source -#### Prerequisites - -- **Node.js** 18+ and npm -- **Expo CLI** – `npm install -g expo-cli` -- **EAS CLI** (for builds) – `npm install -g eas-cli` -- **iOS Development**: Xcode 14+ (macOS only) -- **Android Development**: Android Studio with Android SDK - -#### Step-by-Step Setup - -1. **Clone the Repository** - -```bash -git clone https://github.com/RonasIT/open-webui-react-native.git -cd open-webui-react-native -``` - -2. **Install Dependencies** - -```bash -npm install -``` - -3. **Configure Expo Project** - -- Create an account at [expo.dev](https://expo.dev/) if you don't have one -- Create a new project or use an existing one -- Note your project details: `slug`, `owner`, `project ID` - -4. **Configure App Settings** - -Edit `app.config.js` (or `app.config.ts`) with your project details: - -```javascript -{ - name: "Your App Name", - slug: "your-app-slug", - owner: "your-expo-username", - version: "1.0.0" - // ... additional configuration -} -``` - -5. **Set Up EAS Build** (Optional, for production builds) - -- Create `eas.json` following the [EAS Configuration Guide](https://docs.expo.dev/eas/json/) -- Configure build profiles, app IDs, and credentials - -6. **Start Development** - -For development builds: - -```bash -# Create a development build first (one-time setup) -# Follow: https://docs.expo.dev/develop/development-builds/create-a-build/ - -# Then start the Metro bundler -npm start -``` - -For production builds: - -```bash -npm run build:prod -``` - -### Development Resources - -- 📖 [Expo Development Builds Guide](https://docs.expo.dev/develop/development-builds/create-a-build/) -- 📦 [EAS Build Documentation](https://docs.expo.dev/build/setup/) -- ⚙️ [Expo Configuration Reference](https://docs.expo.dev/workflow/configuration/) -- 🏗️ [Nx Documentation](https://nx.dev/getting-started/intro) +For detailed setup instructions — prerequisites, cloning, configuring your own Expo project, and running the app — see the [Contributing guide](CONTRIBUTING.md#development-setup). ## 🤝 Contributing We welcome and appreciate contributions from the community! Whether you're fixing bugs, adding features, or improving documentation, your help makes this project better. -### How to Contribute - -1. **Fork the Repository** – Create your own fork of the project -2. **Create a Branch** – Make your changes in a feature branch -3. **Follow Guidelines** – Adhere to our code style and commit conventions -4. **Test Your Changes** – Ensure your changes work correctly -5. **Submit a Pull Request** – Open a PR with a clear description of your changes - -### Contribution Areas - -- 🐛 **Bug Fixes** – Help us squash bugs and improve stability -- ✨ **New Features** – Propose and implement new functionality -- 📝 **Documentation** – Improve docs, add examples, or fix typos -- 🎨 **UI/UX Improvements** – Enhance the user experience -- ⚡ **Performance** – Optimize code and improve app performance -- 🌍 **Internationalization** – Add translations for new languages - -### Getting Help - -- 📋 **Report Issues** – Use [GitHub Issues](https://github.com/RonasIT/open-webui-react-native/issues) for bug reports -- 💬 **Discussions** – Join [Open WebUI Discussions](https://github.com/open-webui/open-webui/discussions) for questions -- 📧 **Contact** – Reach out to [Ronas IT](https://ronasit.com) for enterprise support +See [CONTRIBUTING.md](CONTRIBUTING.md) for how to report issues, set up your development environment, and submit a pull request. --- From 13842718444c44dd59349589afc2e1e06856e8c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9=20=D0=95=D0=BB?= =?UTF-8?q?=D0=B8=D1=81=D0=B5=D0=B5=D0=B2?= Date: Tue, 2 Jun 2026 10:25:00 +0600 Subject: [PATCH 07/14] feat: add store links to readme --- README.md | 16 ++++++++++++++-- docs/images/logo.png | Bin 0 -> 19750 bytes 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 docs/images/logo.png diff --git a/README.md b/README.md index e5c3c98..ff9dc18 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ -# Open MobileUI -
+Open MobileUI logo + +# Open MobileUI + ![License](https://img.shields.io/badge/license-GPL%20v3-blue.svg) ![Platform](https://img.shields.io/badge/platform-iOS%20%7C%20Android-lightgrey.svg) ![React Native](https://img.shields.io/badge/React%20Native-0.79-blue.svg) @@ -11,6 +13,16 @@ [Features](#features) • [Installation](#installation) • [Development](#development) • [Support](#support) • [Privacy Policy](PRIVACY_POLICY.md) +
+ + + Download on the App Store + +   + + Get it on Google Play + +
--- diff --git a/docs/images/logo.png b/docs/images/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e62c1794933b548fa6547bd87e981173403d9475 GIT binary patch literal 19750 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 Date: Tue, 2 Jun 2026 10:35:21 +0600 Subject: [PATCH 08/14] refactor: update stores images --- README.md | 4 ++-- docs/images/app-store.png | Bin 0 -> 5296 bytes docs/images/google-play.png | Bin 0 -> 10382 bytes 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 docs/images/app-store.png create mode 100644 docs/images/google-play.png diff --git a/README.md b/README.md index ff9dc18..7c7b6fb 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,11 @@
- Download on the App Store + Download on the App Store    - Get it on Google Play + Get it on Google Play diff --git a/docs/images/app-store.png b/docs/images/app-store.png new file mode 100644 index 0000000000000000000000000000000000000000..52d3fb93591d1361c188d98c902793e886ec94a1 GIT binary patch literal 5296 zcmV;h6i@3?Nk&Gf6aWBMMM6+kP&iDS6aWA(bpam`wRpq!f05Jv|FXf|idAq8l)B+9 z?he5%P{&G;zDK$w~w<#>M05j&%9L`}YJEx-VYd~dl-8|{ zD|Nzd%SI_}L|akMVB38*&$Vi0gIh~QhZ*~ZM^sgd5Dpe_NCNNo}jeTkEqTnU3`FiTexv< z=Mc@BaKR83n+qr|x~+lVd595|_TvdM=;Sj1TCz$aB!7?+LuxHtN(G)~7^VGsfJ&Bv z*qDX(*vjYI0RRrUTg>PIKy998D5d>JyEJBq0`fK%>V}y)uO8L_{EhvOHiS~qEv@H) zJ}48bG3T@Zutjz{N2=FHg;|8E1? z$du4Zh(>Zd>^Qs(x?f}K@r5;j{)m*mHUWTNv>?<0j3r#d1wSKJ!z#@D3PkXaaR`9D z1~THm%Q^tCMn^hDye<*|Y}SWPUB3Yk_na(DsN^dEu-img5uE{z)Upu(yevDZ{{r0t zl``2O0JiBu=O&*4fY{k`In49|{b8a5_XK=O$l!I*9fz4S+6xN^0{~G9V&;p$6R7)v z?nN$T9_T*CK`3NB7u|n|W@16U<6lEvB!m7=UON5k1MFbV8qG&T!7;M7R%wV zQl3}On^&~R1K1-FGtU70qJ;vka+j@u&Y1Z<*eg9|RscF+=C*(&0*5S6T^UV$3)m(z zsZhWg?G$u{u2O*Bgy#XXl$KV0y(HsIHq3l{GvEu2lu%6=BpazH83&A1QeHKD4p0tM z^50ICQr$D60QJdSucoV1KjIfu=F%47=I54#k@ z%zU*2Tz1HgnFpF+1cw03{1l)jX7&MJxx~!;7#Aa-0lHyk&g3URebf#YnVIJUrjTKN z08kr~YXIXhGZ(N6PysWC13F=5PHzbu&*v~wR0O?E@{1_+tkyOYla!I*gimnc~foNAyA;6+Rp1^j|a zCT;;d%)Gw@AZG$9V!j6Oy`IP^fVjiR=k%uIXmTO~mSg7k0Y|6~fQgv-S=hvZzk~Mp z3+RLE0xB{vhJkQEHB>{ulbAVB@*7fW@LodB7_; zdPcMB3Hv>#5RNVm4*@pGjG6lYoFj}Z(mM>@Ea@j%Zz0>BFF9uDS${bp*axhEyVUk@{v76}K0 zs-&`kwn(NjSiuFGjMd&COS!CPq_C}kw{_IOa2o*+WB0TI>@-eKC7E)$L>IiFf$Q8M z4DdMz&y`VY&sgRl0Kb~8u5_eI8|_>�ZN`bqj0gZ`TLwjuZvtJ}ohs)@k5n%*+M& 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 Cu)zla literal 0 HcmV?d00001 diff --git a/docs/images/google-play.png b/docs/images/google-play.png new file mode 100644 index 0000000000000000000000000000000000000000..1890fd1b953ed52f80cafb79f51d4d0257d61e5d GIT binary patch literal 10382 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 literal 0 HcmV?d00001 From 8f27aa4eacb4c28b7a57e7824ad9ae11eabc4e4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9=20=D0=95=D0=BB?= =?UTF-8?q?=D0=B8=D1=81=D0=B5=D0=B5=D0=B2?= Date: Tue, 2 Jun 2026 10:48:14 +0600 Subject: [PATCH 09/14] feat: add coming soon section to readme --- README.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7c7b6fb..4efa73e 100644 --- a/README.md +++ b/README.md @@ -71,13 +71,10 @@ While Open WebUI works in mobile browsers, Open MobileUI provides: - 🌙 **Dark Mode** – System-aware theme support for comfortable viewing in any lighting - ⌨️ **Keyboard Optimization** – Intelligent keyboard handling and input management -### Enterprise Features +### Coming Soon -- 🏢 **Self-Hosted Ready** – Connect to your private Open WebUI deployment -- 🔐 **Security First** – Secure credential storage, encrypted connections, and privacy-focused architecture -- 📊 **Offline Mode** – Graceful handling of network interruptions -- 🔔 **Real-time Updates** – Live notifications and instant message delivery -- 🌍 **Internationalization** – Multi-language support (coming soon) +- 🌍 **Internationalization** – Multi-language support +- 🎙️ **Voice Mode** – Hands-free voice input --- From 597dd99d92f0669b001e85a8a36b64e3b005518b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9=20=D0=95=D0=BB?= =?UTF-8?q?=D0=B8=D1=81=D0=B5=D0=B5=D0=B2?= Date: Tue, 2 Jun 2026 10:57:53 +0600 Subject: [PATCH 10/14] refactor: remove duplicated content form readme --- README.md | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 4efa73e..6b34a00 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ While Open WebUI works in mobile browsers, Open MobileUI provides: - ✅ **Multi-Model Support** – Switch between different AI models seamlessly - ✅ **Chat Management** – Organize conversations with folders, search, and archive functionality - ✅ **Authentication** – Email/password and Google Sign-In support (requires additional setup) -- ✅ **Secure Connections** – Supports encrypted HTTPS/WSS connections to your self-hosted Open WebUI instance (use HTTPS URLs for encrypted communication) +- ✅ **Secure Connections** – Encrypted HTTPS/WSS connections to your self-hosted Open WebUI instance ### Mobile-Optimized Experience @@ -80,24 +80,9 @@ While Open WebUI works in mobile browsers, Open MobileUI provides: ## 🎯 Use Cases -### For Individuals - -- **On-the-Go AI Assistant** – Access your personal AI assistant from anywhere -- **Mobile Productivity** – Get instant answers and assistance without opening a laptop -- **Privacy-Conscious Users** – Keep your conversations private with self-hosted infrastructure - -### For Businesses - -- **Team Collaboration** – Enable your team to access company AI assistants from mobile devices -- **Field Operations** – Support remote workers and field teams with mobile AI access -- **Cost Efficiency** – Leverage self-hosted infrastructure without per-user mobile app licensing fees -- **Enterprise Security** – Maintain full control over data and conversations with on-premise deployment - -### For Developers - -- **Open Source Alternative** – Professional-grade mobile client for the Open WebUI ecosystem -- **Reference Implementation** – Well-architected React Native codebase using modern best practices -- **Extensible Platform** – Built with modular architecture for easy customization and extension +- **Individuals** – An on-the-go AI assistant for instant answers without reaching for a laptop +- **Businesses** – Mobile access to company AI assistants for teams and field workers, with no per-user app licensing fees +- **Developers** – A well-architected, extensible React Native reference client for the Open WebUI ecosystem ## 📥 Installation @@ -192,17 +177,11 @@ For businesses requiring professional support, custom development, or enterprise ### Frequently Asked Questions **Q: Is this app free to use?** -A: Yes! This is an open-source project released under the GNU General Public License v3 (GPL v3). You are free to use, modify, and distribute it under the terms of the GPL v3. +A: Yes — it's open source under GPL v3. Commercial use is allowed; see [License](#license) for the terms. **Q: Do I need to host my own Open WebUI instance?** A: Yes, this app connects to your self-hosted Open WebUI deployment. See [Open WebUI Installation](https://docs.openwebui.com/) for setup instructions. -**Q: Is my data secure?** -A: Absolutely. All connections are encrypted, and your data stays on your self-hosted instance. The app never stores or transmits your conversations to third parties. For detailed information about data handling, see our [Privacy Policy](PRIVACY_POLICY.md). - -**Q: Can I use this for commercial purposes?** -A: Yes, GPL v3 allows commercial use. However, if you distribute the software (or modified versions), you must also provide the source code and license your modifications under GPL v3. See the [LICENSE](LICENSE.txt) file for complete terms. - **Q: How do I report a security vulnerability?** A: Please email security concerns directly to our team through [Ronas IT](https://ronasit.com) rather than opening a public issue. From 5f5123cf372c3bba4c6a2cac01f90ef197123fbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9=20=D0=95=D0=BB?= =?UTF-8?q?=D0=B8=D1=81=D0=B5=D0=B5=D0=B2?= Date: Tue, 2 Jun 2026 12:41:45 +0600 Subject: [PATCH 11/14] refactor: update installation section in readme --- README.md | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 6b34a00..9f204cc 100644 --- a/README.md +++ b/README.md @@ -86,24 +86,15 @@ While Open WebUI works in mobile browsers, Open MobileUI provides: ## 📥 Installation -### Quick Start - -Get started in minutes with pre-built releases or build from source. - -### Option 1: Download Pre-built App (Recommended) - -#### Android - -1. Download the latest `.apk` file from [GitHub Releases](https://github.com/RonasIT/open-webui-react-native/releases) -2. Enable "Install from Unknown Sources" in your Android device settings -3. Install the APK file -4. Launch the app and enter your Open WebUI instance URL - -#### iOS +### First-Time Setup -iOS builds are available through TestFlight or App Store (coming soon). Check [Releases](https://github.com/RonasIT/open-webui-react-native/releases) for TestFlight links. +1. **Install the App** – Download Open MobileUI from the [App Store](https://apps.apple.com/us/app/open-mobileui/id6754266176) or [Google Play](https://play.google.com/store/apps/details?id=com.open.web.ui) +2. **Launch the App** – Open the installed application +3. **Enter Server URL** – Provide your Open WebUI instance URL (e.g., `https://your-instance.com`) +4. **Authenticate** – Sign in with your Open WebUI credentials (email/password) +5. **Start Chatting** – You're ready to use your AI assistant on mobile! -### Option 2: Build from Source +### Build from Source See the [Development](#development) section below for detailed build instructions. @@ -113,13 +104,6 @@ See the [Development](#development) section below for detailed build instruction - **Android**: Android 8.0 (API level 26) or higher - **iOS**: iOS 13 or higher -### First-Time Setup - -1. **Launch the App** – Open the installed application -2. **Enter Server URL** – Provide your Open WebUI instance URL (e.g., `https://your-instance.com`) -3. **Authenticate** – Sign in with your Open WebUI credentials (email/password) -4. **Start Chatting** – You're ready to use your AI assistant on mobile! - ## 🛠️ Development ### Tech Stack From 9e70dbf74838e338b561a84ea1cf32c43c30f400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9=20=D0=95=D0=BB?= =?UTF-8?q?=D0=B8=D1=81=D0=B5=D0=B5=D0=B2?= Date: Tue, 2 Jun 2026 12:49:06 +0600 Subject: [PATCH 12/14] refactor: remove duplication build from source section --- README.md | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 9f204cc..1612034 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ **Professional mobile client for Open WebUI** – Access your self-hosted AI assistant anywhere, anytime -[Features](#features) • [Installation](#installation) • [Development](#development) • [Support](#support) • [Privacy Policy](PRIVACY_POLICY.md) +[Features](#-features) • [Installation](#-installation) • [Development](#️-development) • [Support](#-support) • [Privacy Policy](PRIVACY_POLICY.md)
@@ -86,24 +86,12 @@ While Open WebUI works in mobile browsers, Open MobileUI provides: ## 📥 Installation -### First-Time Setup - 1. **Install the App** – Download Open MobileUI from the [App Store](https://apps.apple.com/us/app/open-mobileui/id6754266176) or [Google Play](https://play.google.com/store/apps/details?id=com.open.web.ui) 2. **Launch the App** – Open the installed application 3. **Enter Server URL** – Provide your Open WebUI instance URL (e.g., `https://your-instance.com`) 4. **Authenticate** – Sign in with your Open WebUI credentials (email/password) 5. **Start Chatting** – You're ready to use your AI assistant on mobile! -### Build from Source - -See the [Development](#development) section below for detailed build instructions. - -### System Requirements - -- **Open WebUI**: active instance with accessible URL -- **Android**: Android 8.0 (API level 26) or higher -- **iOS**: iOS 13 or higher - ## 🛠️ Development ### Tech Stack @@ -161,7 +149,7 @@ For businesses requiring professional support, custom development, or enterprise ### Frequently Asked Questions **Q: Is this app free to use?** -A: Yes — it's open source under GPL v3. Commercial use is allowed; see [License](#license) for the terms. +A: Yes — it's open source under GPL v3. Commercial use is allowed; see [License](#-license) for the terms. **Q: Do I need to host my own Open WebUI instance?** A: Yes, this app connects to your self-hosted Open WebUI deployment. See [Open WebUI Installation](https://docs.openwebui.com/) for setup instructions. From b311d3ac6e2d598d97cad3fc370fd71d903022ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9=20=D0=95=D0=BB?= =?UTF-8?q?=D0=B8=D1=81=D0=B5=D0=B5=D0=B2?= Date: Tue, 2 Jun 2026 13:11:27 +0600 Subject: [PATCH 13/14] chore: pull issue template --- .github/ISSUE_TEMPLATE/bug_report.md | 36 +++++++++++++++++++++++ .github/ISSUE_TEMPLATE/feature_request.md | 25 ++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..ef0e9b6 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,36 @@ +--- +name: Bug report +about: Create a report to help us improve Open MobileUI +title: '[BUG]' +labels: bug, for review +assignees: ipakhomov +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: + +1. Go to '...' +2. Press on '....' +3. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Versions** + +- Open MobileUI app version: [e.g. v1.5.0] +- Open WebUI API version: [e.g. v0.7.2] + +**Platform** + +- Device: [e.g. iPhone 15] +- OS: [e.g. iOS 26.1] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..34b4650 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,25 @@ +--- +name: Feature request +about: Suggest an idea to enhance Open MobileUI +title: '[FEATURE]' +labels: enhancement, for review +assignees: ipakhomov +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Does this feature available in Open WebUI?** +Describe whether there is an existing feature in Open WebUI for web. + +**Why is this feature important to you?** +Describe, how much would it enhance your experience. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. From b2bbfe1fd37a015ef2275f6f02927f8af34eff67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B0=D1=81=D0=B8=D0=BB=D0=B8=D0=B9=20=D0=95=D0=BB?= =?UTF-8?q?=D0=B8=D1=81=D0=B5=D0=B5=D0=B2?= Date: Tue, 2 Jun 2026 13:15:39 +0600 Subject: [PATCH 14/14] chore: update contributing md with issue template --- CONTRIBUTING.md | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 34e9481..e86352e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,14 +15,10 @@ Thanks for your interest in improving Open MobileUI! Bug fixes, new features, do Before opening an issue, please [search existing issues](https://github.com/RonasIT/open-webui-react-native/issues) to avoid duplicates. -When [filing a new issue](https://github.com/RonasIT/open-webui-react-native/issues/new), include as much as applies: +When [filing a new issue](https://github.com/RonasIT/open-webui-react-native/issues/new/choose), pick the template that fits: -- **What happened** vs. **what you expected** -- **Steps to reproduce** (the more precise, the better) -- **Environment** — app version, device + OS version, and your Open WebUI version -- **Screenshots or logs** where relevant - -For feature requests, describe the use case and the problem it solves — not just the proposed solution. +- 🐛 **Bug report** — for something that's broken. Fill in what happened vs. what you expected, precise steps to reproduce, the app + Open WebUI versions, your device + OS, and screenshots where relevant. +- ✨ **Feature request** — for new functionality. Describe the use case and the problem it solves, not just the proposed solution. ## Development setup