Add TODO app

This commit is contained in:
icewithcola 2024-04-26 13:42:06 +08:00
parent 1da5250b9a
commit 04dabcb418
18 changed files with 774 additions and 28 deletions

View file

@ -11,8 +11,8 @@ android {
applicationId = "uk.kagurach.android101"
minSdk = 31
targetSdk = 34
versionCode = 132
versionName = "1.3.2"
versionCode = 140
versionName = "1.4.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
@ -33,16 +33,50 @@ android {
kotlinOptions {
jvmTarget = "17"
}
buildFeatures {
compose = true
viewBinding = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.1"
}
androidResources {
generateLocaleConfig = true
}
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
implementation(libs.androidx.activity)
implementation(libs.androidx.constraintlayout)
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
implementation(libs.androidx.room.common)
implementation(libs.androidx.room.ktx)
implementation(libs.androidx.constraintlayout)
implementation(libs.androidx.navigation.fragment.ktx)
implementation(libs.androidx.navigation.ui.ktx)
implementation(libs.androidx.activity)
implementation(libs.androidx.annotation)
implementation(libs.androidx.lifecycle.livedata.ktx)
implementation(libs.androidx.lifecycle.viewmodel.ktx)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
}

View file

@ -14,15 +14,6 @@
android:supportsRtl="true"
android:theme="@style/Theme.Android101"
tools:targetApi="31">
<activity
android:name=".Page4"
android:exported="false" />
<activity
android:name=".Page3"
android:exported="false" />
<activity
android:name=".MainActivity2"
android:exported="false" />
<activity
android:name=".MainActivity"
android:exported="true">
@ -32,6 +23,37 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".Page4"
android:exported="false" />
<activity
android:name=".Page3"
android:exported="false" />
<activity
android:name=".MainActivity2"
android:exported="false" />
<activity
android:name=".todoList.AddPage"
android:exported="false"
android:label="@string/title_activity_add_page"
android:theme="@style/Theme.TODOList" />
<activity
android:name=".todoList.MainActivity"
android:exported="true"
android:label="todoListMain"
android:theme="@style/Theme.TODOList">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</activity>
</application>
</manifest>

View file

@ -1,9 +1,15 @@
package uk.kagurach.android101;
import android.Manifest;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
@ -17,6 +23,8 @@ import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import java.util.Arrays;
public class MainActivity extends AppCompatActivity {
PageHelper pageHelper;
@Override
@ -29,6 +37,7 @@ public class MainActivity extends AppCompatActivity {
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
}
@Override
@ -50,6 +59,7 @@ public class MainActivity extends AppCompatActivity {
101);
}
textViewAppendString(tv,"Check Finished");
textViewAppendString(tv,"提示:常桉有惊喜");
}
textViewAppendString(tv,"*************************\nfinished");
@ -58,10 +68,8 @@ public class MainActivity extends AppCompatActivity {
Button button = findViewById(R.id.Page1NextPage);
button.setEnabled(true);
}
public void jumpToNext(View view) {
pageHelper.goNext();
button.setOnClickListener(pageHelper.pageButtonHandler);
button.setOnLongClickListener(new LongClickHandler(this));
}
private void textViewAppendString(@NonNull TextView tv, String s){
@ -72,4 +80,41 @@ public class MainActivity extends AppCompatActivity {
last += s;
tv.setText(last);
}
private final class LongClickHandler implements View.OnLongClickListener
{
LongClickHandler(Context ctx){
context = ctx;
}
Context context;
@Override
public boolean onLongClick(View v){
CreateShortcut(context);
return false;
}
}
private void CreateShortcut(Context context) {
ShortcutManager shortcutManager =
this.getSystemService(ShortcutManager.class);
if (shortcutManager.isRequestPinShortcutSupported()) {
ShortcutInfo pinShortcutInfo;
try {
pinShortcutInfo =
new ShortcutInfo.Builder(context, "start_TODO").build();
}catch (Exception e){
Log.e("ShortCutManager", Arrays.toString(e.getStackTrace()));
return;
}
Intent pinnedShortcutCallbackIntent =
shortcutManager.createShortcutResultIntent(pinShortcutInfo);
PendingIntent successCallback = PendingIntent.getBroadcast(context, 0,
pinnedShortcutCallbackIntent, PendingIntent.FLAG_IMMUTABLE);
shortcutManager.requestPinShortcut(pinShortcutInfo,
successCallback.getIntentSender());
}
}
}

