Skip to content

Refactor & Use new data structures #194

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 73 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
89f5108
Update ktor library to 3.0 and update SSE method to native
Taewan-P Oct 26, 2024
9ae36c3
Merge remote-tracking branch 'origin/main' into refactor/ktor-3.0-mig…
Taewan-P Nov 23, 2024
0dffff5
Replace SSE function to library native function
Taewan-P Nov 23, 2024
dea38f2
Remove unused function
Taewan-P Nov 23, 2024
3be0660
Update Ktor to latest version
Taewan-P Nov 23, 2024
70b806f
Update OpenAI library version
Taewan-P Nov 23, 2024
e889aa0
Added translation using Weblate (German)
Jan 18, 2025
07546a5
Translated using Weblate (German)
Jan 18, 2025
bbbf43a
allow empty textFieldPrompt token customModel
rhjdvsgsgks Jan 26, 2025
cf778ed
fix on customSelected
rhjdvsgsgks Jan 26, 2025
509cbff
also skip isNotBlank in SettingViewModel
rhjdvsgsgks Jan 26, 2025
a99604a
fix empty string on token
rhjdvsgsgks Jan 26, 2025
af26176
missing bracket
rhjdvsgsgks Jan 26, 2025
ac4ff78
disable system prompt only if user set it to empty explicitly
rhjdvsgsgks Jan 26, 2025
1ba50d8
if null use default prompt
rhjdvsgsgks Jan 26, 2025
3fe448d
Update dependencies
Taewan-P Jan 27, 2025
971da80
Migrate current database to index foreign key
Taewan-P Jan 28, 2025
32f2e15
Add new redesign database
Taewan-P Jan 28, 2025
53fa96c
Move PlatformV2 to store in db
Taewan-P Jan 29, 2025
41726da
Add migrate platform logic to setting repository
Taewan-P Jan 30, 2025
761ef3e
Merge pull request #175 from rhjdvsgsgks/patch-1
Taewan-P Jan 31, 2025
3894a37
Merge pull request #166 from weblate/weblate-gptmobile-gptmobile
Taewan-P Feb 1, 2025
32f3322
Merge branch 'refactor/complete-redesign' into refactor/ktor-3.0-migr…
Taewan-P Feb 3, 2025
677e4e3
Merge pull request #83 from Taewan-P/refactor/ktor-3.0-migration
Taewan-P Feb 3, 2025
4eb6b6f
Update dependencies to latest version
Taewan-P Feb 3, 2025
0062d38
Implement migration functions
Taewan-P Feb 4, 2025
504d59f
Use new database file due to migration error
Taewan-P Feb 25, 2025
ad0140d
Add temporary migration screen
Taewan-P Feb 25, 2025
97a8c30
Route to migration screen in MainActivity
Taewan-P Feb 25, 2025
623628c
Complete migration screen UI
Taewan-P Feb 25, 2025
482074d
Remove migration page from backstack when finished
Taewan-P Feb 25, 2025
0ee1181
Set migration card height to auto
Taewan-P Feb 25, 2025
7a78395
Update state icons
Taewan-P Feb 26, 2025
9a3327d
Update image vector names
Taewan-P Feb 26, 2025
c6c258f
Implement migration logic with viewmodel
Taewan-P Feb 26, 2025
0fbfcdb
Delete leftovers in case error occurred previously
Taewan-P Feb 26, 2025
6a55f44
Fix chat migration blocked state
Taewan-P Feb 26, 2025
1ffa465
Use ChatRoomV2 for home chat list after migration
Taewan-P Feb 26, 2025
7017fc3
Merge branch 'main' into refactor/complete-redesign
Taewan-P Feb 26, 2025
9a3661b
Implement migrated chat list screen
Taewan-P Feb 27, 2025
5ffb17e
Merge branch 'main' into refactor/complete-redesign
Taewan-P Feb 27, 2025
e0aa665
Add reasoning column in PlatformV2
Taewan-P Mar 1, 2025
03b51e5
Remove unused functions
Taewan-P Mar 1, 2025
f2a3fa0
Set reasoning default value to false when migrating
Taewan-P Mar 1, 2025
e73daf1
Remove brand text from chat bubble
Taewan-P Mar 1, 2025
cc60148
Remove unused AICore feature
Taewan-P Mar 1, 2025
5e07295
Migrate chat screen to new data structures
Taewan-P Mar 1, 2025
dc3d988
Remove auto scroll delay
Taewan-P Mar 1, 2025
0b81bed
Merge branch 'main' into refactor/complete-redesign
Taewan-P Mar 1, 2025
3460d93
Merge branch 'main' into refactor/complete-redesign
Taewan-P Mar 1, 2025
64706ff
Merge branch 'main' into refactor/complete-redesign
Taewan-P Mar 1, 2025
157c336
Remove unused brand text component
Taewan-P Mar 1, 2025
a0d90dc
Change opponent bubble width to full screen width
Taewan-P Mar 1, 2025
1eb49b2
Add app icon above the response
Taewan-P Mar 1, 2025
31ce76a
Update dependencies
Taewan-P Mar 1, 2025
5073271
Remove gemini sdk and fix build error
Taewan-P Mar 1, 2025
af2bd4d
Change markdown library
Taewan-P Mar 3, 2025
4acd5c6
Add select text icon to opponent bubble
Taewan-P Mar 3, 2025
5528b9c
Fix user chat bubble width
Taewan-P Mar 3, 2025
b549921
Update assistant chat bubble to only use one each
Taewan-P Mar 4, 2025
e8e54e8
Add platform buttons to select content of assistant bubbles
Taewan-P Mar 4, 2025
7748189
Show platform toggle button when more than two platforms are enabled
Taewan-P Mar 4, 2025
9246534
Add revision column to MessageV2
Taewan-P Mar 4, 2025
7812974
Implement select text feature for each text bubble
Taewan-P Mar 5, 2025
132a70d
Remove useless max statements
Taewan-P Mar 5, 2025
fab2dfc
Change default title mode button design
Taewan-P Mar 5, 2025
a13f3fa
Move user chat bubble actions to dropdown menu
Taewan-P Mar 5, 2025
67c6c60
Update chat bubble paddings
Taewan-P Mar 5, 2025
925b0a1
Add chat search query in DAO
Taewan-P Mar 7, 2025
05b8957
Add chat search button
Taewan-P Mar 13, 2025
d00ae2d
Add search bar when search button is clicked
Taewan-P Mar 13, 2025
eb27c86
Merge branch 'main' into refactor/complete-redesign
Taewan-P Mar 14, 2025
4e47d96
Create CLAUDE.md
Taewan-P Jun 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

