1
0
Fork 0
mirror of https://github.com/anyproto/anytype-kotlin.git synced 2025-06-08 05:47:05 +09:00

DROID-2146 Objects | Enhancement | Allow pinning and unpinning types in the new object-creation panel (#771)

This commit is contained in:
Evgenii Kozlov 2024-01-16 16:10:52 +01:00 committed by GitHub
parent 60415edafd
commit e6acc965ff
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 461 additions and 37 deletions

View file

@ -3,6 +3,7 @@ plugins {
id "kotlin-android"
id "kotlin-kapt"
id "kotlinx-serialization"
id "com.squareup.wire"
}
dependencies {
@ -18,6 +19,7 @@ dependencies {
implementation libs.room
implementation libs.roomKtx
implementation libs.dataStore
kapt libs.annotations
@ -30,6 +32,7 @@ dependencies {
testImplementation libs.mockitoKotlin
testImplementation libs.robolectric
testImplementation libs.archCoreTesting
testImplementation libs.androidXTestCore
testImplementation libs.coroutineTesting
}
@ -42,4 +45,9 @@ android {
jvmToolchain(17)
}
namespace 'com.anytypeio.anytype.persistence'
}
wire {
protoPath { srcDir 'src/main/proto' }
kotlin {}
}

View file

@ -0,0 +1,23 @@
package com.anytypeio.anytype.persistence.preferences
import androidx.datastore.core.Serializer
import com.anytypeio.anytype.persistence.SpacePreferences
import java.io.InputStream
import java.io.OutputStream
object SpacePrefSerializer : Serializer<SpacePreferences> {
override val defaultValue: SpacePreferences = SpacePreferences()
override suspend fun readFrom(input: InputStream): SpacePreferences {
return SpacePreferences.ADAPTER.decode(input)
}
override suspend fun writeTo(t: SpacePreferences, output: OutputStream) {
SpacePreferences.ADAPTER.encode(
stream = output,
value = t
)
}
}
const val SPACE_PREFERENCE_FILENAME = "space-preferences.pb"

View file

@ -1,6 +1,9 @@
package com.anytypeio.anytype.persistence.repo
import android.content.Context
import android.content.SharedPreferences
import androidx.datastore.core.DataStore
import androidx.datastore.dataStore
import com.anytypeio.anytype.core_models.Id
import com.anytypeio.anytype.core_models.NO_VALUE
import com.anytypeio.anytype.core_models.ThemeMode
@ -9,6 +12,8 @@ import com.anytypeio.anytype.core_models.WidgetSession
import com.anytypeio.anytype.core_models.primitives.SpaceId
import com.anytypeio.anytype.core_models.primitives.TypeId
import com.anytypeio.anytype.data.auth.repo.UserSettingsCache
import com.anytypeio.anytype.persistence.SpacePreference
import com.anytypeio.anytype.persistence.SpacePreferences
import com.anytypeio.anytype.persistence.common.JsonString
import com.anytypeio.anytype.persistence.common.deserializeWallpaperSettings
import com.anytypeio.anytype.persistence.common.serializeWallpaperSettings
@ -16,8 +21,20 @@ import com.anytypeio.anytype.persistence.common.toJsonString
import com.anytypeio.anytype.persistence.common.toStringMap
import com.anytypeio.anytype.persistence.model.asSettings
import com.anytypeio.anytype.persistence.model.asWallpaper
import com.anytypeio.anytype.persistence.preferences.SPACE_PREFERENCE_FILENAME
import com.anytypeio.anytype.persistence.preferences.SpacePrefSerializer
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
class DefaultUserSettingsCache(private val prefs: SharedPreferences) : UserSettingsCache {
class DefaultUserSettingsCache(
private val prefs: SharedPreferences,
private val context: Context
) : UserSettingsCache {
private val Context.spacePrefsStore: DataStore<SpacePreferences> by dataStore(
fileName = SPACE_PREFERENCE_FILENAME,
serializer = SpacePrefSerializer
)
override suspend fun setCurrentSpace(space: SpaceId) {
prefs.edit()
@ -46,6 +63,22 @@ class DefaultUserSettingsCache(private val prefs: SharedPreferences) : UserSetti
.edit()
.putString(DEFAULT_OBJECT_TYPES_KEY, updated.toJsonString())
.apply()
context
.spacePrefsStore
.updateData { prefs ->
val givenSpacePreferences = prefs.preferences.getOrDefault(
space.id,
SpacePreference()
)
val updatedSpacePreferences = givenSpacePreferences.copy(
defaultObjectTypeKey = type.id
)
val result = prefs.preferences + mapOf(space.id to updatedSpacePreferences)
prefs.copy(preferences = result)
}
}
override suspend fun getDefaultObjectType(space: SpaceId): TypeId? {
@ -168,7 +201,41 @@ class DefaultUserSettingsCache(private val prefs: SharedPreferences) : UserSetti
.apply()
}
override suspend fun setPinnedObjectTypes(space: SpaceId, types: List<TypeId>) {
context.spacePrefsStore.updateData { existingPreferences ->
val givenSpacePreference = existingPreferences
.preferences
.getOrDefault(key = space.id, defaultValue = SpacePreference())
val updated = givenSpacePreference.copy(
pinnedObjectTypeKeys = types.map { type -> type.id }
)
val result = buildMap {
putAll(existingPreferences.preferences)
put(key = space.id, updated)
}
SpacePreferences(
preferences = result
)
}
}
override fun getPinnedObjectTypes(space: SpaceId): Flow<List<TypeId>> {
return context.spacePrefsStore
.data
.map { preferences ->
preferences
.preferences[space.id]
?.pinnedObjectTypeKeys?.map { id -> TypeId(id) } ?: emptyList()
}
}
override suspend fun clear() {
// Clearing shared preferences
prefs.edit()
.remove(DEFAULT_OBJECT_TYPE_ID_KEY)
.remove(DEFAULT_OBJECT_TYPE_NAME_KEY)
@ -176,6 +243,12 @@ class DefaultUserSettingsCache(private val prefs: SharedPreferences) : UserSetti
.remove(ACTIVE_WIDGETS_VIEWS_KEY)
.remove(CURRENT_SPACE_KEY)
.apply()
// Clearing data stores
context.spacePrefsStore.updateData {
SpacePreferences(emptyMap())
}
}
companion object {

View file

@ -0,0 +1,14 @@
syntax = "proto3";
option java_package = "com.anytypeio.anytype.persistence";
option java_multiple_files = true;
message SpacePreferences {
// maps space id to space preference
map <string, SpacePreference> preferences = 1;
}
message SpacePreference {
optional string defaultObjectTypeKey = 1;
repeated string pinnedObjectTypeKeys = 2;
}

View file

@ -2,6 +2,7 @@ package com.anytypeio.anytype.persistence
import android.content.Context
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.test.core.app.ApplicationProvider
import com.anytypeio.anytype.core_models.Wallpaper
import com.anytypeio.anytype.core_models.primitives.SpaceId
import com.anytypeio.anytype.core_models.primitives.TypeId
@ -32,7 +33,8 @@ class UserSettingsCacheTest {
fun `should save and return default wallpaper`() = runTest {
val cache = DefaultUserSettingsCache(
prefs = defaultPrefs
prefs = defaultPrefs,
context = ApplicationProvider.getApplicationContext()
)
val space = MockDataFactory.randomUuid()
@ -55,7 +57,8 @@ class UserSettingsCacheTest {
fun `should save and return gradient wallpaper`() = runTest {
val cache = DefaultUserSettingsCache(
prefs = defaultPrefs
prefs = defaultPrefs,
context = ApplicationProvider.getApplicationContext()
)
val space = MockDataFactory.randomUuid()
@ -81,7 +84,8 @@ class UserSettingsCacheTest {
fun `should not save wallpaper if space id is empty, should return default`() = runTest {
val cache = DefaultUserSettingsCache(
prefs = defaultPrefs
prefs = defaultPrefs,
context = ApplicationProvider.getApplicationContext()
)
val space = ""
@ -108,7 +112,8 @@ class UserSettingsCacheTest {
fun `should save and return solid-color wallpaper`() = runTest {
val cache = DefaultUserSettingsCache(
prefs = defaultPrefs
prefs = defaultPrefs,
context = ApplicationProvider.getApplicationContext()
)
val space = MockDataFactory.randomUuid()
@ -134,7 +139,8 @@ class UserSettingsCacheTest {
fun `should save and return image wallpaper`() = runTest {
val cache = DefaultUserSettingsCache(
prefs = defaultPrefs
prefs = defaultPrefs,
context = ApplicationProvider.getApplicationContext()
)
val space = MockDataFactory.randomUuid()
@ -160,7 +166,8 @@ class UserSettingsCacheTest {
fun `should return default wallpaper`() = runTest {
val cache = DefaultUserSettingsCache(
prefs = defaultPrefs
prefs = defaultPrefs,
context = ApplicationProvider.getApplicationContext()
)
val space = MockDataFactory.randomUuid()
@ -178,7 +185,8 @@ class UserSettingsCacheTest {
fun `should save new default object type for given space`() = runTest {
val cache = DefaultUserSettingsCache(
prefs = defaultPrefs
prefs = defaultPrefs,
context = ApplicationProvider.getApplicationContext()
)
val space = SpaceId(MockDataFactory.randomUuid())
@ -210,7 +218,8 @@ class UserSettingsCacheTest {
fun `should save default object type for two given spaces`() = runTest {
val cache = DefaultUserSettingsCache(
prefs = defaultPrefs
prefs = defaultPrefs,
context = ApplicationProvider.getApplicationContext()
)
val space1 = SpaceId(MockDataFactory.randomUuid())