Skip to content

Commit

Permalink
Merge pull request #3 from navgurukul/feature_aiEngine/develop
Browse files Browse the repository at this point in the history
Feature ai engine/develop
  • Loading branch information
surajsahani authored Aug 7, 2024
2 parents 9a273a2 + 04d0c37 commit 027eb76
Show file tree
Hide file tree
Showing 89 changed files with 4,331 additions and 123 deletions.
15 changes: 15 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ android {
lint {
abortOnError true
}
buildFeatures {
viewBinding true
}
}

dependencies {
Expand All @@ -107,6 +110,8 @@ dependencies {

// color picker for user-defined colors
implementation 'com.github.martin-stone:hsv-alpha-color-picker-android:3.1.0'
implementation 'androidx.activity:activity:1.9.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'

// test
testImplementation 'junit:junit:4.13.2'
Expand All @@ -115,4 +120,14 @@ dependencies {
testImplementation 'org.robolectric:robolectric:4.12.1'
testImplementation 'androidx.test:runner:1.5.2'
testImplementation 'androidx.test:core:1.5.0'

// Generative AI
implementation("com.google.ai.client.generativeai:generativeai:0.9.0")

//multiple bottom sheets
implementation ("com.roshaan.multiplebottomsheets:multiplebottomsheets:1.0.1")
implementation ("com.google.android.material:material:1.12.0")
// Rich Editor

implementation("com.mohamedrejeb.richeditor:richeditor-compose:1.0.0-rc05")
}
6 changes: 3 additions & 3 deletions app/src/debug/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
SPDX-License-Identifier: GPL-3.0-only
-->
<resources>
<string name="english_ime_name" translatable="false">HeliBoard debug</string>
<string name="spell_checker_service_name" translatable="false">HeliBoard debug Spell Checker</string>
<string name="ime_settings" translatable="false">HeliBoard debug Settings</string>
<string name="english_ime_name" translatable="false">Oscar AI Keyboard</string>
<string name="spell_checker_service_name" translatable="false">Oscar debug Spell Checker</string>
<string name="ime_settings" translatable="false">Oscar debug Settings</string>

</resources>
24 changes: 20 additions & 4 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only

<application android:label="@string/english_ime_name"
android:name="helium314.keyboard.latin.App"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:allowBackup="true"
android:defaultToDeviceProtectedStorage="true"
Expand Down Expand Up @@ -48,7 +46,6 @@ SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
<!-- Activities -->
<activity android:name=".setup.SetupActivity"
android:theme="@style/platformActivityTheme"
android:icon="@mipmap/ic_launcher"
android:launchMode="singleTask"
android:noHistory="true"
android:exported="true">
Expand Down Expand Up @@ -99,7 +96,26 @@ SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>

<activity
android:name=".setup.MainActivity"
android:exported="false"
android:label="@string/app_name"
android:theme="@style/AppTheme"/>
<activity
android:name=".setup.KeyboardselectionActivity"
android:exported="false"
android:label="@string/app_name"
android:theme="@style/AppTheme"/>
<activity
android:name=".setup.PrivacyPolicyActivity"
android:exported="false"
android:label="@string/app_name"
android:theme="@style/AppTheme"/>
<activity
android:name=".setup.TermsOfUseActivity"
android:exported="false"
android:label="@string/app_name"
android:theme="@style/AppTheme"/>
<!-- Broadcast receivers -->
<receiver android:name="SystemBroadcastReceiver"
android:exported="true">
Expand Down
9 changes: 9 additions & 0 deletions app/src/main/java/helium314/keyboard/AIEngine/AIState.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package helium314.keyboard.AIEngine

import com.mohamedrejeb.richeditor.model.RichTextState

data class AIState(
val isAIProcessing: Boolean = false,
val isAICorrecting: Boolean = false,
val aiText: RichTextState = RichTextState(),
)
47 changes: 47 additions & 0 deletions app/src/main/java/helium314/keyboard/AIEngine/SummarizeUiState.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright 2023 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package helium314.keyboard.AIEngine

/**
* A sealed hierarchy describing the state of the text generation.
*/
sealed interface SummarizeUiState {

/**
* Empty state when the screen is first shown
*/
data object Initial: SummarizeUiState

/**
* Still loading
*/
data object Loading: SummarizeUiState

/**
* Text has been generated
*/
data class Success(
val outputText: String
): SummarizeUiState

/**
* There was an error generating text
*/
data class Error(
val errorMessage: String
): SummarizeUiState
}
108 changes: 108 additions & 0 deletions app/src/main/java/helium314/keyboard/AIEngine/SummarizeViewModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package helium314.keyboard.AIEngine

import android.content.Context
import android.widget.Toast
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.ai.client.generativeai.GenerativeModel
import com.google.ai.client.generativeai.type.content
import helium314.keyboard.gemini.GeminiClient
import helium314.keyboard.latin.utils.Log
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

class SummarizeViewModel(
private val generativeModel: GenerativeModel
) : ViewModel() {

private val _state = MutableStateFlow(AIState())
val state: StateFlow<AIState> = _state.asStateFlow()


private val _aiState = MutableLiveData<AIState>()
val replyData: LiveData<AIState>
get() = _aiState

private val _isAICorrecting = MutableLiveData<Boolean>()
val isAICorrecting: LiveData<Boolean>
get() = _isAICorrecting

private val _uiState: MutableStateFlow<SummarizeUiState> =
MutableStateFlow(SummarizeUiState.Initial)
val uiState: StateFlow<SummarizeUiState> =
_uiState.asStateFlow()

// fun onAICorrection(context: Context) {
//
// val generativeModel = geminiClient.geminiFlashModel
//
// val inputContent = content {
// text("Please correct the following text for any spelling and grammatical errors, and slightly paraphrase it while keeping the original language and the markdown format:\n")
// }
// viewModelScope.launch {
// try {
// val response = generativeModel.generateContent(inputContent)
// _state.update { it.copy(isAICorrecting = true) }
// Toast.makeText(context, "Text Corrected With AIEngine", Toast.LENGTH_SHORT).show()
// } catch (e: Exception) {
// Toast.makeText(context, "Error Correcting Text With AIEngine", Toast.LENGTH_SHORT)
// .show()
// } finally {
// _state.update { it.copy(isAICorrecting = false) }
// }
// }
// }

fun summarizeStreaming(inputText: String) {
_uiState.value = SummarizeUiState.Loading

val prompt =
"Please correct the following text for any spelling and grammatical errors, and slightly paraphrase it while keeping the original language and the markdown format:\n: $inputText"

viewModelScope.launch {
try {
var outputContent = ""
generativeModel.generateContentStream(prompt)
.collect { response ->
outputContent += response.text
_uiState.value = SummarizeUiState.Success(outputContent)
Log.d("SummarizeViewModel", "outputContent: $outputContent")
}
} catch (e: Exception) {
_uiState.value = SummarizeUiState.Error(e.localizedMessage ?: "")
Log.d("SummarizeViewModel", "Error: ${e.localizedMessage}")
}
}
}

// fun summarizeStreamingLiveData(inputText: String) {
// //_uiState.value = SummarizeUiState.Loading
//
// val prompt =
// "Please correct the following text for any spelling and grammatical errors, and slightly paraphrase it while keeping the original language and the markdown format:\n: $inputText"
//
// viewModelScope.launch {
// try {
// var outputContent = ""
// val response = generativeModel.generateContentStream(prompt)
// val response = AIState(prompt)
// _aiState.postValue(response)
//
// //_aiState.value = generativeModel.generateContentStream(prompt)
//
//// .collect { response ->
//// outputContent += response.text
//// _uiState.value = SummarizeUiState.Success(outputContent)
//// }
// } catch (e: Exception) {
// _uiState.value = SummarizeUiState.Error(e.localizedMessage ?: "")
// }
// }
// }

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package helium314.keyboard.AIEngine

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.google.ai.client.generativeai.GenerativeModel
import helium314.keyboard.gemini.GeminiClient

class SummarizeViewModelFactory(
//private val geminiClient: GeminiClient,
private val generativeModel: GenerativeModel
) : ViewModelProvider.Factory {

override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(SummarizeViewModel::class.java)) {
@Suppress("UNCHECKED_CAST")
return SummarizeViewModel( generativeModel) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package helium314.keyboard.bottomsheets


import android.content.Intent
import android.graphics.Color
import android.graphics.Typeface
import android.os.Bundle
import android.text.SpannableString
import android.text.Spanned
import android.text.style.ForegroundColorSpan
import android.text.style.StyleSpan
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import helium314.keyboard.latin.R
import android.provider.Settings

class SheetOneFragment : Fragment() {

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
var view = inflater.inflate(R.layout.fragment_sheet1, container, false)

val instructionText =
"Tap the toggle to enable Oscar Keyboard in \n your keyboard list"
val spannableString = SpannableString(instructionText)

val startIndex = instructionText.indexOf("Oscar Keyboard")
val endIndex = startIndex + "Oscar Keyboard".length

if (startIndex >= 0) {
spannableString.setSpan(
ForegroundColorSpan(Color.BLACK), // Set color to black
startIndex,
endIndex,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)

spannableString.setSpan(
StyleSpan(Typeface.BOLD), // Set style to bold
startIndex,
endIndex,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
}

val textViewInstruction = view.findViewById<TextView>(R.id.text_view_instruction)
textViewInstruction.text = spannableString

val buttonEnable = view.findViewById<Button>(R.id.enableId)
buttonEnable.setOnClickListener {
// Open the system settings to enable the keyboard
startActivity(Intent(Settings.ACTION_INPUT_METHOD_SETTINGS))
}

return view
}

}
Loading

0 comments on commit 027eb76

Please sign in to comment.