65 changes: 65 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

GPT Mobile is an Android chat application that supports chatting with multiple AI models simultaneously (OpenAI GPT, Anthropic Claude, Google Gemini, Groq, and Ollama). Built with 100% Kotlin, Jetpack Compose, and follows Modern Android App Architecture patterns.

## Build Commands

### Development Build
```bash
./gradlew assembleDebug
```

### Release Build
```bash
./gradlew assembleRelease
./gradlew bundleRelease # For Google Play Store AAB format
```

### Testing
```bash
./gradlew test # Unit tests
./gradlew connectedAndroidTest # Instrumented tests
```

### Code Quality
- **Linting**: Handled by GitHub Actions with ktlint 1.3.1
- **Security**: CodeQL analysis runs automatically on main branch changes

## Architecture

### Core Structure
- **MVVM Pattern**: ViewModels handle UI state, Repositories manage data
- **Dependency Injection**: Hilt for all dependency management
- **Database**: Room for local chat history storage
- **Networking**: Ktor client with OkHttp engine for API calls
- **UI**: Jetpack Compose with Material 3 design system

### Data Flow
1. **Chat Flow**: `ChatViewModel` → `ChatRepository` → API clients (OpenAI, Anthropic, etc.) → Streaming responses
2. **Persistence**: All chat data stored locally via Room database
3. **Settings**: DataStore for user preferences and API configurations

### Key Components
- **ChatRepositoryImpl**: Handles all AI platform communications with streaming support
- **NetworkModule**: Configures Ktor client and Anthropic API
- **Platform Support**: Each AI service has dedicated completion methods with consistent `Flow<ApiState>` responses
- **Message Transformation**: Platform-specific message format conversion for API compatibility

