Skip to content

Commit

Permalink
Merge pull request #97 from mudkipme/feat/open-api-to-id
Browse files Browse the repository at this point in the history
feat: switch to login with Open ID
  • Loading branch information
mudkipme authored Jul 29, 2023
2 parents d02700a + fd31608 commit e9e027f
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 36 deletions.
1 change: 1 addition & 0 deletions .idea/gradle.xml

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

2 changes: 1 addition & 1 deletion .idea/misc.xml

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

76 changes: 54 additions & 22 deletions app/src/main/java/me/mudkip/moememos/ui/page/login/LoginPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import me.mudkip.moememos.viewmodel.LocalUserState

private enum class LoginMethod {
USERNAME_AND_PASSWORD,
OPEN_API
OPEN_ID
}

@OptIn(ExperimentalFoundationApi::class)
Expand All @@ -46,7 +46,7 @@ fun LoginPage(
var loginMethodMenuExpanded by remember { mutableStateOf(false) }
var loginMethod by remember { mutableStateOf(LoginMethod.USERNAME_AND_PASSWORD) }

var email by rememberSaveable(stateSaver = TextFieldValue.Saver) {
var username by rememberSaveable(stateSaver = TextFieldValue.Saver) {
mutableStateOf(TextFieldValue())
}

Expand All @@ -58,15 +58,19 @@ fun LoginPage(
mutableStateOf(TextFieldValue(userStateViewModel.host))
}

var openId by rememberSaveable(stateSaver = TextFieldValue.Saver) {
mutableStateOf(TextFieldValue())
}

fun login() = coroutineScope.launch {
if (host.text.isBlank() || (loginMethod == LoginMethod.USERNAME_AND_PASSWORD && (email.text.isBlank() || password.text.isEmpty()))) {
if (host.text.isBlank() || (loginMethod == LoginMethod.USERNAME_AND_PASSWORD && (username.text.isBlank() || password.text.isEmpty())) || (loginMethod == LoginMethod.OPEN_ID && openId.text.isBlank())) {
snackbarState.showSnackbar(R.string.fill_login_form.string)
return@launch
}

val resp = when(loginMethod) {
LoginMethod.USERNAME_AND_PASSWORD -> userStateViewModel.login(host.text.trim(), email.text.trim(), password.text)
LoginMethod.OPEN_API -> userStateViewModel.login(host.text.trim())
LoginMethod.USERNAME_AND_PASSWORD -> userStateViewModel.login(host.text.trim(), username.text.trim(), password.text)
LoginMethod.OPEN_ID -> userStateViewModel.login(host.text.trim(), openId.text.trim())
}

resp.suspendOnSuccess {
Expand Down Expand Up @@ -112,13 +116,13 @@ fun LoginPage(
}
)
DropdownMenuItem(
text = { Text(R.string.open_api.string) },
text = { Text(R.string.open_id.string) },
onClick = {
loginMethod = LoginMethod.OPEN_API
loginMethod = LoginMethod.OPEN_ID
loginMethodMenuExpanded = false
},
trailingIcon = {
if (loginMethod == LoginMethod.OPEN_API) {
if (loginMethod == LoginMethod.OPEN_ID) {
Icon(
Icons.Outlined.Check,
contentDescription = R.string.selected.string
Expand Down Expand Up @@ -186,27 +190,22 @@ fun LoginPage(
},
value = host,
onValueChange = { host = it },
singleLine = loginMethod == LoginMethod.USERNAME_AND_PASSWORD,
singleLine = true,
leadingIcon = {
Icon(
imageVector = Icons.Outlined.Computer,
contentDescription = R.string.address.string
)
},
label = {
if (loginMethod == LoginMethod.USERNAME_AND_PASSWORD) {
Text(R.string.host.string)
} else {
Text(R.string.open_api.string)
}
Text(R.string.host.string)
},
keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.None,
autoCorrect = false,
keyboardType = KeyboardType.Uri,
imeAction = if (loginMethod == LoginMethod.OPEN_API) ImeAction.Go else ImeAction.Next
),
keyboardActions = KeyboardActions(onGo = { login() })
imeAction = ImeAction.Next
)
)

if (loginMethod == LoginMethod.USERNAME_AND_PASSWORD) {
Expand All @@ -220,20 +219,20 @@ fun LoginPage(
}
}
},
value = email,
onValueChange = { email = it },
value = username,
onValueChange = { username = it },
singleLine = true,
leadingIcon = {
Icon(
imageVector = Icons.Outlined.Email,
contentDescription = R.string.email.string
imageVector = Icons.Outlined.Person,
contentDescription = R.string.username.string
)
},
label = { Text(R.string.username.string) },
keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.None,
autoCorrect = false,
keyboardType = KeyboardType.Email,
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
)
)
Expand Down Expand Up @@ -268,6 +267,39 @@ fun LoginPage(
keyboardActions = KeyboardActions(onGo = { login() })
)
}

if (loginMethod == LoginMethod.OPEN_ID) {
OutlinedTextField(
modifier = Modifier
.fillMaxWidth()
.onFocusEvent { focusState ->
if (focusState.isFocused) {
coroutineScope.launch {
bringIntoViewRequester.bringIntoView()
}
}
},
value = openId,
onValueChange = { openId = it },
singleLine = true,
leadingIcon = {
Icon(
imageVector = Icons.Outlined.PermIdentity,
contentDescription = R.string.open_id.string
)
},
label = {
Text(R.string.open_id.string)
},
keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.None,
autoCorrect = false,
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Go
),
keyboardActions = KeyboardActions(onGo = { login() })
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package me.mudkip.moememos.viewmodel

import android.net.Uri
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
Expand All @@ -17,7 +16,6 @@ import kotlinx.coroutines.withContext
import me.mudkip.moememos.R
import me.mudkip.moememos.data.api.MemosApiService
import me.mudkip.moememos.data.api.SignInInput
import me.mudkip.moememos.data.constant.MoeMemosException
import me.mudkip.moememos.data.model.Status
import me.mudkip.moememos.data.model.User
import me.mudkip.moememos.data.repository.UserRepository
Expand All @@ -43,10 +41,10 @@ class UserStateViewModel @Inject constructor(
}
}

suspend fun login(host: String, email: String, password: String): ApiResponse<User> = withContext(viewModelScope.coroutineContext) {
suspend fun login(host: String, username: String, password: String): ApiResponse<User> = withContext(viewModelScope.coroutineContext) {
try {
val (_, client) = memosApiService.createClient(host, null)
client.signIn(SignInInput(email, email, password)).getOrThrow()
client.signIn(SignInInput(username, username, password)).getOrThrow()
val resp = client.me()
if (resp.isSuccess) {
memosApiService.update(host, null)
Expand All @@ -58,15 +56,8 @@ class UserStateViewModel @Inject constructor(
}
}

suspend fun login(memosOpenApi: String): ApiResponse<User> = withContext(viewModelScope.coroutineContext) {
suspend fun login(host: String, openId: String): ApiResponse<User> = withContext(viewModelScope.coroutineContext) {
try {
val uri = Uri.parse(memosOpenApi)
val openId = uri.getQueryParameter("openId")
if (openId == null || openId.isEmpty()) {
throw MoeMemosException.invalidOpenAPI
}

val host = uri.buildUpon().path("/").clearQuery().fragment("").build().toString()
val resp = memosApiService.createClient(host, openId).second.me()
if (resp.isSuccess) {
memosApiService.update(host, openId)
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<string name="sign_in_method">Sign in method</string>
<string name="address">Address</string>
<string name="host">Host</string>
<string name="open_api" translatable="false">Open API</string>
<string name="open_id" translatable="false">Open ID</string>
<string name="edit">Edit</string>
<string name="close">Close</string>
<string name="add_task">Add Task</string>
Expand Down

0 comments on commit e9e027f

Please sign in to comment.