mirror of
https://github.com/wismna/DoNext.git
synced 2025-10-03 07:30:13 -04:00
Add extended icons
Some layout improvements Update README
This commit is contained in:
12
.idea/caches/deviceStreaming.xml
generated
12
.idea/caches/deviceStreaming.xml
generated
@@ -561,6 +561,18 @@
|
|||||||
<option name="screenX" value="720" />
|
<option name="screenX" value="720" />
|
||||||
<option name="screenY" value="1600" />
|
<option name="screenY" value="1600" />
|
||||||
</PersistentDeviceSelectionData>
|
</PersistentDeviceSelectionData>
|
||||||
|
<PersistentDeviceSelectionData>
|
||||||
|
<option name="api" value="35" />
|
||||||
|
<option name="brand" value="motorola" />
|
||||||
|
<option name="codename" value="kansas" />
|
||||||
|
<option name="id" value="kansas" />
|
||||||
|
<option name="labId" value="google" />
|
||||||
|
<option name="manufacturer" value="Motorola" />
|
||||||
|
<option name="name" value="moto g - 2025" />
|
||||||
|
<option name="screenDensity" value="280" />
|
||||||
|
<option name="screenX" value="720" />
|
||||||
|
<option name="screenY" value="1604" />
|
||||||
|
</PersistentDeviceSelectionData>
|
||||||
<PersistentDeviceSelectionData>
|
<PersistentDeviceSelectionData>
|
||||||
<option name="api" value="34" />
|
<option name="api" value="34" />
|
||||||
<option name="brand" value="google" />
|
<option name="brand" value="google" />
|
||||||
|
19
README.md
19
README.md
@@ -2,10 +2,19 @@
|
|||||||
|
|
||||||
[](https://github.com/wismna/DoNext/actions/workflows/android.yaml)
|
[](https://github.com/wismna/DoNext/actions/workflows/android.yaml)
|
||||||
|
|
||||||
DoNext is an innovative task application.
|
DoNext is an a task app that aims for simplicity.
|
||||||
You can create and arrange task lists, create, edit and delete tasks...
|
You can create and arrange task lists, create, edit and delete tasks...
|
||||||
But the emphasis is not a long list, as the more you have to do, the less you actually do!
|
|
||||||
|
|
||||||
Instead, focus only on the first task on the list:
|
Focus on what's important:
|
||||||
Swipe it to the left: it's done!
|
- Tasks are sorted by priority
|
||||||
Swipe it to the right: "nexted!". It goes to the end of the list and you can work on the next task.
|
- Easily see when each task is due, with a warning when it's overdue
|
||||||
|
- All tasks due today are grouped in a special view
|
||||||
|
|
||||||
|
## Technical stack
|
||||||
|
|
||||||
|
DoNext is made with:
|
||||||
|
- Kotlin
|
||||||
|
- Jetpack Compose for UI
|
||||||
|
- Hilt for dependency injection
|
||||||
|
- Room for the Database
|
||||||
|
- Clean Architecture
|
||||||
|
@@ -22,7 +22,10 @@ android {
|
|||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
isMinifyEnabled = false
|
// Enables code-related app optimization.
|
||||||
|
isMinifyEnabled = true
|
||||||
|
// Enables resource shrinking.
|
||||||
|
isShrinkResources = true
|
||||||
proguardFiles(
|
proguardFiles(
|
||||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||||
"proguard-rules.pro"
|
"proguard-rules.pro"
|
||||||
@@ -48,25 +51,26 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.9.4")
|
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.9.4")
|
||||||
implementation("androidx.activity:activity-compose:1.11.0")
|
implementation("androidx.activity:activity-compose:1.11.0")
|
||||||
implementation(platform("androidx.compose:compose-bom:2025.09.00"))
|
implementation(platform("androidx.compose:compose-bom:2025.09.01"))
|
||||||
implementation("androidx.compose.ui:ui")
|
implementation("androidx.compose.ui:ui")
|
||||||
implementation("androidx.compose.ui:ui-graphics")
|
implementation("androidx.compose.ui:ui-graphics")
|
||||||
implementation("androidx.compose.ui:ui-tooling-preview")
|
implementation("androidx.compose.ui:ui-tooling-preview")
|
||||||
implementation("androidx.compose.material3:material3")
|
implementation("androidx.compose.material3:material3")
|
||||||
implementation("androidx.navigation:navigation-compose:2.9.4")
|
implementation("androidx.compose.material:material-icons-extended:1.7.8")
|
||||||
|
implementation("androidx.navigation:navigation-compose:2.9.5")
|
||||||
implementation("androidx.hilt:hilt-navigation-compose:1.3.0")
|
implementation("androidx.hilt:hilt-navigation-compose:1.3.0")
|
||||||
implementation("androidx.test.ext:junit-ktx:1.3.0")
|
implementation("androidx.test.ext:junit-ktx:1.3.0")
|
||||||
implementation("sh.calvin.reorderable:reorderable:3.0.0")
|
implementation("sh.calvin.reorderable:reorderable:3.0.0")
|
||||||
androidTestImplementation(platform("androidx.compose:compose-bom:2025.09.00"))
|
androidTestImplementation(platform("androidx.compose:compose-bom:2025.09.01"))
|
||||||
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
|
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
|
||||||
debugImplementation("androidx.compose.ui:ui-tooling")
|
debugImplementation("androidx.compose.ui:ui-tooling")
|
||||||
debugImplementation("androidx.compose.ui:ui-test-manifest")
|
debugImplementation("androidx.compose.ui:ui-test-manifest")
|
||||||
|
|
||||||
val roomVersion = "2.8.0"
|
val roomVersion = "2.8.1"
|
||||||
implementation("androidx.room:room-runtime:$roomVersion")
|
implementation("androidx.room:room-runtime:$roomVersion")
|
||||||
ksp("androidx.room:room-compiler:$roomVersion")
|
ksp("androidx.room:room-compiler:$roomVersion")
|
||||||
|
|
||||||
val hiltVersion = "2.57.1"
|
val hiltVersion = "2.57.2"
|
||||||
implementation("com.google.dagger:hilt-android:$hiltVersion")
|
implementation("com.google.dagger:hilt-android:$hiltVersion")
|
||||||
ksp("com.google.dagger:hilt-android-compiler:$hiltVersion")
|
ksp("com.google.dagger:hilt-android-compiler:$hiltVersion")
|
||||||
}
|
}
|
||||||
|
@@ -145,7 +145,7 @@ fun AppContent(
|
|||||||
}
|
}
|
||||||
is AppDestination.RecycleBin -> {
|
is AppDestination.RecycleBin -> {
|
||||||
TextButton(onClick = { viewModel.emptyRecycleBin() }) {
|
TextButton(onClick = { viewModel.emptyRecycleBin() }) {
|
||||||
Text(text = "Empty Recycle Bin", color = MaterialTheme.colorScheme.onPrimary)
|
Text(text = "Empty Recycle Bin", color = MaterialTheme.colorScheme.onPrimaryContainer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
|
@@ -20,6 +20,7 @@ import androidx.compose.material.icons.Icons
|
|||||||
import androidx.compose.material.icons.filled.Check
|
import androidx.compose.material.icons.filled.Check
|
||||||
import androidx.compose.material.icons.filled.Close
|
import androidx.compose.material.icons.filled.Close
|
||||||
import androidx.compose.material.icons.filled.Delete
|
import androidx.compose.material.icons.filled.Delete
|
||||||
|
import androidx.compose.material.icons.filled.DragHandle
|
||||||
import androidx.compose.material.icons.filled.Edit
|
import androidx.compose.material.icons.filled.Edit
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
@@ -70,7 +71,7 @@ fun ManageListsScreen(
|
|||||||
)
|
)
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = modifier.fillMaxWidth(),
|
modifier = modifier.fillMaxWidth().padding(start = 10.dp, end = 10.dp),
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
contentPadding = PaddingValues(vertical = 8.dp),
|
contentPadding = PaddingValues(vertical = 8.dp),
|
||||||
state = lazyListState
|
state = lazyListState
|
||||||
@@ -133,6 +134,7 @@ fun ManageListsScreen(
|
|||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
|
Icon(Icons.Default.DragHandle, contentDescription = "Edit")
|
||||||
AnimatedContent(
|
AnimatedContent(
|
||||||
targetState = isInEditMode,
|
targetState = isInEditMode,
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
|
@@ -7,10 +7,10 @@ import androidx.compose.foundation.layout.fillMaxHeight
|
|||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.List
|
|
||||||
import androidx.compose.material.icons.filled.DateRange
|
|
||||||
import androidx.compose.material.icons.filled.Delete
|
import androidx.compose.material.icons.filled.Delete
|
||||||
import androidx.compose.material.icons.filled.Edit
|
import androidx.compose.material.icons.filled.EditNote
|
||||||
|
import androidx.compose.material.icons.filled.LineWeight
|
||||||
|
import androidx.compose.material.icons.filled.Today
|
||||||
import androidx.compose.material3.Badge
|
import androidx.compose.material3.Badge
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
@@ -56,7 +56,7 @@ fun MenuScreen(
|
|||||||
Text(viewModel.dueTodayTasksCount.toString())
|
Text(viewModel.dueTodayTasksCount.toString())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
icon = { Icon(Icons.Default.DateRange, contentDescription = "Due Today") },
|
icon = { Icon(Icons.Default.Today, contentDescription = "Due Today") },
|
||||||
selected = currentDestination is AppDestination.DueTodayList,
|
selected = currentDestination is AppDestination.DueTodayList,
|
||||||
onClick = { onNavigate(AppDestination.DueTodayList.route) },
|
onClick = { onNavigate(AppDestination.DueTodayList.route) },
|
||||||
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
|
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
|
||||||
@@ -71,7 +71,7 @@ fun MenuScreen(
|
|||||||
overflow = TextOverflow.Ellipsis
|
overflow = TextOverflow.Ellipsis
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
icon = { Icon(Icons.AutoMirrored.Default.List, contentDescription = list.name) },
|
icon = { Icon(Icons.Default.LineWeight, contentDescription = list.name) },
|
||||||
selected = currentDestination is AppDestination.TaskList &&
|
selected = currentDestination is AppDestination.TaskList &&
|
||||||
currentDestination.taskListId == list.id,
|
currentDestination.taskListId == list.id,
|
||||||
onClick = { onNavigate("taskList/${list.id}") },
|
onClick = { onNavigate("taskList/${list.id}") },
|
||||||
@@ -96,7 +96,7 @@ fun MenuScreen(
|
|||||||
)
|
)
|
||||||
NavigationDrawerItem(
|
NavigationDrawerItem(
|
||||||
label = { Text("Edit Lists") },
|
label = { Text("Edit Lists") },
|
||||||
icon = { Icon(Icons.Default.Edit, contentDescription = "Edit Lists") },
|
icon = { Icon(Icons.Default.EditNote, contentDescription = "Edit Lists") },
|
||||||
selected = currentDestination is AppDestination.ManageLists,
|
selected = currentDestination is AppDestination.ManageLists,
|
||||||
onClick = { onNavigate(AppDestination.ManageLists.route) },
|
onClick = { onNavigate(AppDestination.ManageLists.route) },
|
||||||
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
|
modifier = Modifier.padding(NavigationDrawerItemDefaults.ItemPadding)
|
||||||
|
@@ -12,11 +12,11 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.AddCircle
|
|
||||||
import androidx.compose.material.icons.filled.CheckCircle
|
import androidx.compose.material.icons.filled.CheckCircle
|
||||||
import androidx.compose.material.icons.filled.Clear
|
import androidx.compose.material.icons.filled.DeleteForever
|
||||||
import androidx.compose.material.icons.filled.Delete
|
import androidx.compose.material.icons.filled.DeleteOutline
|
||||||
import androidx.compose.material.icons.filled.PlayArrow
|
import androidx.compose.material.icons.filled.RestoreFromTrash
|
||||||
|
import androidx.compose.material.icons.filled.Unpublished
|
||||||
import androidx.compose.material3.Badge
|
import androidx.compose.material3.Badge
|
||||||
import androidx.compose.material3.Card
|
import androidx.compose.material3.Card
|
||||||
import androidx.compose.material3.CardDefaults
|
import androidx.compose.material3.CardDefaults
|
||||||
@@ -49,6 +49,7 @@ fun TaskItemScreen(
|
|||||||
onSwipeLeft: () -> Unit,
|
onSwipeLeft: () -> Unit,
|
||||||
onSwipeRight: () -> Unit
|
onSwipeRight: () -> Unit
|
||||||
) {
|
) {
|
||||||
|
// TODO: change this
|
||||||
val dismissState = rememberSwipeToDismissBoxState(
|
val dismissState = rememberSwipeToDismissBoxState(
|
||||||
confirmValueChange = {
|
confirmValueChange = {
|
||||||
when (it) {
|
when (it) {
|
||||||
@@ -183,7 +184,7 @@ fun DismissBackground(dismissState: SwipeToDismissBoxState, isDone: Boolean, isD
|
|||||||
) {
|
) {
|
||||||
Column (horizontalAlignment = Alignment.CenterHorizontally) {
|
Column (horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
Icon(
|
Icon(
|
||||||
if (isDeleted) Icons.Default.Clear else Icons.Default.Delete,
|
if (isDeleted) Icons.Default.DeleteForever else Icons.Default.DeleteOutline,
|
||||||
tint = Color.LightGray,
|
tint = Color.LightGray,
|
||||||
contentDescription = "Delete"
|
contentDescription = "Delete"
|
||||||
)
|
)
|
||||||
@@ -196,15 +197,15 @@ fun DismissBackground(dismissState: SwipeToDismissBoxState, isDone: Boolean, isD
|
|||||||
Spacer(modifier = Modifier)
|
Spacer(modifier = Modifier)
|
||||||
Column (horizontalAlignment = Alignment.CenterHorizontally) {
|
Column (horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
Icon(
|
Icon(
|
||||||
if (isDeleted) Icons.Default.AddCircle else
|
if (isDeleted) Icons.Default.RestoreFromTrash else
|
||||||
if (isDone) Icons.Default.PlayArrow else Icons.Default.CheckCircle,
|
if (isDone) Icons.Default.Unpublished else Icons.Default.CheckCircle,
|
||||||
tint = Color.LightGray,
|
tint = Color.LightGray,
|
||||||
contentDescription = "Archive"
|
contentDescription = "Archive"
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
color = MaterialTheme.colorScheme.onPrimary,
|
color = MaterialTheme.colorScheme.onPrimary,
|
||||||
fontSize = 10.sp,
|
fontSize = 10.sp,
|
||||||
text = if (isDeleted) "Restore" else if (isDone) "Active" else "Done"
|
text = if (isDeleted) "Restore" else if (isDone) "Undone" else "Done"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,8 +8,8 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.CalendarMonth
|
||||||
import androidx.compose.material.icons.filled.Clear
|
import androidx.compose.material.icons.filled.Clear
|
||||||
import androidx.compose.material.icons.filled.DateRange
|
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.ButtonDefaults
|
import androidx.compose.material3.ButtonDefaults
|
||||||
import androidx.compose.material3.DatePicker
|
import androidx.compose.material3.DatePicker
|
||||||
@@ -127,7 +127,7 @@ fun TaskBottomSheet(
|
|||||||
IconButton(
|
IconButton(
|
||||||
onClick = { showDatePicker = true },
|
onClick = { showDatePicker = true },
|
||||||
enabled = !viewModel.isDone) {
|
enabled = !viewModel.isDone) {
|
||||||
Icon(Icons.Default.DateRange, contentDescription = "Pick due date")
|
Icon(Icons.Default.CalendarMonth, contentDescription = "Pick due date")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user