### Module Structure
- `data/`: Models, DTOs, database entities, repositories, network clients
- `di/`: Hilt dependency injection modules
- `presentation/`: ViewModels, UI components, navigation, theming
- `util/`: Extensions, utilities, string resources

## Development Notes

- **Min SDK**: 31 (Android 12)
- **Target SDK**: 35
- **Java Version**: 17
- **Build System**: Gradle with Kotlin DSL
- **Material You**: Dynamic theming support without activity restart
- **Internationalization**: Multiple language support via string resources
8 changes: 5 additions & 3 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ android {
vectorDrawables {
useSupportLibrary = true
}

ksp {
arg("room.schemaLocation", "$projectDir/schemas")
}
}

androidResources {
Expand Down Expand Up @@ -82,9 +86,6 @@ dependencies {
implementation(libs.androidx.lifecycle.runtime.compose.android)
ksp(libs.hilt.compiler)

// Gemini SDK
implementation(libs.gemini)

// Ktor
implementation(libs.ktor.content.negotiation)
implementation(libs.ktor.core)
Expand All @@ -98,6 +99,7 @@ dependencies {

// Markdown
implementation(libs.compose.markdown)
implementation(libs.richtext)

// Navigation
implementation(libs.hilt.navigation)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "f1cc616c51cc6e2ff8472c95d5b07c8f",
"entities": [
{
"tableName": "chats",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`chat_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT NOT NULL, `enabled_platform` TEXT NOT NULL, `created_at` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "chat_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "enabledPlatform",
"columnName": "enabled_platform",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "createdAt",
"columnName": "created_at",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"chat_id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "messages",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`message_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `chat_id` INTEGER NOT NULL, `content` TEXT NOT NULL, `image_data` TEXT, `linked_message_id` INTEGER NOT NULL, `platform_type` TEXT, `created_at` INTEGER NOT NULL, FOREIGN KEY(`chat_id`) REFERENCES `chats`(`chat_id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "id",
"columnName": "message_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "chatId",
"columnName": "chat_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "content",
"columnName": "content",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "imageData",
"columnName": "image_data",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "linkedMessageId",
"columnName": "linked_message_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "platformType",
"columnName": "platform_type",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "createdAt",
"columnName": "created_at",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"message_id"
]
},
"indices": [],
"foreignKeys": [
{
"table": "chats",
"onDelete": "CASCADE",
"onUpdate": "NO ACTION",
"columns": [
"chat_id"
],
"referencedColumns": [
"chat_id"
]
}
]
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f1cc616c51cc6e2ff8472c95d5b07c8f')"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
{
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "778d15aaf1d9b9853912299330d2ec1e",
"entities": [
{
"tableName": "chats",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`chat_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT NOT NULL, `enabled_platform` TEXT NOT NULL, `created_at` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "chat_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "enabledPlatform",
"columnName": "enabled_platform",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "createdAt",
"columnName": "created_at",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"chat_id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "messages",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`message_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `chat_id` INTEGER NOT NULL, `content` TEXT NOT NULL, `image_data` TEXT, `linked_message_id` INTEGER NOT NULL, `platform_type` TEXT, `created_at` INTEGER NOT NULL, FOREIGN KEY(`chat_id`) REFERENCES `chats`(`chat_id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
"fields": [
{
"fieldPath": "id",
"columnName": "message_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "chatId",
"columnName": "chat_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "content",
"columnName": "content",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "imageData",
"columnName": "image_data",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "linkedMessageId",
"columnName": "linked_message_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "platformType",
"columnName": "platform_type",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "createdAt",
"columnName": "created_at",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"message_id"
]
},
"indices": [
{
"name": "index_messages_chat_id",
"unique": false,
"columnNames": [
"chat_id"
],
"orders": [],
"createSql": "CREATE INDEX IF NOT EXISTS `index_messages_chat_id` ON `${TABLE_NAME}` (`chat_id`)"
}
],
"foreignKeys": [
{
"table": "chats",
"onDelete": "CASCADE",
"onUpdate": "NO ACTION",
"columns": [
"chat_id"
],
"referencedColumns": [
"chat_id"
]
}
]
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '778d15aaf1d9b9853912299330d2ec1e')"
]
}
}
Loading
Loading