View file

@ -62,7 +62,7 @@ public class MainActivity2 extends AppCompatActivity {
public void setColor(View view) {
TextView t = findViewById(R.id.test2strview);
EditText r_edit = findViewById(R.id.R);
EditText r_edit = findViewById(R.id.EditText_R);
EditText g_edit = findViewById(R.id.G);
EditText b_edit = findViewById(R.id.B);

View file

@ -0,0 +1,185 @@
package uk.kagurach.android101.todoList
import android.content.Intent
import android.icu.util.Calendar
import android.os.Bundle
import android.view.MotionEvent
import android.view.inputmethod.InputMethodManager
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material3.DatePicker
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FabPosition
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TimePicker
import androidx.compose.material3.TimePickerState
import androidx.compose.material3.rememberDatePickerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.content.ContextCompat
import uk.kagurach.android101.R
import uk.kagurach.android101.todoList.ui.theme.LightBlue100
import java.text.SimpleDateFormat
class AddPage() : ComponentActivity() {
var item: TodoItem? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
) {
AddPageLayout()
}
}
}
// Fix Input Method
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
if (currentFocus != null) {
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(currentFocus!!.windowToken, 0)
}
return super.dispatchTouchEvent(ev)
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AddPageLayout(){
val context = LocalContext.current
var title by remember {
mutableStateOf(
when (item){
null -> ""
else -> item!!.title
}
)
}
val c = Calendar.getInstance()
val timePickerState by remember {
mutableStateOf(
when (item){
null -> TimePickerState(c.get(Calendar.HOUR_OF_DAY),c.get(Calendar.MINUTE),true)
else -> TimePickerState(
item!!.dueDate.split(" ")[1].split(":")[0].toInt(),
item!!.dueDate.split(" ")[1].split(":")[1].toInt(),
true
)
}
)
}
val datePickerState = rememberDatePickerState(
initialDisplayedMonthMillis = System.currentTimeMillis(),
yearRange = 2024..2099
)
Scaffold (
topBar = {
Surface(
modifier = Modifier
.fillMaxWidth()
.height(50.dp),
) {
Text(
text = context.getText(R.string.edit_page_title).toString(),
fontSize = 30.sp,
textAlign = TextAlign.Center
)
}
},
content = { padding ->
Column(
modifier = Modifier
.fillMaxWidth()
.verticalScroll(rememberScrollState())
.padding(padding)
) {
TextField(
value = title,
onValueChange = { title = it },
label = { Text(context.getText(R.string.enter_title).toString()) },
maxLines = 1,
modifier = Modifier
.height(80.dp)
.fillMaxWidth()
)
Box(
modifier = Modifier.padding(top = 15.dp, bottom = 15.dp),
contentAlignment = Alignment.CenterStart
) {
DatePicker(state = datePickerState)
}
TimePicker(
state = timePickerState,
modifier = Modifier.padding(start = 70.dp)
)
}
},
floatingActionButtonPosition = FabPosition.End,
floatingActionButton = {
Submit {
if (title.isBlank()||datePickerState.selectedDateMillis==null){
Toast.makeText(context,"Please Fill Every field",Toast.LENGTH_SHORT)
.show()
return@Submit
}
val loader = TodoItemLoader(context)
val sdf = SimpleDateFormat("yyyy-MM-dd")
val todoItem = TodoItem(
loader.getLastId()+1,
title.replace("\t"," "),
sdf.format(datePickerState.selectedDateMillis) + " " +
timePickerState.hour.toString() + ":" +
timePickerState.minute.toString()
)
loader.changeItem(todoItem)
val myIntent = Intent(context, MainActivity::class.java)
ContextCompat.startActivity(context, myIntent, null)
}
},
)
}
@Composable
fun Submit(onClick: () -> Unit) {
FloatingActionButton(
onClick = { onClick() },
containerColor = LightBlue100
) {
Icon(Icons.Filled.Add, "Submit")
}
}
}

