Skip to content

Commit

Permalink
Merge pull request #198 from PatilShreyas/v1.1.0-dev
Browse files Browse the repository at this point in the history
Improvements for Compose App
  • Loading branch information
PatilShreyas authored Aug 6, 2021
2 parents 2fe3ca7 + deb3c79 commit d1d6b19
Show file tree
Hide file tree
Showing 33 changed files with 670 additions and 357 deletions.
2 changes: 2 additions & 0 deletions docs/pages/noty-android/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,6 @@ For single source of data. Implements `local` and `remote` modules.

- [Jetpack Compose UI Toolkit](https://developer.android.com/jetpack/compose) - Modern UI development toolkit.

- [Accompanist](https://google.github.io/accompanist/) - Accompanist is a group of libraries that aim to supplement Jetpack Compose with features that are commonly required by developers but not yet available.

- [LeakCanary](https://square.github.io/leakcanary/) - Memory leak detection library for Android
1 change: 1 addition & 0 deletions noty-android/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ Design of this awesome application is implemented by [Sanju S](https://github.co
- [Moshi Converter](https://github.com/square/retrofit/tree/master/retrofit-converters/moshi) - A Converter which uses Moshi for serialization to and from JSON.
- [Material Components for Android](https://github.com/material-components/material-components-android) - Modular and customizable Material Design UI components for Android.
- [Jetpack Compose UI Toolkit](https://developer.android.com/jetpack/compose) - Modern UI development toolkit.
- [Accompanist](https://google.github.io/accompanist/) - Accompanist is a group of libraries that aim to supplement Jetpack Compose with features that are commonly required by developers but not yet available.
- [LeakCanary](https://square.github.io/leakcanary/) - Memory leak detection library for Android

## Modules
Expand Down
3 changes: 3 additions & 0 deletions noty-android/app/composeapp/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ dependencies {
// Compose Lifecycle
implementation "androidx.compose.runtime:runtime-livedata:$composeVersion"

// Accompanist
implementation "com.google.accompanist:accompanist-swiperefresh:$accompanistVersion"

// Navigation
implementation "androidx.navigation:navigation-compose:$composeNavVersion"

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright 2020 Shreyas Patil
*
* 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 dev.shreyaspatil.noty.composeapp.component.text

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import dev.shreyaspatil.noty.composeapp.ui.theme.getTextFieldHintColor

@Composable
fun NotyTextField(
value: String,
label: String,
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier,
fontSize: TextUnit = 16.sp,
color: Color = MaterialTheme.colors.onPrimary,
leadingIcon: @Composable() (() -> Unit)? = null,
isError: Boolean = false,
visualTransformation: VisualTransformation = VisualTransformation.None
) {
OutlinedTextField(
value = value,
label = { Text(text = label) },
modifier = modifier,
onValueChange = onValueChange,
leadingIcon = leadingIcon,
textStyle = TextStyle(color, fontSize = fontSize),
isError = isError,
visualTransformation = visualTransformation
)
}

@ExperimentalAnimationApi
@Composable
fun BasicNotyTextField(
modifier: Modifier = Modifier,
value: String = "",
label: String = "",
textStyle: TextStyle = TextStyle(fontSize = 16.sp, fontWeight = FontWeight.Normal),
onTextChange: (String) -> Unit,
maxLines: Int = Int.MAX_VALUE
) {

Box(modifier = modifier.padding(4.dp)) {
AnimatedVisibility(visible = value.isBlank()) {
Text(
text = label,
color = getTextFieldHintColor(),
fontSize = textStyle.fontSize,
fontWeight = textStyle.fontWeight
)
}
BasicTextField(
value = value,
onValueChange = onTextChange,
textStyle = textStyle.copy(color = MaterialTheme.colors.onPrimary),
maxLines = maxLines,
cursorBrush = SolidColor(MaterialTheme.colors.primary)
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright 2020 Shreyas Patil
*
* 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 dev.shreyaspatil.noty.composeapp.component.text

import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp

@ExperimentalAnimationApi
@Composable
fun NoteTitleField(
modifier: Modifier = Modifier,
value: String = "",
onTextChange: (String) -> Unit
) {
BasicNotyTextField(
modifier,
value = value,
label = "Title",
onTextChange = onTextChange,
textStyle = MaterialTheme.typography.h6,
maxLines = 2
)
}

@ExperimentalAnimationApi
@Composable
fun NoteField(
modifier: Modifier = Modifier,
value: String = "",
onTextChange: (String) -> Unit
) {
BasicNotyTextField(
modifier,
value = value,
label = "Write here",
onTextChange = onTextChange,
textStyle = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Light)
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright 2020 Shreyas Patil
*
* 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 dev.shreyaspatil.noty.composeapp.component.text

import androidx.compose.material.Icon
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Password
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.text.input.PasswordVisualTransformation
import dev.shreyaspatil.noty.utils.validator.AuthValidator.isPasswordAndConfirmPasswordSame
import dev.shreyaspatil.noty.utils.validator.AuthValidator.isValidPassword

@Composable
fun PasswordTextField(
modifier: Modifier = Modifier,
value: String = "",
onTextChange: (TextFieldValue<String>) -> Unit,
) {
var startedTyping by remember { mutableStateOf(false) }
var isValid by remember { mutableStateOf(false) }

NotyTextField(
value = value,
label = "Password",
onValueChange = {
isValid = isValidPassword(it)
onTextChange(if (isValid) TextFieldValue.Valid(it) else TextFieldValue.Invalid(it))
if (!startedTyping) {
startedTyping = true
}
},
modifier = modifier,
leadingIcon = { Icon(Icons.Outlined.Password, "Password") },
visualTransformation = PasswordVisualTransformation(),
isError = !isValid && startedTyping
)
}

@Composable
fun ConfirmPasswordTextField(
modifier: Modifier = Modifier,
value: String = "",
expectedValue: String = "",
onTextChange: (TextFieldValue<String>) -> Unit,
) {
var startedTyping by remember { mutableStateOf(false) }
var isValid by remember { mutableStateOf(false) }

NotyTextField(
value = value,
label = "Confirm Password",
onValueChange = {
isValid = isValidPassword(it) && isPasswordAndConfirmPasswordSame(expectedValue, it)
onTextChange(if (isValid) TextFieldValue.Valid(it) else TextFieldValue.Invalid(it))
if (!startedTyping) {
startedTyping = true
}
},
modifier = modifier,
leadingIcon = { Icon(Icons.Outlined.Password, "Confirm Password") },
visualTransformation = PasswordVisualTransformation(),
isError = !isValid && startedTyping
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2020 Shreyas Patil
*
* 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 dev.shreyaspatil.noty.composeapp.component.text

sealed class TextFieldValue<T>(val data: T) {
class Valid<T>(data: T) : TextFieldValue<T>(data)
class Invalid<T>(data: T) : TextFieldValue<T>(data)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2020 Shreyas Patil
*
* 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 dev.shreyaspatil.noty.composeapp.component.text

import androidx.compose.material.Icon
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Person
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 dev.shreyaspatil.noty.utils.validator.AuthValidator

@Composable
fun UsernameTextField(
modifier: Modifier = Modifier,
value: String = "",
onTextChange: (TextFieldValue<String>) -> Unit,
) {
var startedTyping by remember { mutableStateOf(false) }
var isValid by remember { mutableStateOf(false) }

NotyTextField(
value = value,
label = "Username",
onValueChange = {
isValid = AuthValidator.isValidUsername(it)
onTextChange(if (isValid) TextFieldValue.Valid(it) else TextFieldValue.Invalid(it))
if (!startedTyping) {
startedTyping = true
}
},
modifier = modifier,
leadingIcon = { Icon(Icons.Outlined.Person, "User") },
isError = !isValid && startedTyping
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package dev.shreyaspatil.noty.composeapp.navigation

import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.runtime.Composable
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavType
Expand All @@ -37,10 +38,11 @@ import kotlinx.coroutines.InternalCoroutinesApi

const val NOTY_NAV_HOST_ROUTE = "noty-main-route"

@ExperimentalAnimationApi
@InternalCoroutinesApi
@ExperimentalCoroutinesApi
@Composable
fun NotyNavigation(toggleTheme: () -> Unit) {
fun NotyNavigation() {
val navController = rememberNavController()

NavHost(navController, startDestination = Screen.Notes.route, route = NOTY_NAV_HOST_ROUTE) {
Expand All @@ -54,7 +56,7 @@ fun NotyNavigation(toggleTheme: () -> Unit) {
AddNoteScreen(navController, hiltViewModel())
}
composable(Screen.Notes.route) {
NotesScreen(toggleTheme, navController, hiltViewModel())
NotesScreen(navController, hiltViewModel())
}
composable(
Screen.NotesDetail.route,
Expand Down
Loading

0 comments on commit d1d6b19

Please sign in to comment.