improvement: Show category in passkeys directory and correctly select items with the same name

This commit is contained in:
Artem Chepurnoy 2024-03-30 13:12:11 +02:00
parent b402e038bc
commit e0949a7042
No known key found for this signature in database
GPG Key ID: FAC37D0CF674043E
8 changed files with 618 additions and 107 deletions

View File

@ -1,6 +1,7 @@
import json
import requests
import argparse
import hashlib
parser = argparse.ArgumentParser("update_passkeys")
parser.add_argument("api_key", help="An API Key to access the https://passkeys.directory/ backend.", type=str)
@ -23,8 +24,14 @@ response = requests.get(
aggr = []
for site in response.json():
# generate a unique id
id_str = site['name'] + '|' + site['domain'] + '|' + (site.get('created_at') or '')
id = hashlib\
.md5(id_str.encode('utf-8'))\
.hexdigest()
features = []
entry = {
'id': id,
'name': site['name'],
'domain': site['domain'],
'features': features,
@ -36,6 +43,8 @@ for site in response.json():
append_if_not_empty('documentation_link', 'documentation')
append_if_not_empty('setup_link', 'setup')
append_if_not_empty('category', 'category')
append_if_not_empty('created_at', 'created_at')
append_if_not_empty('notes', 'notes')
# convert features to a list

View File

@ -1,11 +1,16 @@
package com.artemchep.keyguard.common.service.passkey
import kotlinx.datetime.Instant
data class PassKeyServiceInfo(
val id: String,
val name: String,
val domain: String,
val domains: Set<String> = emptySet(),
val setup: String? = null,
val documentation: String? = null,
val notes: String? = null,
val category: String? = null,
val addedAt: Instant? = null,
val features: Set<String> = emptySet(),
)

View File

@ -8,6 +8,7 @@ import com.artemchep.keyguard.common.service.passkey.PassKeyServiceInfo
import com.artemchep.keyguard.common.service.text.TextService
import com.artemchep.keyguard.common.service.text.readFromResourcesAsText
import com.artemchep.keyguard.res.Res
import kotlinx.datetime.Instant
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
@ -16,6 +17,7 @@ import org.kodein.di.instance
@Serializable
data class PassKeyEntity(
val id: String,
val name: String,
val domain: String,
@SerialName("additional-domains")
@ -23,17 +25,23 @@ data class PassKeyEntity(
val setup: String? = null,
val documentation: String? = null,
val notes: String? = null,
val category: String? = null,
@SerialName("created_at")
val createdAt: Instant? = null,
val features: Set<String> = emptySet(),
)
fun PassKeyEntity.toDomain() = kotlin.run {
PassKeyServiceInfo(
id = id,
name = name,
domain = domain,
domains = domains + domain,
setup = setup,
documentation = documentation,
notes = notes,
category = category,
addedAt = createdAt,
features = features,
)
}

View File

@ -258,7 +258,7 @@ private fun AppItem(
val nextEntry = navigationNextEntryOrNull()
val nextRoute = nextEntry?.route as? PasskeysServiceViewFullRoute
val selected = nextRoute?.args?.model?.name == item.name.text
val selected = nextRoute?.args?.model?.id == item.data.id
if (selected) {
return@run MaterialTheme.colorScheme.selectedContainer
}

View File

@ -82,10 +82,10 @@ fun producePasskeysListState(
.map { serviceInfo ->
val key = kotlin.run {
val newNameCollisionCounter = nameCollisions
.getOrDefault(serviceInfo.name, 0) + 1
nameCollisions[serviceInfo.name] =
.getOrDefault(serviceInfo.id, 0) + 1
nameCollisions[serviceInfo.id] =
newNameCollisionCounter
serviceInfo.name + ":" + newNameCollisionCounter
serviceInfo.id + ":" + newNameCollisionCounter
}
val faviconUrl = serviceInfo.documentation?.let { url ->
FaviconUrl(

View File

@ -29,6 +29,7 @@ import androidx.compose.ui.unit.dp
import com.artemchep.keyguard.common.model.Loadable
import com.artemchep.keyguard.common.model.getOrNull
import com.artemchep.keyguard.feature.dialog.Dialog
import com.artemchep.keyguard.feature.home.vault.component.Section
import com.artemchep.keyguard.feature.navigation.NavigationIcon
import com.artemchep.keyguard.feature.tfa.directory.FlatLaunchBrowserItem
import com.artemchep.keyguard.res.Res
@ -194,14 +195,26 @@ fun ColumnScope.Content(
.padding(horizontal = Dimens.horizontalPadding),
markdown = notes,
)
Spacer(
}
val category = state?.model?.category
if (category != null) {
Section(
text = stringResource(Res.strings.category),
)
Text(
modifier = Modifier
.height(16.dp),
.padding(horizontal = Dimens.horizontalPadding),
text = category,
)
}
val documentationUrl = state?.model?.documentation
if (documentationUrl != null) {
Spacer(
modifier = Modifier
.height(16.dp),
)
FlatLaunchBrowserItem(
title = stringResource(Res.strings.uri_action_launch_docs_title),
url = documentationUrl,

View File

@ -89,6 +89,7 @@
<string name="organizations">Organizations</string>
<string name="organizations_empty_label">No organizations</string>
<string name="misc">Miscellaneous</string>
<string name="category">Category</string>
<string name="command">Command</string>
<string name="execute_command">Execute</string>
<!-- Add (something) -->

File diff suppressed because it is too large Load Diff