View file

@ -0,0 +1,85 @@
package uk.kagurach.android101.todoList
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.FabPosition
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.core.content.ContextCompat
import uk.kagurach.android101.todoList.ui.theme.LightBlue100
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
val loader = TodoItemLoader(this)
val tmpList = loader.getTodoItems()
super.onCreate(savedInstanceState)
setContent {
LayOut(tmpList)
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun LayOut(tmpList : List<TodoItem>?) {
val context = LocalContext.current
Scaffold (
topBar = {
TopAppBar(
title = { Text("Simple TODO ^_^") }
)
},
content = {
padding ->
Surface(
modifier = Modifier.padding(padding)
.verticalScroll(rememberScrollState())
) {
if (tmpList != null) {
Column {
for (i in tmpList) {
TodoItemView(todoItem = i)
}
}
}
}
},
floatingActionButtonPosition = FabPosition.End,
floatingActionButton = {
NextPage {
val myIntent = Intent(context, AddPage::class.java)
ContextCompat.startActivity(context, myIntent, null)
}
},
)
}
@Composable
fun NextPage(onClick: () -> Unit) {
FloatingActionButton(
onClick = { onClick() },
containerColor = LightBlue100
) {
Icon(Icons.Filled.Add, "Floating action button.")
}
}

View file

@ -0,0 +1,17 @@
package uk.kagurach.android101.todoList
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity
data class TodoItem(
@PrimaryKey(autoGenerate = true)
val id: Int,
var title: String,
var dueDate: String,
var isCompleted:Boolean = false,
var MarkDeleted:Boolean = false
)

View file

@ -0,0 +1,106 @@
package uk.kagurach.android101.todoList
import android.content.Context
import android.util.Log
import java.io.File
import java.io.FileWriter
class TodoItemLoader(private val context: Context) {
private val db = File(context.filesDir,"db")
public fun getTodoItems(): List<TodoItem>?{
if (!db.exists()){
return null
}
val lines = db.readLines()
if (lines.isEmpty()){
return null
}
var list: List<TodoItem> = listOf()
for (line in lines){
val split = line.split("\t")
val item: TodoItem
try {
item = TodoItem(split[0].toInt(),split[1],split[2], split[3].toBooleanStrict())
list = list + item
} catch (e: Exception){
Log.e("DB Error", e.printStackTrace().toString())
}
}
if (list.isNotEmpty()){
return list
}
return null
}
public fun saveTodoItems(list:List<TodoItem>){
var result = ""
for (i in list){
if(!i.MarkDeleted) {
result += "%s\t%s\t%s\t%s\n".format(
i.id.toString(),
i.title,
i.dueDate,
i.isCompleted.toString()
)
}
}
val fileWriter = FileWriter(db)
fileWriter.write(result)
fileWriter.close()
}
public fun getLastId():Int{
val items = getTodoItems();
return if (items==null){
0
}else{
var max = 0
for (i in items){
if (i.id>max){
max = i.id
}
}
max
}
}
public fun changeItem(todoItem: TodoItem){
var items = getTodoItems()
var changeFlag = false
if (items != null) {
for (i in items){
if (i.id==todoItem.id){
i.title = todoItem.title
i.dueDate = todoItem.dueDate
i.MarkDeleted = todoItem.MarkDeleted
i.isCompleted = todoItem.isCompleted
changeFlag = true
break
}
}
if (!changeFlag){
items = items + todoItem
}
}else{
items = listOf(todoItem)
}
saveTodoItems(items)
}
public fun searchItem(id:Int): TodoItem?{
val items = getTodoItems();
return if (items==null){
null
}else{
for (i in items){
if (i.id>id){
return i
}
}
null
}
}
}

View file

@ -0,0 +1,167 @@
package uk.kagurach.android101.todoList
import android.content.Context
import android.content.Intent
import android.widget.Toast
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.content.ContextCompat
import uk.kagurach.android101.R
import uk.kagurach.android101.todoList.ui.theme.Blue100
import uk.kagurach.android101.todoList.ui.theme.Green100
@Composable
fun TodoItemView(todoItem: TodoItem) {
val context = LocalContext.current
val loader = TodoItemLoader(context)
var deleteText by remember {
mutableStateOf(context.getText(R.string.first_delete).toString())
}
var bgColor by remember {
mutableStateOf(
when (todoItem.isCompleted){
true -> Green100
false -> Blue100
}
)
}
var needShow by remember {
mutableStateOf(true)
}
if (!needShow){
return
}
Spacer(modifier = Modifier.height(10.dp))
Surface(
modifier = Modifier
.wrapContentSize()
.fillMaxWidth(),
shape = RoundedCornerShape(20.dp),
color = bgColor
) {
Column(
modifier = Modifier.padding(
start = 10.dp,
end = 10.dp
)
){
Text(
text = todoItem.title,
color = Color.Black,
fontSize = 30.sp,
fontFamily = FontFamily.Monospace
)
Row{
Spacer(modifier = Modifier.weight(1f))
Text(
text = todoItem.dueDate,
color = Color.Black,
fontSize = 20.sp,
fontFamily = FontFamily.SansSerif
)
}
Row {
TextButton(
onClick = {
if (!todoItem.isCompleted){
Toast.makeText( context,
context.getText(R.string.yes_not_finish)
,Toast.LENGTH_SHORT).show()
}else{
todoItem.isCompleted = false
loader.changeItem(todoItem)
bgColor = Blue100
}
},
shape = RoundedCornerShape(0),
modifier = Modifier.width(110.dp)
) {
Text(text = context.getText(R.string.unfinish).toString())
}
Spacer(modifier = Modifier.width(20.dp))
TextButton(
onClick = {
if (todoItem.isCompleted){
Toast.makeText( context,
context.getText(R.string.already_finish)
,Toast.LENGTH_SHORT).show()
}else{
todoItem.isCompleted = true
loader.changeItem(todoItem)
bgColor = Green100
}
},
shape = RoundedCornerShape(0),
modifier = Modifier.width(110.dp)
) {
Text(text = context.getText(R.string.finish).toString())
}
Spacer(modifier = Modifier.width(20.dp))
TextButton(
onClick = {
when (deleteText){
context.getText(R.string.first_delete).toString() ->
deleteText=context.getText(R.string.second_delete).toString()
else -> {
needShow = false
todoItem.MarkDeleted = true
loader.changeItem(todoItem)
}
}
},
shape = RoundedCornerShape(0),
modifier = Modifier.width(110.dp)
) {
Text(
text = deleteText
)
}
}
}
}
}
@Preview(showBackground = true)
@Composable
fun TodoItemPreview(){
val todoItem = TodoItem(
0,"Test TODO Item","2024-04-30 11:45",
)
val todoItem2 = TodoItem(
1,"测试喵","2024-11-01 22:33",true
)
Column {
TodoItemView(todoItem)
TodoItemView(todoItem2)
}
}
fun NextPage(context:Context,item: TodoItem) {
val myIntent = Intent(context, AddPage::class.java)
myIntent.putExtra("ITEM",item.id)
ContextCompat.startActivity(context, myIntent, null)
}

View file

@ -0,0 +1,10 @@
package uk.kagurach.android101.todoList.ui.theme
import androidx.compose.ui.graphics.Color
val Green100 = Color(0xFFC8E6C9)
val Blue100 = Color(0xFFBBDEFB)
val Red100 = Color(0xFFFFCDD2)
val LightBlue100 = Color(0xFFB2EBF2)
val Yellow100 = Color(0xFFFFF9C4)

View file

@ -86,7 +86,7 @@
android:orientation="horizontal">
<EditText
android:id="@+id/R"
android:id="@+id/EditText_R"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"

View file

@ -0,0 +1 @@
unqualifiedResLocale=zh-rCN

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Android 101</string>
<string name="already_finish">您已经完成了喵</string>
<string name="yes_not_finish">呜呜您还没完成呢</string>
<string name="finish">做完了!</string>
<string name="unfinish">还没好!</string>
<string name="edit_page_title">修改您的TODO任务</string>
<string name="enter_title">标题</string>
<string name="first_delete">删除</string>
<string name="second_delete">确认删除</string>
<string name="todo_app">任务清单</string>
<string name="todo_app_short_label">启动任务清单</string>
</resources>

View file

@ -1,12 +1,24 @@
<resources>
<string name="todo_app">TODO List</string>
<string name="already_finish">You have already finished❤</string>
<string name="yes_not_finish">You haven\'t finished😇</string>
<string name="finish">Finish</string>
<string name="unfinish">Not Finish</string>
<string name="title_activity_add_page" translatable="false">add_page</string>
<string name="edit_page_title">Edit Your TODO Item Here</string>
<string name="enter_title">Enter Title</string>
<string name="first_delete">Delete</string>
<string name="second_delete">Delete!!</string>
<string name="app_name">Android101</string>
<string name="hello_world">你好,世界!</string>
<string name="next_page">下一页</string>
<string name="two_way_page">单击下一页,长按上一页</string>
<string name="test_str">测试文本</string>
<string name="set_color">设置颜色</string>
<string name="set">设置</string>
<string name="setText">设置文本</string>
<string name="kaculate">弱智计算器</string>
<string name="Backspace">退格</string>
<string name="hello_world" translatable="false">你好,世界!</string>
<string name="next_page" translatable="false">下一页</string>
<string name="two_way_page" translatable="false">单击下一页,长按上一页</string>
<string name="test_str" translatable="false">测试文本</string>
<string name="set_color" translatable="false">设置颜色</string>
<string name="set" translatable="false">设置</string>
<string name="setText" translatable="false">设置文本</string>
<string name="kaculate" translatable="false">弱智计算器</string>
<string name="Backspace" translatable="false">退格</string>
<string name="todo_app_short_label">Open TODO</string>
</resources>

View file

@ -13,4 +13,8 @@
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
<style name="Theme.TODOList" parent="android:Theme.Material.Light.NoActionBar" />
<!-- Base application theme. -->
<style name="Base.Theme.TODOList" parent="Theme.Material3.DayNight.NoActionBar"/>
</resources>

View file

@ -0,0 +1,17 @@
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:shortcutId="start_TODO"
android:enabled="true"
android:icon="@drawable/ic_launcher_background"
android:shortcutShortLabel="@string/todo_app_short_label"
android:shortcutLongLabel="@string/todo_app"
android:shortcutDisabledMessage="@string/todo_app">
<intent
android:action="android.intent.action.VIEW"
android:targetPackage="uk.kagurach.android101"
android:targetClass="uk.kagurach.android101.todoList.MainActivity" />
<categories android:name="android.shortcut.conversation" />
<capability-binding android:key="actions.intent.CREATE_MESSAGE" />
</shortcut>
</shortcuts>

View file

@ -6,7 +6,7 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
org.gradle.jvmargs=-Xmx4096m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. For more details, visit
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects

View file

@ -9,6 +9,16 @@ appcompat = "1.6.1"
material = "1.11.0"
activity = "1.8.0"
constraintlayout = "2.1.4"
lifecycleRuntimeKtx = "2.7.0"
activityCompose = "1.8.2"
composeBom = "2023.08.00"
roomCommon = "2.6.1"
roomKtx = "2.6.1"
navigationFragmentKtx = "2.6.0"
navigationUiKtx = "2.6.0"
annotation = "1.6.0"
lifecycleLivedataKtx = "2.7.0"
lifecycleViewmodelKtx = "2.7.0"
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@ -19,6 +29,23 @@ androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" }
androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
androidx-ui = { group = "androidx.compose.ui", name = "ui" }
androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-room-common = { group = "androidx.room", name = "room-common", version.ref = "roomCommon" }
androidx-room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "roomKtx" }
androidx-navigation-fragment-ktx = { group = "androidx.navigation", name = "navigation-fragment-ktx", version.ref = "navigationFragmentKtx" }
androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "navigationUiKtx" }
androidx-annotation = { group = "androidx.annotation", name = "annotation", version.ref = "annotation" }
androidx-lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version.ref = "lifecycleLivedataKtx" }
androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }