Compare commits
89 Commits
main
...
droid-2107
Author | SHA1 | Date | |
---|---|---|---|
|
4b3bdf197c | ||
|
de027e3563 | ||
|
615f8a8615 | ||
|
cd4209ff9a | ||
|
a79e607835 | ||
|
7f996c455a | ||
|
175ca75128 | ||
|
64882b7d9c | ||
|
788341aa78 | ||
|
2da8d90603 | ||
|
8b2c4124cc | ||
|
d41bdd0a37 | ||
|
25bc621903 | ||
|
ac507dcc2d | ||
|
24c27a0dbc | ||
|
3ce80bfefc | ||
|
9b0c51fd5a | ||
|
bf62043064 | ||
|
e8ccfad117 | ||
|
d838cdeac4 | ||
|
00c742b3d9 | ||
|
6ed11ecf45 | ||
|
cd7336cc9f | ||
|
d295876ca8 | ||
|
30d39bdf94 | ||
|
12960b027d | ||
|
8db6837471 | ||
|
ca0e79f3ea | ||
|
4a251354ab | ||
|
d1558add81 | ||
|
11195df494 | ||
|
01c729216f | ||
|
08531d8393 | ||
|
79ff246858 | ||
|
e25023edc3 | ||
|
d6906b73be | ||
|
fbc7a25b1c | ||
|
c58ec46924 | ||
|
e527260faf | ||
|
5c056aebf5 | ||
|
c36a90b2e6 | ||
|
3f13e93d15 | ||
|
9db9234c2c | ||
|
8feab35098 | ||
|
c0d9bcc89b | ||
|
f53be3f926 | ||
|
ec52dff7fb | ||
|
10cccab7fd | ||
|
231c6eda2f | ||
|
b663cd5960 | ||
|
915e54c037 | ||
|
968c4e1f35 | ||
|
25d985c448 | ||
|
ce96af8cd9 | ||
|
665eb8d9e8 | ||
|
1114cc3517 | ||
|
9c65811634 | ||
|
a5df9cc362 | ||
|
438162cdfb | ||
|
9c52ef4c6b | ||
|
d64d4f00c4 | ||
|
aed9f1a720 | ||
|
8b41c9cd34 | ||
|
d7434e7336 | ||
|
ecb75efbe7 | ||
|
ba76dc3535 | ||
|
bf3a0d73ff | ||
|
26a23de502 | ||
|
dcb75d5e7f | ||
|
7f78502cb0 | ||
|
482534edca | ||
|
0f8eb37456 | ||
|
4853266507 | ||
|
98b48aab7d | ||
|
b7543cbec9 | ||
|
55885effb5 | ||
|
2a4e5b267c | ||
|
18a53cc916 | ||
|
bc2099f57c | ||
|
ecacddeade | ||
|
21045d92a6 | ||
|
3243280555 | ||
|
8f4cdb1ec5 | ||
|
584afe0e97 | ||
|
55ebc87413 | ||
|
968b1fd385 | ||
|
5e5e4b0768 | ||
|
4fc3ff43fd | ||
|
0b1cd7b17f |
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -19,5 +19,4 @@
|
|||
.externalNativeBuild
|
||||
ktlint
|
||||
.idea/*.xml
|
||||
signing.properties
|
||||
network.properties
|
||||
signing.properties
|
|
@ -13,6 +13,16 @@ android {
|
|||
buildConfigField "boolean", "SEND_EVENTS", getProperty('config.enableAnalyticsForDebugBuilds')
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(17)
|
||||
}
|
||||
|
||||
namespace 'com.anytypeio.anytype.analytics'
|
||||
}
|
||||
|
||||
|
|
|
@ -184,6 +184,17 @@ object EventsDictionary {
|
|||
const val MENU_HELP_PRIVACY = "MenuHelpPrivacy"
|
||||
const val MENU_HELP_CONTACT_US = "MenuHelpContact"
|
||||
|
||||
// Sharing extension
|
||||
|
||||
const val CLICK_ONBOARDING_TOOLTIP = "ClickOnboardingTooltip"
|
||||
const val CLICK_ONBOARDING_TOOLTIP_ID_SHARING_EXTENSION = "SharingExtension"
|
||||
const val CLICK_ONBOARDING_TOOLTIP_TYPE_SHARING_MENU = "ShareMenu"
|
||||
const val CLICK_ONBOARDING_TOOLTIP_TYPE_CLOSE = "Close"
|
||||
|
||||
// Network mode
|
||||
const val selectNetwork = "SelectNetwork"
|
||||
const val uploadNetworkConfiguration = "UploadNetworkConfiguration"
|
||||
|
||||
enum class ScreenOnboardingStep(val value: String) {
|
||||
VOID("Void"),
|
||||
PHRASE("Phrase"),
|
||||
|
@ -218,6 +229,8 @@ object EventsDictionary {
|
|||
const val settings = "Settings"
|
||||
const val screenDeletion = "ScreenDeletion"
|
||||
const val navigation = "Navigation"
|
||||
const val longTap = "LongTap"
|
||||
const val sharingExtension = "SharingExtension"
|
||||
}
|
||||
|
||||
object Type {
|
||||
|
@ -228,6 +241,9 @@ object EventsDictionary {
|
|||
const val dataView = "dataview"
|
||||
const val block = "block"
|
||||
const val bookmark = "bookmark"
|
||||
const val anytype = "Anytype"
|
||||
const val localOnly = "LocalOnly"
|
||||
const val selfHost = "SelfHost"
|
||||
}
|
||||
|
||||
object BlockAction {
|
||||
|
@ -254,6 +270,7 @@ object EventsDictionary {
|
|||
}
|
||||
|
||||
object EventsPropertiesKey {
|
||||
const val id = "id"
|
||||
const val tab = "tab"
|
||||
const val route = "route"
|
||||
const val type = "type"
|
||||
|
|
|
@ -118,15 +118,6 @@ android {
|
|||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
|
||||
composeOptions {
|
||||
kotlinCompilerExtensionVersion libs.versions.composeKotlinCompilerVersion.get()
|
||||
}
|
||||
|
@ -136,6 +127,15 @@ android {
|
|||
compose true
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(17)
|
||||
}
|
||||
|
||||
splits {
|
||||
// Configures multiple APKs based on ABI.
|
||||
abi {
|
||||
|
@ -151,16 +151,6 @@ android {
|
|||
namespace 'com.anytypeio.anytype'
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(11))
|
||||
}
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(11))
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation project(':domain')
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
version.versionMajor=0
|
||||
version.versionMinor=27
|
||||
version.versionPatch=0
|
||||
version.versionPatch=15
|
||||
version.useDatedVersionName=false
|
|
@ -21,6 +21,7 @@ import com.anytypeio.anytype.domain.`object`.ReloadObject
|
|||
import com.anytypeio.anytype.domain.objects.DefaultObjectStore
|
||||
import com.anytypeio.anytype.domain.objects.DefaultStoreOfRelations
|
||||
import com.anytypeio.anytype.domain.objects.ObjectStore
|
||||
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
|
||||
import com.anytypeio.anytype.domain.objects.StoreOfRelations
|
||||
import com.anytypeio.anytype.presentation.relations.providers.DataViewObjectRelationProvider
|
||||
import com.anytypeio.anytype.presentation.relations.providers.DataViewObjectValueProvider
|
||||
|
@ -57,6 +58,9 @@ class DisplayObjectRelationTextValueTest {
|
|||
@Mock
|
||||
lateinit var analytics: Analytics
|
||||
|
||||
@Mock
|
||||
lateinit var storeOfObjectTypes: StoreOfObjectTypes
|
||||
|
||||
val root = MockDataFactory.randomUuid()
|
||||
|
||||
private val state: MutableStateFlow<ObjectState> = MutableStateFlow(ObjectState.Init)
|
||||
|
@ -74,7 +78,8 @@ class DisplayObjectRelationTextValueTest {
|
|||
),
|
||||
values = DataViewObjectValueProvider(db = db, objectState = state),
|
||||
reloadObject = reloadObject,
|
||||
analytics = analytics
|
||||
analytics = analytics,
|
||||
storeOfObjectTypes = storeOfObjectTypes
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import com.anytypeio.anytype.domain.`object`.ReloadObject
|
|||
import com.anytypeio.anytype.domain.objects.DefaultObjectStore
|
||||
import com.anytypeio.anytype.domain.objects.DefaultStoreOfRelations
|
||||
import com.anytypeio.anytype.domain.objects.ObjectStore
|
||||
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
|
||||
import com.anytypeio.anytype.domain.objects.StoreOfRelations
|
||||
import com.anytypeio.anytype.presentation.relations.providers.DataViewObjectRelationProvider
|
||||
import com.anytypeio.anytype.presentation.relations.providers.DataViewObjectValueProvider
|
||||
|
@ -59,6 +60,9 @@ class DisplayRelationNumberValueTest {
|
|||
@Mock
|
||||
lateinit var analytics: Analytics
|
||||
|
||||
@Mock
|
||||
lateinit var storeOfObjectTypes: StoreOfObjectTypes
|
||||
|
||||
@get:Rule
|
||||
val animationsRule = DisableAnimationsRule()
|
||||
|
||||
|
@ -81,7 +85,8 @@ class DisplayRelationNumberValueTest {
|
|||
),
|
||||
values = DataViewObjectValueProvider(db = db, objectState = state),
|
||||
reloadObject = reloadObject,
|
||||
analytics = analytics
|
||||
analytics = analytics,
|
||||
storeOfObjectTypes = storeOfObjectTypes
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,11 @@
|
|||
<data android:scheme="anytype"
|
||||
android:host="main" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="text/plain" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.settings.system.SettingsActivity"
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.anytypeio.anytype.di.common
|
|||
import android.content.Context
|
||||
import com.anytypeio.anytype.BuildConfig
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.primitives.TypeKey
|
||||
import com.anytypeio.anytype.di.feature.AddDataViewRelationObjectValueModule
|
||||
import com.anytypeio.anytype.di.feature.AddDataViewRelationOptionValueModule
|
||||
import com.anytypeio.anytype.di.feature.AddFileRelationModule
|
||||
|
@ -87,6 +88,7 @@ import com.anytypeio.anytype.di.feature.settings.DaggerSpacesStorageComponent
|
|||
import com.anytypeio.anytype.di.feature.settings.LogoutWarningModule
|
||||
import com.anytypeio.anytype.di.feature.settings.MainSettingsModule
|
||||
import com.anytypeio.anytype.di.feature.settings.ProfileModule
|
||||
import com.anytypeio.anytype.di.feature.sharing.DaggerAddToAnytypeComponent
|
||||
import com.anytypeio.anytype.di.feature.spaces.DaggerCreateSpaceComponent
|
||||
import com.anytypeio.anytype.di.feature.spaces.DaggerSelectSpaceComponent
|
||||
import com.anytypeio.anytype.di.feature.spaces.DaggerSpaceSettingsComponent
|
||||
|
@ -100,6 +102,7 @@ import com.anytypeio.anytype.di.feature.wallpaper.WallpaperSelectModule
|
|||
import com.anytypeio.anytype.di.feature.widgets.SelectWidgetSourceModule
|
||||
import com.anytypeio.anytype.di.feature.widgets.SelectWidgetTypeModule
|
||||
import com.anytypeio.anytype.di.main.MainComponent
|
||||
import com.anytypeio.anytype.presentation.objects.CreateObjectOfTypeViewModel
|
||||
import com.anytypeio.anytype.ui.relations.RelationEditParameters
|
||||
import com.anytypeio.anytype.ui.types.edit.TypeEditParameters
|
||||
import com.anytypeio.anytype.ui.widgets.collection.DaggerCollectionComponent
|
||||
|
@ -929,10 +932,13 @@ class ComponentManager(
|
|||
.create(findComponentDependencies())
|
||||
}
|
||||
|
||||
val createObjectOfTypeComponent = Component {
|
||||
val createObjectOfTypeComponent = ComponentWithParams { excludedTypeKeys: List<TypeKey> ->
|
||||
DaggerCreateObjectOfTypeComponent
|
||||
.factory()
|
||||
.create(findComponentDependencies())
|
||||
.create(
|
||||
params = CreateObjectOfTypeViewModel.Params(excludedTypeKeys),
|
||||
dependencies = findComponentDependencies()
|
||||
)
|
||||
}
|
||||
|
||||
val appPreferencesComponent = Component {
|
||||
|
@ -941,6 +947,11 @@ class ComponentManager(
|
|||
.create(findComponentDependencies())
|
||||
}
|
||||
|
||||
val addToAnytypeComponent = Component {
|
||||
DaggerAddToAnytypeComponent
|
||||
.factory()
|
||||
.create(findComponentDependencies())
|
||||
}
|
||||
|
||||
class Component<T>(private val builder: () -> T) {
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.anytypeio.anytype.di.feature
|
|||
import com.anytypeio.anytype.core_utils.di.scope.PerDialog
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.domain.search.SearchObjects
|
||||
import com.anytypeio.anytype.domain.workspace.SpaceManager
|
||||
import com.anytypeio.anytype.presentation.relations.add.AddFileRelationViewModel
|
||||
import com.anytypeio.anytype.presentation.relations.providers.ObjectRelationProvider
|
||||
import com.anytypeio.anytype.presentation.relations.providers.ObjectRelationProvider.Companion.INTRINSIC_PROVIDER_TYPE
|
||||
|
@ -36,8 +37,9 @@ object AddFileRelationModule {
|
|||
@Named(INTRINSIC_PROVIDER_TYPE) relations: ObjectRelationProvider,
|
||||
@Named(INTRINSIC_PROVIDER_TYPE) values: ObjectValueProvider,
|
||||
searchObjects: SearchObjects,
|
||||
urlBuilder: UrlBuilder
|
||||
urlBuilder: UrlBuilder,
|
||||
spaceManager: SpaceManager
|
||||
): AddFileRelationViewModel.Factory = AddFileRelationViewModel.Factory(
|
||||
relations, values, searchObjects, urlBuilder
|
||||
relations, values, searchObjects, urlBuilder, spaceManager
|
||||
)
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.anytypeio.anytype.di.feature
|
||||
|
||||
import android.content.Context
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
|
||||
import com.anytypeio.anytype.di.common.ComponentDependencies
|
||||
import com.anytypeio.anytype.domain.auth.repo.AuthRepository
|
||||
|
@ -46,11 +47,13 @@ object AppPreferencesModule {
|
|||
fun provideViewModelFactory(
|
||||
copyFileToCacheDirectory: CopyFileToCacheDirectory,
|
||||
getNetworkMode: GetNetworkMode,
|
||||
setNetworkMode: SetNetworkMode
|
||||
setNetworkMode: SetNetworkMode,
|
||||
analytics: Analytics
|
||||
): PreferencesViewModel.Factory = PreferencesViewModel.Factory(
|
||||
copyFileToCacheDirectory = copyFileToCacheDirectory,
|
||||
getNetworkMode = getNetworkMode,
|
||||
setNetworkMode = setNetworkMode
|
||||
setNetworkMode = setNetworkMode,
|
||||
analytics = analytics
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -58,4 +61,5 @@ interface AppPreferencesDependencies : ComponentDependencies {
|
|||
fun context(): Context
|
||||
fun dispatchers(): AppCoroutineDispatchers
|
||||
fun authRepository(): AuthRepository
|
||||
fun analytics(): Analytics
|
||||
}
|
|
@ -4,6 +4,7 @@ import com.anytypeio.anytype.analytics.base.Analytics
|
|||
import com.anytypeio.anytype.core_utils.di.scope.PerModal
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
import com.anytypeio.anytype.domain.`object`.ReloadObject
|
||||
import com.anytypeio.anytype.domain.objects.StoreOfObjectTypes
|
||||
import com.anytypeio.anytype.presentation.relations.providers.ObjectRelationProvider
|
||||
import com.anytypeio.anytype.presentation.relations.providers.ObjectRelationProvider.Companion.DATA_VIEW_PROVIDER_TYPE
|
||||
import com.anytypeio.anytype.presentation.relations.providers.ObjectRelationProvider.Companion.INTRINSIC_PROVIDER_TYPE
|
||||
|
@ -39,12 +40,14 @@ object RelationTextValueModule {
|
|||
@Named(INTRINSIC_PROVIDER_TYPE) relations: ObjectRelationProvider,
|
||||
@Named(INTRINSIC_PROVIDER_TYPE) values: ObjectValueProvider,
|
||||
reloadObject: ReloadObject,
|
||||
analytics: Analytics
|
||||
analytics: Analytics,
|
||||
storeOfObjectTypes: StoreOfObjectTypes
|
||||
) = RelationTextValueViewModel.Factory(
|
||||
relations = relations,
|
||||
values = values,
|
||||
reloadObject = reloadObject,
|
||||
analytics = analytics
|
||||
analytics = analytics,
|
||||
storeOfObjectTypes = storeOfObjectTypes
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
@ -77,12 +80,14 @@ object RelationDataViewTextValueModule {
|
|||
@Named(DATA_VIEW_PROVIDER_TYPE) relations: ObjectRelationProvider,
|
||||
@Named(DATA_VIEW_PROVIDER_TYPE) values: ObjectValueProvider,
|
||||
reloadObject: ReloadObject,
|
||||
analytics: Analytics
|
||||
analytics: Analytics,
|
||||
storeOfObjectTypes: StoreOfObjectTypes
|
||||
) = RelationTextValueViewModel.Factory(
|
||||
relations = relations,
|
||||
values = values,
|
||||
reloadObject = reloadObject,
|
||||
analytics = analytics
|
||||
analytics = analytics,
|
||||
storeOfObjectTypes = storeOfObjectTypes
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.anytypeio.anytype.di.feature
|
|||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
|
||||
import com.anytypeio.anytype.domain.account.AccountStatusChannel
|
||||
import com.anytypeio.anytype.domain.account.AwaitAccountStartManager
|
||||
import com.anytypeio.anytype.domain.account.InterceptAccountStatus
|
||||
import com.anytypeio.anytype.domain.auth.interactor.CheckAuthorizationStatus
|
||||
import com.anytypeio.anytype.domain.auth.interactor.Logout
|
||||
|
@ -87,13 +88,15 @@ object MainEntryModule {
|
|||
pathProvider: PathProvider,
|
||||
configStorage: ConfigStorage,
|
||||
featuresConfigProvider: FeaturesConfigProvider,
|
||||
metricsProvider: MetricsProvider
|
||||
metricsProvider: MetricsProvider,
|
||||
awaitAccountStartManager: AwaitAccountStartManager
|
||||
): ResumeAccount = ResumeAccount(
|
||||
repository = authRepository,
|
||||
pathProvider = pathProvider,
|
||||
configStorage = configStorage,
|
||||
featuresConfigProvider = featuresConfigProvider,
|
||||
metricsProvider = metricsProvider
|
||||
metricsProvider = metricsProvider,
|
||||
awaitAccountStartManager = awaitAccountStartManager
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
@ -146,13 +149,15 @@ object MainEntryModule {
|
|||
provider: ConfigStorage,
|
||||
user: UserSettingsRepository,
|
||||
dispatchers: AppCoroutineDispatchers,
|
||||
spaceManager: SpaceManager
|
||||
spaceManager: SpaceManager,
|
||||
awaitAccountStartManager: AwaitAccountStartManager
|
||||
): Logout = Logout(
|
||||
repo = repo,
|
||||
user = user,
|
||||
config = provider,
|
||||
dispatchers = dispatchers,
|
||||
spaceManager = spaceManager
|
||||
spaceManager = spaceManager,
|
||||
awaitAccountStartManager = awaitAccountStartManager
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
|
|
@ -6,6 +6,7 @@ import com.anytypeio.anytype.analytics.base.Analytics
|
|||
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
|
||||
import com.anytypeio.anytype.core_utils.tools.FeatureToggles
|
||||
import com.anytypeio.anytype.di.common.ComponentDependencies
|
||||
import com.anytypeio.anytype.domain.account.AwaitAccountStartManager
|
||||
import com.anytypeio.anytype.domain.auth.interactor.CheckAuthorizationStatus
|
||||
import com.anytypeio.anytype.domain.auth.interactor.GetLastOpenedObject
|
||||
import com.anytypeio.anytype.domain.auth.interactor.LaunchAccount
|
||||
|
@ -75,7 +76,8 @@ object SplashModule {
|
|||
configStorage: ConfigStorage,
|
||||
spaceManager: SpaceManager,
|
||||
metricsProvider: MetricsProvider,
|
||||
userSettings: UserSettingsRepository
|
||||
userSettings: UserSettingsRepository,
|
||||
awaitAccountStartManager: AwaitAccountStartManager
|
||||
): LaunchAccount = LaunchAccount(
|
||||
repository = authRepository,
|
||||
pathProvider = pathProvider,
|
||||
|
@ -83,7 +85,8 @@ object SplashModule {
|
|||
configStorage = configStorage,
|
||||
spaceManager = spaceManager,
|
||||
metricsProvider = metricsProvider,
|
||||
settings = userSettings
|
||||
settings = userSettings,
|
||||
awaitAccountStartManager = awaitAccountStartManager
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
@ -192,4 +195,5 @@ interface SplashDependencies : ComponentDependencies {
|
|||
fun spaceManager(): SpaceManager
|
||||
fun spaceStatusWatcher(): SpaceDeletedStatusWatcher
|
||||
fun localeProvider(): LocaleProvider
|
||||
fun awaitAccountStartManager(): AwaitAccountStartManager
|
||||
}
|
|
@ -4,6 +4,7 @@ import androidx.lifecycle.ViewModelProvider
|
|||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
|
||||
import com.anytypeio.anytype.di.common.ComponentDependencies
|
||||
import com.anytypeio.anytype.domain.account.AwaitAccountStartManager
|
||||
import com.anytypeio.anytype.domain.account.DateHelper
|
||||
import com.anytypeio.anytype.domain.account.RestoreAccount
|
||||
import com.anytypeio.anytype.domain.auth.interactor.Logout
|
||||
|
@ -64,13 +65,15 @@ object DeletedAccountModule {
|
|||
provider: ConfigStorage,
|
||||
dispatchers: AppCoroutineDispatchers,
|
||||
user: UserSettingsRepository,
|
||||
spaceManager: SpaceManager
|
||||
spaceManager: SpaceManager,
|
||||
awaitAccountStartManager: AwaitAccountStartManager
|
||||
): Logout = Logout(
|
||||
repo = repo,
|
||||
config = provider,
|
||||
user = user,
|
||||
dispatchers = dispatchers,
|
||||
spaceManager = spaceManager
|
||||
spaceManager = spaceManager,
|
||||
awaitAccountStartManager = awaitAccountStartManager
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
@ -102,4 +105,5 @@ interface DeletedAccountDependencies : ComponentDependencies {
|
|||
fun relationsSubscriptionManager(): RelationsSubscriptionManager
|
||||
fun objectTypesSubscriptionManager(): ObjectTypesSubscriptionManager
|
||||
fun spaceDeletedStatusWatcher(): SpaceDeletedStatusWatcher
|
||||
fun awaitAccountStartManager(): AwaitAccountStartManager
|
||||
}
|
|
@ -10,6 +10,7 @@ import com.anytypeio.anytype.domain.workspace.SpaceManager
|
|||
import com.anytypeio.anytype.presentation.objects.CreateObjectOfTypeViewModel
|
||||
import com.anytypeio.anytype.ui.objects.creation.CreateObjectOfTypeFragment
|
||||
import dagger.Binds
|
||||
import dagger.BindsInstance
|
||||
import dagger.Component
|
||||
import dagger.Module
|
||||
|
||||
|
@ -22,12 +23,14 @@ import dagger.Module
|
|||
)
|
||||
@PerScreen
|
||||
interface CreateObjectOfTypeComponent {
|
||||
fun inject(fragment: CreateObjectOfTypeFragment)
|
||||
@Component.Factory
|
||||
interface Builder {
|
||||
fun create(dependencies: CreateObjectOfTypeDependencies): CreateObjectOfTypeComponent
|
||||
interface Factory {
|
||||
fun create(
|
||||
@BindsInstance params: CreateObjectOfTypeViewModel.Params,
|
||||
dependencies: CreateObjectOfTypeDependencies
|
||||
): CreateObjectOfTypeComponent
|
||||
}
|
||||
|
||||
fun inject(fragment: CreateObjectOfTypeFragment)
|
||||
}
|
||||
|
||||
@Module
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.anytypeio.anytype.CrashReporter
|
|||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
|
||||
import com.anytypeio.anytype.di.common.ComponentDependencies
|
||||
import com.anytypeio.anytype.domain.account.AwaitAccountStartManager
|
||||
import com.anytypeio.anytype.domain.auth.repo.AuthRepository
|
||||
import com.anytypeio.anytype.domain.config.ConfigStorage
|
||||
import com.anytypeio.anytype.domain.config.FeaturesConfigProvider
|
||||
|
@ -62,4 +63,5 @@ interface OnboardingMnemonicLoginDependencies : ComponentDependencies {
|
|||
fun relationsSubscriptionManager(): RelationsSubscriptionManager
|
||||
fun spaceStatusWatcher(): SpaceDeletedStatusWatcher
|
||||
fun localeProvider(): LocaleProvider
|
||||
fun awaitAccountStartManager(): AwaitAccountStartManager
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.anytypeio.anytype.di.feature.settings
|
|||
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
|
||||
import com.anytypeio.anytype.domain.account.AwaitAccountStartManager
|
||||
import com.anytypeio.anytype.domain.auth.interactor.Logout
|
||||
import com.anytypeio.anytype.domain.auth.repo.AuthRepository
|
||||
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
||||
|
@ -61,12 +62,14 @@ object LogoutWarningModule {
|
|||
provider: ConfigStorage,
|
||||
user: UserSettingsRepository,
|
||||
dispatchers: AppCoroutineDispatchers,
|
||||
spaceManager: SpaceManager
|
||||
spaceManager: SpaceManager,
|
||||
awaitAccountStartManager: AwaitAccountStartManager
|
||||
): Logout = Logout(
|
||||
repo = repo,
|
||||
config = provider,
|
||||
user = user,
|
||||
dispatchers = dispatchers,
|
||||
spaceManager = spaceManager
|
||||
spaceManager = spaceManager,
|
||||
awaitAccountStartManager = awaitAccountStartManager
|
||||
)
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.anytypeio.anytype.di.feature.settings
|
|||
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_utils.di.scope.PerScreen
|
||||
import com.anytypeio.anytype.domain.account.AwaitAccountStartManager
|
||||
import com.anytypeio.anytype.domain.account.DeleteAccount
|
||||
import com.anytypeio.anytype.domain.auth.interactor.Logout
|
||||
import com.anytypeio.anytype.domain.auth.repo.AuthRepository
|
||||
|
@ -83,13 +84,15 @@ object ProfileModule {
|
|||
provider: ConfigStorage,
|
||||
user: UserSettingsRepository,
|
||||
dispatchers: AppCoroutineDispatchers,
|
||||
spaceManager: SpaceManager
|
||||
spaceManager: SpaceManager,
|
||||
awaitAccountStartManager: AwaitAccountStartManager
|
||||
): Logout = Logout(
|
||||
repo = repo,
|
||||
config = provider,
|
||||
user = user,
|
||||
dispatchers = dispatchers,
|
||||
spaceManager = spaceManager
|
||||
spaceManager = spaceManager,
|
||||
awaitAccountStartManager = awaitAccountStartManager
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
package com.anytypeio.anytype.di.feature.sharing
|
||||
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.anytypeio.anytype.analytics.base.Analytics
|
||||
import com.anytypeio.anytype.core_utils.di.scope.PerDialog
|
||||
import com.anytypeio.anytype.di.common.ComponentDependencies
|
||||
import com.anytypeio.anytype.domain.account.AwaitAccountStartManager
|
||||
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
import com.anytypeio.anytype.domain.config.ConfigStorage
|
||||
import com.anytypeio.anytype.domain.config.UserSettingsRepository
|
||||
import com.anytypeio.anytype.domain.library.StorelessSubscriptionContainer
|
||||
import com.anytypeio.anytype.domain.misc.UrlBuilder
|
||||
import com.anytypeio.anytype.domain.workspace.SpaceManager
|
||||
import com.anytypeio.anytype.presentation.sharing.AddToAnytypeViewModel
|
||||
import com.anytypeio.anytype.ui.sharing.SharingFragment
|
||||
import dagger.Binds
|
||||
import dagger.Component
|
||||
import dagger.Module
|
||||
|
||||
@Component(
|
||||
dependencies = [AddToAnytypeDependencies::class],
|
||||
modules = [
|
||||
AddToAnytypeModule::class,
|
||||
AddToAnytypeModule.Declarations::class
|
||||
]
|
||||
)
|
||||
@PerDialog
|
||||
interface AddToAnytypeComponent {
|
||||
@Component.Factory
|
||||
interface Factory {
|
||||
fun create(dependency: AddToAnytypeDependencies): AddToAnytypeComponent
|
||||
}
|
||||
|
||||
fun inject(fragment: SharingFragment)
|
||||
}
|
||||
|
||||
@Module
|
||||
object AddToAnytypeModule {
|
||||
@Module
|
||||
interface Declarations {
|
||||
@PerDialog
|
||||
@Binds
|
||||
fun factory(factory: AddToAnytypeViewModel.Factory): ViewModelProvider.Factory
|
||||
}
|
||||
}
|
||||
|
||||
interface AddToAnytypeDependencies : ComponentDependencies {
|
||||
fun blockRepo(): BlockRepository
|
||||
fun spaceManager(): SpaceManager
|
||||
fun dispatchers(): AppCoroutineDispatchers
|
||||
fun userSettings(): UserSettingsRepository
|
||||
fun configStorage(): ConfigStorage
|
||||
fun container(): StorelessSubscriptionContainer
|
||||
fun urlBuilder(): UrlBuilder
|
||||
fun awaitAccountStartedManager(): AwaitAccountStartManager
|
||||
fun analytics(): Analytics
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.anytypeio.anytype.di.main
|
||||
|
||||
import com.anytypeio.anytype.data.auth.repo.config.GatewayProvider
|
||||
import com.anytypeio.anytype.domain.account.AwaitAccountStartManager
|
||||
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
||||
import com.anytypeio.anytype.domain.config.ConfigStorage
|
||||
import com.anytypeio.anytype.domain.config.Gateway
|
||||
|
@ -50,5 +51,10 @@ object ConfigModule {
|
|||
SupervisorJob() + Dispatchers.Default
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@Singleton
|
||||
fun awaitAccountStartedManager(): AwaitAccountStartManager = AwaitAccountStartManager.Default
|
||||
|
||||
const val DEFAULT_APP_COROUTINE_SCOPE = "Default application coroutine scope"
|
||||
}
|
|
@ -36,6 +36,7 @@ import com.anytypeio.anytype.di.feature.settings.LogoutWarningSubComponent
|
|||
import com.anytypeio.anytype.di.feature.settings.MainSettingsSubComponent
|
||||
import com.anytypeio.anytype.di.feature.settings.ProfileSubComponent
|
||||
import com.anytypeio.anytype.di.feature.settings.SpacesStorageDependencies
|
||||
import com.anytypeio.anytype.di.feature.sharing.AddToAnytypeDependencies
|
||||
import com.anytypeio.anytype.di.feature.spaces.CreateSpaceDependencies
|
||||
import com.anytypeio.anytype.di.feature.spaces.SelectSpaceDependencies
|
||||
import com.anytypeio.anytype.di.feature.spaces.SpaceSettingsDependencies
|
||||
|
@ -103,8 +104,8 @@ interface MainComponent :
|
|||
SpaceSettingsDependencies,
|
||||
CreateObjectOfTypeDependencies,
|
||||
SpacesStorageDependencies,
|
||||
AppPreferencesDependencies
|
||||
{
|
||||
AppPreferencesDependencies,
|
||||
AddToAnytypeDependencies {
|
||||
|
||||
fun inject(app: AndroidApplication)
|
||||
|
||||
|
@ -275,4 +276,9 @@ private abstract class ComponentDependenciesModule private constructor() {
|
|||
@IntoMap
|
||||
@ComponentDependenciesKey(AppPreferencesDependencies::class)
|
||||
abstract fun providePreferencesDependencies(component: MainComponent): ComponentDependencies
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ComponentDependenciesKey(AddToAnytypeDependencies::class)
|
||||
abstract fun provideAddToAnytypeDependencies(component: MainComponent): ComponentDependencies
|
||||
}
|
|
@ -614,7 +614,7 @@ open class EditorFragment : NavigationFragment<FragmentEditorBinding>(R.layout.f
|
|||
.onEach {
|
||||
val dialog = CreateObjectOfTypeFragment().apply {
|
||||
onTypeSelected = {
|
||||
vm.onAddNewDocumentClicked(it.uniqueKey)
|
||||
vm.onAddNewDocumentClicked(it)
|
||||
}
|
||||
}
|
||||
dialog.show(childFragmentManager, "editor-create-object-of-type-dialog")
|
||||
|
@ -842,7 +842,7 @@ open class EditorFragment : NavigationFragment<FragmentEditorBinding>(R.layout.f
|
|||
}
|
||||
}
|
||||
subscribe(vm.icon) { icon ->
|
||||
binding.bottomToolbar.bind(icon)
|
||||
if (hasBinding) binding.bottomToolbar.bind(icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1036,12 +1036,10 @@ open class EditorFragment : NavigationFragment<FragmentEditorBinding>(R.layout.f
|
|||
}
|
||||
is Command.OpenObjectSelectTypeScreen -> {
|
||||
hideKeyboard()
|
||||
val dialog = CreateObjectOfTypeFragment().apply {
|
||||
onTypeSelected = {
|
||||
vm.onObjectTypeChanged(it)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
val dialog = CreateObjectOfTypeFragment.newInstance(
|
||||
excludedTypeKeys = command.excludedTypes,
|
||||
onTypeSelected = vm::onObjectTypeChanged
|
||||
)
|
||||
dialog.show(childFragmentManager, null)
|
||||
}
|
||||
is Command.OpenMoveToScreen -> {
|
||||
|
|
|
@ -5,7 +5,7 @@ import android.content.Intent
|
|||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.Button
|
||||
import android.view.View
|
||||
import android.widget.ProgressBar
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.Fragment
|
||||
|
@ -100,7 +100,12 @@ interface PickerDelegate : PickiTCallbacks {
|
|||
}
|
||||
|
||||
override fun openFilePicker(mimeType: Mimetype, requestCode: Int?) {
|
||||
permissionHelper.openFilePicker(mimeType, requestCode)
|
||||
try {
|
||||
permissionHelper.openFilePicker(mimeType, requestCode)
|
||||
} catch (e: Throwable) {
|
||||
Timber.e(e, "Error while opening file picker")
|
||||
fragment.toast("Error while opening file picker")
|
||||
}
|
||||
}
|
||||
|
||||
override fun initPicker(ctx: Id) {
|
||||
|
@ -188,7 +193,7 @@ interface PickerDelegate : PickiTCallbacks {
|
|||
LayoutInflater.from(fragment.requireContext())
|
||||
.inflate(R.layout.dialog_layout, null)
|
||||
setView(view)
|
||||
view.findViewById<Button>(R.id.btnCancel).setOnClickListener {
|
||||
view.findViewById<View>(R.id.btnCancel).setOnClickListener {
|
||||
pickiT.cancelTask()
|
||||
if (pickitAlertDialog?.isShowing == true) {
|
||||
pickitAlertDialog?.cancel()
|
||||
|
|
|
@ -94,7 +94,7 @@ class HomeScreenFragment : BaseComposeFragment() {
|
|||
onClick = {
|
||||
val dialog = CreateObjectOfTypeFragment().apply {
|
||||
onTypeSelected = {
|
||||
vm.onCreateNewObjectClicked(it.uniqueKey)
|
||||
vm.onCreateNewObjectClicked(it)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import com.anytypeio.anytype.ui.relations.REQUEST_UNINSTALL_RELATION_ARG_ID
|
|||
import com.anytypeio.anytype.ui.relations.REQUEST_UNINSTALL_RELATION_ARG_NAME
|
||||
import com.anytypeio.anytype.ui.relations.RelationCreateFromScratchForObjectFragment
|
||||
import com.anytypeio.anytype.ui.relations.RelationEditFragment
|
||||
import com.anytypeio.anytype.ui.sets.ObjectSetFragment
|
||||
import com.anytypeio.anytype.ui.settings.typography
|
||||
import com.anytypeio.anytype.ui.spaces.SelectSpaceFragment
|
||||
import com.anytypeio.anytype.ui.types.create.CreateObjectTypeFragment
|
||||
|
@ -73,7 +74,7 @@ class LibraryFragment : BaseComposeFragment() {
|
|||
onCreateObjectLongClicked = {
|
||||
val dialog = CreateObjectOfTypeFragment().apply {
|
||||
onTypeSelected = {
|
||||
vm.onCreateObjectOfTypeClicked(it.uniqueKey)
|
||||
vm.onCreateObjectOfTypeClicked(it)
|
||||
}
|
||||
}
|
||||
dialog.show(childFragmentManager, "library-create-object-of-type-dialog")
|
||||
|
@ -139,7 +140,7 @@ class LibraryFragment : BaseComposeFragment() {
|
|||
R.id.pageSearchFragment
|
||||
)
|
||||
}
|
||||
is LibraryViewModel.Navigation.CreateDoc -> {
|
||||
is LibraryViewModel.Navigation.OpenEditor -> {
|
||||
findNavController().safeNavigate(
|
||||
R.id.libraryFragment,
|
||||
R.id.objectNavigation,
|
||||
|
@ -154,6 +155,16 @@ class LibraryFragment : BaseComposeFragment() {
|
|||
args = SelectSpaceFragment.args(exitHomeWhenSpaceIsSelected = true)
|
||||
)
|
||||
}
|
||||
|
||||
is LibraryViewModel.Navigation.OpenSetOrCollection -> {
|
||||
findNavController().safeNavigate(
|
||||
R.id.libraryFragment,
|
||||
R.id.dataViewNavigation,
|
||||
bundleOf(
|
||||
ObjectSetFragment.CONTEXT_ID_KEY to it.id
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import com.anytypeio.anytype.presentation.main.MainViewModelFactory
|
|||
import com.anytypeio.anytype.presentation.navigation.AppNavigation
|
||||
import com.anytypeio.anytype.presentation.wallpaper.WallpaperColor
|
||||
import com.anytypeio.anytype.ui.editor.CreateObjectFragment
|
||||
import com.anytypeio.anytype.ui.sharing.SharingFragment
|
||||
import com.anytypeio.anytype.ui_settings.appearance.ThemeApplicator
|
||||
import com.github.javiersantos.appupdater.AppUpdater
|
||||
import com.github.javiersantos.appupdater.enums.UpdateFrom
|
||||
|
@ -106,6 +107,12 @@ class MainActivity : AppCompatActivity(R.layout.activity_main), AppNavigation.Pr
|
|||
)
|
||||
)
|
||||
}
|
||||
is Command.AddToAnytype -> {
|
||||
SharingFragment.new(command.data).show(
|
||||
supportFragmentManager,
|
||||
SHARE_DIALOG_LABEL
|
||||
)
|
||||
}
|
||||
is Command.Error -> {
|
||||
toast(command.msg)
|
||||
}
|
||||
|
@ -114,6 +121,9 @@ class MainActivity : AppCompatActivity(R.layout.activity_main), AppNavigation.Pr
|
|||
}
|
||||
}
|
||||
}
|
||||
if (savedInstanceState == null && intent.action == Intent.ACTION_SEND) {
|
||||
proceedWithShareIntent(intent)
|
||||
}
|
||||
}
|
||||
|
||||
private fun startAppUpdater() {
|
||||
|
@ -147,20 +157,32 @@ class MainActivity : AppCompatActivity(R.layout.activity_main), AppNavigation.Pr
|
|||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
if (intent != null && intent.action == Intent.ACTION_VIEW) {
|
||||
val data = intent.dataString
|
||||
if (data != null && data.contains(DEEP_LINK_PATTERN)) {
|
||||
deepLink = data
|
||||
} else {
|
||||
intent.extras?.getString(DefaultAppActionManager.ACTION_CREATE_NEW_TYPE_KEY)?.let {
|
||||
vm.onIntentCreateObject(it)
|
||||
if (intent != null) {
|
||||
when(intent.action) {
|
||||
Intent.ACTION_VIEW -> {
|
||||
val data = intent.dataString
|
||||
if (data != null && data.contains(DEEP_LINK_PATTERN)) {
|
||||
deepLink = data
|
||||
} else {
|
||||
intent.extras?.getString(DefaultAppActionManager.ACTION_CREATE_NEW_TYPE_KEY)?.let {
|
||||
vm.onIntentCreateObject(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
Intent.ACTION_SEND -> {
|
||||
proceedWithShareIntent(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (BuildConfig.DEBUG) {
|
||||
Timber.d("on NewIntent: $intent")
|
||||
}
|
||||
}
|
||||
|
||||
private fun proceedWithShareIntent(intent: Intent) {
|
||||
intent.getStringExtra(Intent.EXTRA_TEXT)?.let {
|
||||
vm.onIntentShare(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setTheme(themeMode: ThemeMode) {
|
||||
|
@ -226,5 +248,6 @@ class MainActivity : AppCompatActivity(R.layout.activity_main), AppNavigation.Pr
|
|||
|
||||
companion object {
|
||||
const val AUTO_UPDATE_URL = "https://fra1.digitaloceanspaces.com/anytype-release/latest-android.json"
|
||||
const val SHARE_DIALOG_LABEL = "anytype.dialog.share.label"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,10 +8,14 @@ import androidx.compose.material.MaterialTheme
|
|||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.core_models.Key
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.primitives.TypeKey
|
||||
import com.anytypeio.anytype.core_utils.ext.argOrNull
|
||||
import com.anytypeio.anytype.core_utils.ext.toast
|
||||
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetComposeFragment
|
||||
import com.anytypeio.anytype.di.common.componentManager
|
||||
|
@ -25,6 +29,8 @@ class CreateObjectOfTypeFragment : BaseBottomSheetComposeFragment() {
|
|||
@Inject
|
||||
lateinit var factory: CreateObjectOfTypeViewModel.Factory
|
||||
|
||||
private val excludedTypeKeys get() = argOrNull<List<Key>>(EXCLUDED_TYPE_KEYS_ARG_KEY)
|
||||
|
||||
private val vm by viewModels<CreateObjectOfTypeViewModel> { factory }
|
||||
|
||||
lateinit var onTypeSelected: (ObjectWrapper.Type) -> Unit
|
||||
|
@ -40,10 +46,13 @@ class CreateObjectOfTypeFragment : BaseBottomSheetComposeFragment() {
|
|||
typography = typography
|
||||
) {
|
||||
CreateObjectOfTypeScreen(
|
||||
views = vm.views.collectAsStateWithLifecycle().value,
|
||||
state = vm.viewState.collectAsStateWithLifecycle().value,
|
||||
onTypeClicked = vm::onTypeClicked,
|
||||
onQueryChanged = vm::onQueryChanged,
|
||||
onFocused = { expand() }
|
||||
onFocused = {
|
||||
skipCollapsed()
|
||||
expand()
|
||||
}
|
||||
)
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
|
@ -58,6 +67,7 @@ class CreateObjectOfTypeFragment : BaseBottomSheetComposeFragment() {
|
|||
when (command) {
|
||||
is Command.DispatchObjectType -> {
|
||||
onTypeSelected(command.type)
|
||||
dismiss()
|
||||
}
|
||||
is Command.ShowTypeInstalledToast -> {
|
||||
toast(resources.getString(R.string.library_type_added, command.typeName))
|
||||
|
@ -66,10 +76,29 @@ class CreateObjectOfTypeFragment : BaseBottomSheetComposeFragment() {
|
|||
}
|
||||
|
||||
override fun injectDependencies() {
|
||||
componentManager().createObjectOfTypeComponent.get().inject(this)
|
||||
componentManager()
|
||||
.createObjectOfTypeComponent.get(
|
||||
params = excludedTypeKeys?.map { TypeKey(it) } ?: emptyList()
|
||||
)
|
||||
.inject(this)
|
||||
}
|
||||
|
||||
override fun releaseDependencies() {
|
||||
componentManager().createObjectOfTypeComponent.release()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val EXCLUDED_TYPE_KEYS_ARG_KEY = "arg.create-object-of-type.excluded-type-keys"
|
||||
|
||||
fun newInstance(
|
||||
excludedTypeKeys: List<Key>,
|
||||
onTypeSelected: (ObjectWrapper.Type) -> Unit
|
||||
): CreateObjectOfTypeFragment = CreateObjectOfTypeFragment().apply {
|
||||
this.onTypeSelected = onTypeSelected
|
||||
arguments =
|
||||
bundleOf(
|
||||
EXCLUDED_TYPE_KEYS_ARG_KEY to excludedTypeKeys
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -69,13 +69,14 @@ import com.anytypeio.anytype.core_ui.views.Caption1Medium
|
|||
import com.anytypeio.anytype.core_ui.views.Title2
|
||||
import com.anytypeio.anytype.emojifier.Emojifier
|
||||
import com.anytypeio.anytype.presentation.objects.SelectTypeView
|
||||
import com.anytypeio.anytype.presentation.objects.SelectTypeViewState
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewScreen() {
|
||||
CreateObjectOfTypeScreen(
|
||||
onTypeClicked = {},
|
||||
views = emptyList(),
|
||||
state = SelectTypeViewState.Loading,
|
||||
onQueryChanged = {},
|
||||
onFocused = {}
|
||||
)
|
||||
|
@ -86,7 +87,7 @@ fun CreateObjectOfTypeScreen(
|
|||
onTypeClicked: (SelectTypeView.Type) -> Unit,
|
||||
onQueryChanged: (String) -> Unit,
|
||||
onFocused: () -> Unit,
|
||||
views: List<SelectTypeView>
|
||||
state: SelectTypeViewState
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.nestedScroll(rememberNestedScrollInteropConnection())
|
||||
|
@ -96,40 +97,51 @@ fun CreateObjectOfTypeScreen(
|
|||
Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.padding(vertical = 6.dp)
|
||||
.verticalScroll(rememberScrollState())
|
||||
)
|
||||
SearchField(
|
||||
onQueryChanged = onQueryChanged,
|
||||
onFocused = onFocused
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
ScreenContent(views, onTypeClicked)
|
||||
ScreenContent(state, onTypeClicked)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ScreenContent(
|
||||
views: List<SelectTypeView>,
|
||||
state: SelectTypeViewState,
|
||||
onTypeClicked: (SelectTypeView.Type) -> Unit
|
||||
) {
|
||||
if (views.isNotEmpty()) {
|
||||
FlowRowContent(views, onTypeClicked)
|
||||
}
|
||||
AnimatedVisibility(
|
||||
visible = views.isEmpty(),
|
||||
enter = fadeIn(animationSpec = tween(500)),
|
||||
exit = fadeOut(animationSpec = tween(500))
|
||||
) {
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
EmptyState(
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
title = stringResource(id = R.string.nothing_found),
|
||||
description = stringResource(id = R.string.nothing_found_object_types),
|
||||
icon = AlertConfig.Icon(
|
||||
gradient = GRADIENT_TYPE_RED,
|
||||
icon = R.drawable.ic_alert_error
|
||||
)
|
||||
)
|
||||
when (state) {
|
||||
is SelectTypeViewState.Content -> {
|
||||
FlowRowContent(state.views, onTypeClicked)
|
||||
}
|
||||
SelectTypeViewState.Empty -> {
|
||||
AnimatedVisibility(
|
||||
visible = true,
|
||||
enter = fadeIn(animationSpec = tween(500)),
|
||||
exit = fadeOut(animationSpec = tween(500))
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
EmptyState(
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
title = stringResource(id = R.string.nothing_found),
|
||||
description = stringResource(id = R.string.nothing_found_object_types),
|
||||
icon = AlertConfig.Icon(
|
||||
gradient = GRADIENT_TYPE_RED,
|
||||
icon = R.drawable.ic_alert_error
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SelectTypeViewState.Loading -> {}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,8 +155,7 @@ private fun FlowRowContent(
|
|||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(horizontal = 20.dp)
|
||||
.verticalScroll(rememberScrollState())
|
||||
,
|
||||
.verticalScroll(rememberScrollState()),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
|
@ -267,8 +278,7 @@ fun ObjectTypeItem(
|
|||
shape = RoundedCornerShape(12.dp)
|
||||
)
|
||||
.clip(RoundedCornerShape(12.dp))
|
||||
.clickable { onItemClicked() }
|
||||
,
|
||||
.clickable { onItemClicked() },
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Spacer(
|
||||
|
@ -306,6 +316,7 @@ private fun SearchField(
|
|||
modifier = Modifier
|
||||
.height(48.dp)
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
val focusManager = LocalFocusManager.current
|
||||
val focusRequester = FocusRequester()
|
||||
|
@ -356,8 +367,7 @@ private fun SearchField(
|
|||
.onFocusChanged { state ->
|
||||
if (state.isFocused)
|
||||
onFocused()
|
||||
}
|
||||
,
|
||||
},
|
||||
maxLines = 1,
|
||||
singleLine = true,
|
||||
textStyle = BodyRegular.copy(
|
||||
|
@ -374,7 +384,7 @@ private fun SearchField(
|
|||
enabled = true,
|
||||
placeholder = {
|
||||
Text(
|
||||
text = stringResource(R.string.search),
|
||||
text = stringResource(R.string.search_hint),
|
||||
style = BodyRegular
|
||||
)
|
||||
},
|
||||
|
@ -405,9 +415,11 @@ private fun SearchField(
|
|||
|
||||
@Composable
|
||||
private fun Section(title: String) {
|
||||
Box(modifier = Modifier
|
||||
.height(44.dp)
|
||||
.fillMaxWidth()) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.height(44.dp)
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomStart),
|
||||
|
|
|
@ -37,6 +37,7 @@ import androidx.compose.ui.text.input.VisualTransformation
|
|||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.core_ui.ColorMnemonicStub
|
||||
import com.anytypeio.anytype.core_ui.ColorPagerIndicator
|
||||
|
@ -50,6 +51,7 @@ import com.anytypeio.anytype.core_ui.foundation.noRippleClickable
|
|||
import com.anytypeio.anytype.core_ui.views.HeadlineOnBoardingDescription
|
||||
import com.anytypeio.anytype.core_ui.views.PreviewTitle1Regular
|
||||
import com.anytypeio.anytype.core_ui.views.UXBody
|
||||
import com.anytypeio.anytype.ui.onboarding.screens.signin.MnemonicPhraseFormatter
|
||||
|
||||
@Composable
|
||||
fun PagerIndicator(
|
||||
|
@ -201,6 +203,45 @@ fun MnemonicPhraseWidgetPreview() {
|
|||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OnboardingMnemonicInput(
|
||||
modifier: Modifier = Modifier,
|
||||
text: MutableState<String>,
|
||||
placeholder: String? = null,
|
||||
singleLine: Boolean = true,
|
||||
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
|
||||
keyboardActions: KeyboardActions = KeyboardActions()
|
||||
) {
|
||||
TextField(
|
||||
modifier = modifier,
|
||||
textStyle = UXBody
|
||||
.copy(
|
||||
lineHeight = 34.sp
|
||||
)
|
||||
,
|
||||
value = text.value,
|
||||
onValueChange = {
|
||||
text.value = it
|
||||
},
|
||||
colors = TextFieldDefaults.outlinedTextFieldColors(
|
||||
disabledBorderColor = Color.Transparent,
|
||||
errorBorderColor = Color.Transparent,
|
||||
focusedBorderColor = Color.Transparent,
|
||||
unfocusedBorderColor = Color.Transparent,
|
||||
cursorColor = ColorTextInputCursor
|
||||
),
|
||||
placeholder = {
|
||||
placeholder?.let {
|
||||
Text(text = it, style = UXBody.copy(color = ColorPlaceholderText))
|
||||
}
|
||||
},
|
||||
singleLine = singleLine,
|
||||
keyboardActions = keyboardActions,
|
||||
keyboardOptions = keyboardOptions,
|
||||
visualTransformation = MnemonicPhraseFormatter
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OnboardingInput(
|
||||
modifier: Modifier = Modifier,
|
||||
|
@ -215,9 +256,11 @@ fun OnboardingInput(
|
|||
modifier = modifier.then(
|
||||
Modifier
|
||||
.background(
|
||||
Color(0x26DAD7CA), RoundedCornerShape(24.dp)
|
||||
color = Color(0x26DAD7CA),
|
||||
shape = RoundedCornerShape(24.dp)
|
||||
)
|
||||
.height(68.dp)
|
||||
.padding(horizontal = 8.dp)
|
||||
),
|
||||
textStyle = UXBody.copy(color = ColorTextInput),
|
||||
value = text.value,
|
||||
|
|
|
@ -280,16 +280,22 @@ class OnboardingFragment : Fragment() {
|
|||
}
|
||||
) {
|
||||
val focus = LocalFocusManager.current
|
||||
val onBackClicked : () -> Unit = {
|
||||
val lastDestination = navController.currentBackStackEntry
|
||||
if (lastDestination?.destination?.route == OnboardingNavigation.setProfileName) {
|
||||
focus.clearFocus(true)
|
||||
navController.popBackStack()
|
||||
} else {
|
||||
Timber.d("Skipping exit click...")
|
||||
}
|
||||
}
|
||||
currentPage.value = OnboardingPage.SET_PROFILE_NAME
|
||||
backButtonCallback.value = {
|
||||
focus.clearFocus(true)
|
||||
navController.popBackStack()
|
||||
}
|
||||
SetProfileName(navController = navController)
|
||||
BackHandler {
|
||||
focus.clearFocus(true)
|
||||
navController.popBackStack()
|
||||
}
|
||||
backButtonCallback.value = onBackClicked
|
||||
SetProfileName(
|
||||
navController = navController,
|
||||
onBackClicked = onBackClicked
|
||||
)
|
||||
BackHandler { onBackClicked() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -403,7 +409,8 @@ class OnboardingFragment : Fragment() {
|
|||
|
||||
@Composable
|
||||
private fun SetProfileName(
|
||||
navController: NavHostController
|
||||
navController: NavHostController,
|
||||
onBackClicked: () -> Unit
|
||||
) {
|
||||
val component = componentManager().onboardingSoulCreationComponent
|
||||
val vm = daggerViewModel { component.get().getViewModel() }
|
||||
|
@ -414,7 +421,7 @@ class OnboardingFragment : Fragment() {
|
|||
|
||||
SetProfileNameWrapper(
|
||||
viewModel = vm,
|
||||
onBackClicked = { navController.popBackStack() }
|
||||
onBackClicked = onBackClicked
|
||||
)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
package com.anytypeio.anytype.ui.onboarding.screens.signin
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.Text
|
||||
|
@ -16,6 +18,7 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.res.painterResource
|
||||
|
@ -43,7 +46,7 @@ import com.anytypeio.anytype.core_ui.views.TitleLogin
|
|||
import com.anytypeio.anytype.core_utils.ext.toast
|
||||
import com.anytypeio.anytype.presentation.onboarding.login.OnboardingMnemonicLoginViewModel
|
||||
import com.anytypeio.anytype.presentation.onboarding.login.OnboardingMnemonicLoginViewModel.SetupState
|
||||
import com.anytypeio.anytype.ui.onboarding.OnboardingInput
|
||||
import com.anytypeio.anytype.ui.onboarding.OnboardingMnemonicInput
|
||||
|
||||
@Composable
|
||||
fun RecoveryScreenWrapper(
|
||||
|
@ -94,7 +97,7 @@ fun RecoveryScreen(
|
|||
LazyColumn(
|
||||
content = {
|
||||
item {
|
||||
OnboardingInput(
|
||||
OnboardingMnemonicInput(
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
start = 18.dp,
|
||||
|
@ -104,6 +107,14 @@ fun RecoveryScreen(
|
|||
)
|
||||
.height(165.dp)
|
||||
.fillMaxWidth()
|
||||
.background(
|
||||
color = Color(0x26DAD7CA),
|
||||
shape = RoundedCornerShape(24.dp)
|
||||
)
|
||||
.padding(
|
||||
horizontal = 8.dp,
|
||||
vertical = 4.dp
|
||||
)
|
||||
,
|
||||
text = text,
|
||||
singleLine = false,
|
||||
|
@ -122,8 +133,7 @@ fun RecoveryScreen(
|
|||
context.toast(emptyRecoveryPhraseError)
|
||||
}
|
||||
}
|
||||
),
|
||||
visualTransformation = MnemonicPhraseFormatter
|
||||
)
|
||||
)
|
||||
}
|
||||
item {
|
||||
|
|
|
@ -3,7 +3,6 @@ package com.anytypeio.anytype.ui.onboarding.screens.signup
|
|||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
|
@ -122,7 +121,6 @@ fun SetProfileNameTitle(modifier: Modifier) {
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
fun SetProfileNameInput(
|
||||
text: MutableState<String>,
|
||||
|
|
|
@ -1,22 +1,34 @@
|
|||
package com.anytypeio.anytype.ui.relations
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.core_utils.ext.withParent
|
||||
import com.anytypeio.anytype.core_utils.ui.BaseDialogFragment
|
||||
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetFragment
|
||||
import com.anytypeio.anytype.databinding.FragmentRelationFileValueActionBinding
|
||||
|
||||
class FileActionsFragment : BaseDialogFragment<FragmentRelationFileValueActionBinding>() {
|
||||
class FileActionsFragment : BaseBottomSheetFragment<FragmentRelationFileValueActionBinding>() {
|
||||
|
||||
override fun injectDependencies() {}
|
||||
override fun releaseDependencies() {}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
sheet?.apply {
|
||||
setBackgroundResource(android.R.color.transparent)
|
||||
updateLayoutParams<CoordinatorLayout.LayoutParams> {
|
||||
setMargins(
|
||||
resources.getDimensionPixelSize(R.dimen.dp_8),
|
||||
0,
|
||||
resources.getDimensionPixelSize(R.dimen.dp_8),
|
||||
resources.getDimensionPixelSize(R.dimen.dp_102)
|
||||
)
|
||||
}
|
||||
}
|
||||
binding.btnAdd.setOnClickListener {
|
||||
withParent<FileActionReceiver> { onAddAction() }
|
||||
dismiss()
|
||||
|
@ -31,20 +43,6 @@ class FileActionsFragment : BaseDialogFragment<FragmentRelationFileValueActionBi
|
|||
}
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
setupAppearance()
|
||||
}
|
||||
|
||||
private fun setupAppearance() {
|
||||
dialog?.window?.apply {
|
||||
setGravity(Gravity.BOTTOM)
|
||||
setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
setBackgroundDrawableResource(android.R.color.transparent)
|
||||
setWindowAnimations(R.style.DefaultBottomDialogAnimation)
|
||||
}
|
||||
}
|
||||
|
||||
override fun inflateBinding(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?
|
||||
|
|
|
@ -114,7 +114,8 @@ abstract class RelationValueBaseFragment<T: ViewBinding> : BaseBottomSheetFragm
|
|||
vm.onObjectClicked(
|
||||
ctx = ctx,
|
||||
id = o.id,
|
||||
layout = o.layout
|
||||
layout = o.layout,
|
||||
profileLinkIdentity = o.profileLinkIdentity
|
||||
)
|
||||
} else {
|
||||
vm.onNonExistentObjectClicked(
|
||||
|
@ -160,6 +161,15 @@ abstract class RelationValueBaseFragment<T: ViewBinding> : BaseBottomSheetFragm
|
|||
jobs += lifecycleScope.subscribe(vm.copyFileStatus) { command ->
|
||||
pickerDelegate.onCopyFileCommand(command)
|
||||
}
|
||||
jobs += lifecycleScope.subscribe(vm.isReadOnlyValue) { isReadOnly ->
|
||||
if (isReadOnly) {
|
||||
btnAddValue.gone()
|
||||
btnEditOrDone.gone()
|
||||
} else {
|
||||
btnAddValue.visible()
|
||||
btnEditOrDone.visible()
|
||||
}
|
||||
}
|
||||
super.onStart()
|
||||
vm.onStart(
|
||||
ctx = ctx,
|
||||
|
|
|
@ -56,12 +56,14 @@ class AddFileRelationFragment :
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
skipCollapsed()
|
||||
setFullHeightSheet()
|
||||
binding.rvFiles.layoutManager = LinearLayoutManager(requireContext())
|
||||
binding.rvFiles.adapter = adapter
|
||||
binding.btnAdd.setOnClickListener { vm.onActionButtonClicked() }
|
||||
searchRelationInput = binding.searchBar.root.findViewById(R.id.filterInputField)
|
||||
searchRelationInput.apply {
|
||||
hint = getString(R.string.choose_options)
|
||||
hint = getString(R.string.search_hint)
|
||||
}
|
||||
clearSearchText = binding.searchBar.root.findViewById(R.id.clearSearchText)
|
||||
clearSearchText.setOnClickListener {
|
||||
|
@ -71,6 +73,7 @@ class AddFileRelationFragment :
|
|||
}
|
||||
|
||||
override fun onStart() {
|
||||
expand()
|
||||
jobs += lifecycleScope.subscribe(vm.viewsFiltered) { observeState(it) }
|
||||
jobs += lifecycleScope.subscribe(vm.commands) { observeCommands(it) }
|
||||
jobs += lifecycleScope.subscribe(searchRelationInput.textChanges())
|
||||
|
|
|
@ -315,7 +315,7 @@ open class ObjectSetFragment :
|
|||
.onEach {
|
||||
val dialog = CreateObjectOfTypeFragment().apply {
|
||||
onTypeSelected = {
|
||||
vm.onAddNewDocumentClicked(it.uniqueKey)
|
||||
vm.onAddNewDocumentClicked(it)
|
||||
}
|
||||
}
|
||||
dialog.show(childFragmentManager, "set-create-object-of-type-dialog")
|
||||
|
|
|
@ -164,6 +164,6 @@ class ProfileSettingsFragment : BaseBottomSheetComposeFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
private const val PADDING_TOP = 54
|
||||
private const val PADDING_TOP = 28
|
||||
|
||||
private const val SELECT_IMAGE_CODE = 1
|
||||
|
|
405
app/src/main/java/com/anytypeio/anytype/ui/sharing/Sharing.kt
Normal file
405
app/src/main/java/com/anytypeio/anytype/ui/sharing/Sharing.kt
Normal file
|
@ -0,0 +1,405 @@
|
|||
package com.anytypeio.anytype.ui.sharing
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Divider
|
||||
import androidx.compose.material.DropdownMenuItem
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
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.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.graphics.toColorInt
|
||||
import coil.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.core_ui.foundation.noRippleClickable
|
||||
import com.anytypeio.anytype.core_ui.views.BodyRegular
|
||||
import com.anytypeio.anytype.core_ui.views.ButtonPrimary
|
||||
import com.anytypeio.anytype.core_ui.views.ButtonSecondary
|
||||
import com.anytypeio.anytype.core_ui.views.ButtonSize
|
||||
import com.anytypeio.anytype.core_ui.views.Caption1Medium
|
||||
import com.anytypeio.anytype.core_ui.views.TitleInter15
|
||||
import com.anytypeio.anytype.presentation.sharing.AddToAnytypeViewModel.SpaceView
|
||||
import com.anytypeio.anytype.presentation.spaces.SpaceIconView
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun AddToAnytypeScreenUrlPreview() {
|
||||
AddToAnytypeScreen(
|
||||
data = SharingData.Url("https://en.wikipedia.org/wiki/Walter_Benjamin"),
|
||||
onCancelClicked = {},
|
||||
onDoneClicked = {},
|
||||
spaces = emptyList(),
|
||||
onSelectSpaceClicked = {}
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun AddToAnytypeScreenNotePreview() {
|
||||
AddToAnytypeScreen(
|
||||
data = SharingData.Raw("The Work of Art in the Age of its Technological Reproducibility"),
|
||||
onCancelClicked = {},
|
||||
onDoneClicked = {},
|
||||
spaces = emptyList(),
|
||||
onSelectSpaceClicked = {}
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AddToAnytypeScreen(
|
||||
spaces: List<SpaceView>,
|
||||
data: SharingData,
|
||||
onCancelClicked: () -> Unit,
|
||||
onDoneClicked: (SaveAsOption) -> Unit,
|
||||
onSelectSpaceClicked: (SpaceView) -> Unit
|
||||
) {
|
||||
var isSaveAsMenuExpanded by remember { mutableStateOf(false) }
|
||||
val items = if (data is SharingData.Url)
|
||||
listOf(SAVE_AS_NOTE, SAVE_AS_BOOKMARK)
|
||||
else
|
||||
listOf(SAVE_AS_NOTE)
|
||||
var selectedIndex by remember {
|
||||
mutableStateOf(
|
||||
when(data) {
|
||||
is SharingData.Url -> SAVE_AS_BOOKMARK
|
||||
else -> SAVE_AS_NOTE
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Column(modifier = Modifier.fillMaxWidth()) {
|
||||
Header()
|
||||
DataSection(data)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(76.dp)
|
||||
.noRippleClickable { isSaveAsMenuExpanded = !isSaveAsMenuExpanded }
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.sharing_menu_save_as_section_name),
|
||||
modifier = Modifier
|
||||
.padding(top = 14.dp, start = 20.dp),
|
||||
style = Caption1Medium,
|
||||
color = colorResource(id = R.color.text_secondary)
|
||||
)
|
||||
|
||||
Text(
|
||||
text = if (selectedIndex == SAVE_AS_BOOKMARK)
|
||||
stringResource(id = R.string.sharing_menu_save_as_bookmark_option)
|
||||
else
|
||||
stringResource(id = R.string.sharing_menu_save_as_note_option),
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomStart)
|
||||
.padding(bottom = 14.dp, start = 20.dp),
|
||||
style = BodyRegular,
|
||||
color = colorResource(id = R.color.text_primary)
|
||||
)
|
||||
if (items.size > 1) {
|
||||
DropdownMenu(
|
||||
expanded = isSaveAsMenuExpanded,
|
||||
onDismissRequest = { isSaveAsMenuExpanded = false },
|
||||
modifier = Modifier.background(
|
||||
color = colorResource(id = R.color.background_secondary)
|
||||
)
|
||||
) {
|
||||
items.forEachIndexed { index, s ->
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
selectedIndex = index
|
||||
isSaveAsMenuExpanded = false
|
||||
}
|
||||
) {
|
||||
when(s) {
|
||||
SAVE_AS_BOOKMARK -> {
|
||||
Text(
|
||||
text = stringResource(id = R.string.sharing_menu_save_as_bookmark_option),
|
||||
style = BodyRegular,
|
||||
color = colorResource(id = R.color.text_primary)
|
||||
)
|
||||
}
|
||||
SAVE_AS_NOTE -> {
|
||||
Text(
|
||||
text = stringResource(id = R.string.sharing_menu_save_as_note_option),
|
||||
style = BodyRegular,
|
||||
color = colorResource(id = R.color.text_primary)
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
// Draw nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
if (index != items.lastIndex) {
|
||||
Divider(
|
||||
thickness = 0.5.dp,
|
||||
color = colorResource(id = R.color.shape_primary)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val selected = spaces.firstOrNull { it.isSelected }
|
||||
if (selected != null) {
|
||||
CurrentSpaceSection(
|
||||
name = selected.obj.name.orEmpty(),
|
||||
spaces = spaces,
|
||||
onSelectSpaceClicked = onSelectSpaceClicked,
|
||||
icon = selected.icon
|
||||
)
|
||||
} else {
|
||||
CurrentSpaceSection(
|
||||
name = stringResource(id = R.string.unknown),
|
||||
spaces = spaces,
|
||||
onSelectSpaceClicked = onSelectSpaceClicked
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
Buttons(onCancelClicked, onDoneClicked, selectedIndex)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DataSection(data: SharingData) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 20.dp)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = colorResource(id = R.color.shape_primary),
|
||||
shape = RoundedCornerShape(10.dp)
|
||||
)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.sharing_menu_data),
|
||||
style = Caption1Medium,
|
||||
color = colorResource(id = R.color.text_secondary),
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
top = 10.dp,
|
||||
start = 16.dp,
|
||||
end = 16.dp
|
||||
)
|
||||
)
|
||||
Text(
|
||||
text = data.data,
|
||||
style = BodyRegular,
|
||||
color = colorResource(id = R.color.text_primary),
|
||||
modifier = Modifier.padding(
|
||||
top = 30.dp,
|
||||
start = 16.dp,
|
||||
end = 16.dp,
|
||||
bottom = 10.dp
|
||||
),
|
||||
maxLines = 5
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Buttons(
|
||||
onCancelClicked: () -> Unit,
|
||||
onDoneClicked: (SaveAsOption) -> Unit,
|
||||
selectedIndex: Int
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(68.dp)
|
||||
.padding(horizontal = 20.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
ButtonSecondary(
|
||||
onClick = onCancelClicked,
|
||||
size = ButtonSize.Large,
|
||||
text = stringResource(id = R.string.cancel),
|
||||
modifier = Modifier.weight(1.0f)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
ButtonPrimary(
|
||||
onClick = { onDoneClicked(selectedIndex) },
|
||||
size = ButtonSize.Large,
|
||||
text = stringResource(id = R.string.done),
|
||||
modifier = Modifier.weight(1.0f)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun CurrentSpaceSection(
|
||||
icon: SpaceIconView? = null,
|
||||
name: String,
|
||||
spaces: List<SpaceView>,
|
||||
onSelectSpaceClicked: (SpaceView) -> Unit
|
||||
) {
|
||||
var isSpaceSelectMenuExpanded by remember { mutableStateOf(false) }
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(76.dp)
|
||||
.noRippleClickable {
|
||||
isSpaceSelectMenuExpanded = true
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.space),
|
||||
modifier = Modifier
|
||||
.padding(top = 14.dp, start = 20.dp),
|
||||
style = Caption1Medium,
|
||||
color = colorResource(id = R.color.text_secondary)
|
||||
)
|
||||
val hasIcon = icon is SpaceIconView.Gradient || icon is SpaceIconView.Image
|
||||
if (icon != null && hasIcon) {
|
||||
SmallSpaceIcon(
|
||||
icon = icon,
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
start = 20.dp,
|
||||
bottom = 17.dp
|
||||
)
|
||||
.align(Alignment.BottomStart)
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = name,
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomStart)
|
||||
.padding(
|
||||
bottom = 14.dp,
|
||||
start = if (hasIcon) 44.dp else 20.dp
|
||||
),
|
||||
style = BodyRegular,
|
||||
color = colorResource(id = R.color.text_primary)
|
||||
)
|
||||
DropdownMenu(
|
||||
expanded = isSpaceSelectMenuExpanded,
|
||||
onDismissRequest = { isSpaceSelectMenuExpanded = false },
|
||||
modifier = Modifier.background(
|
||||
color = colorResource(id = R.color.background_secondary)
|
||||
)
|
||||
) {
|
||||
spaces.forEachIndexed { index, view ->
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
onSelectSpaceClicked(view)
|
||||
isSpaceSelectMenuExpanded = false
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
text = view.obj.name.orEmpty(),
|
||||
style = BodyRegular,
|
||||
color = colorResource(id = R.color.text_primary)
|
||||
)
|
||||
}
|
||||
if (index != spaces.lastIndex) {
|
||||
Divider(
|
||||
thickness = 0.5.dp,
|
||||
color = colorResource(id = R.color.shape_primary)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Header() {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(48.dp)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.sharing_menu_add_to_anytype_header_title),
|
||||
color = colorResource(id = R.color.text_primary),
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
style = TitleInter15
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
private fun SmallSpaceIcon(
|
||||
icon: SpaceIconView,
|
||||
modifier: Modifier
|
||||
) {
|
||||
val size = 18.dp
|
||||
when (icon) {
|
||||
is SpaceIconView.Image -> {
|
||||
Image(
|
||||
painter = rememberAsyncImagePainter(
|
||||
model = icon.url,
|
||||
error = painterResource(id = com.anytypeio.anytype.ui_settings.R.drawable.ic_home_widget_space)
|
||||
),
|
||||
contentDescription = "Custom image space icon",
|
||||
contentScale = ContentScale.Crop,
|
||||
modifier = modifier
|
||||
.size(size)
|
||||
.clip(RoundedCornerShape(4.dp))
|
||||
)
|
||||
}
|
||||
|
||||
is SpaceIconView.Gradient -> {
|
||||
val gradient = Brush.radialGradient(
|
||||
colors = listOf(
|
||||
Color(icon.from.toColorInt()),
|
||||
Color(icon.to.toColorInt())
|
||||
)
|
||||
)
|
||||
Box(
|
||||
modifier = modifier
|
||||
.size(size)
|
||||
.clip(CircleShape)
|
||||
.background(gradient)
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
// Draw nothing.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const val SAVE_AS_NOTE = 0
|
||||
const val SAVE_AS_BOOKMARK = 1
|
||||
typealias SaveAsOption = Int
|
||||
|
||||
sealed class SharingData {
|
||||
abstract val data: String
|
||||
data class Url(val url: String) : SharingData() {
|
||||
override val data: String
|
||||
get() = url
|
||||
}
|
||||
data class Raw(val raw: String) : SharingData() {
|
||||
override val data: String
|
||||
get() = raw
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
package com.anytypeio.anytype.ui.sharing
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.webkit.URLUtil
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.core_utils.ext.arg
|
||||
import com.anytypeio.anytype.core_utils.ext.toast
|
||||
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetComposeFragment
|
||||
import com.anytypeio.anytype.di.common.componentManager
|
||||
import com.anytypeio.anytype.presentation.home.OpenObjectNavigation
|
||||
import com.anytypeio.anytype.presentation.sharing.AddToAnytypeViewModel
|
||||
import com.anytypeio.anytype.ui.editor.EditorFragment
|
||||
import com.anytypeio.anytype.ui.settings.typography
|
||||
import javax.inject.Inject
|
||||
|
||||
class SharingFragment : BaseBottomSheetComposeFragment() {
|
||||
|
||||
private val sharedData : SharingData get() {
|
||||
val result = arg<String>(SHARING_DATE_KEY)
|
||||
return if (URLUtil.isValidUrl(result)) {
|
||||
SharingData.Url(result)
|
||||
} else {
|
||||
SharingData.Raw(result)
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
lateinit var factory: AddToAnytypeViewModel.Factory
|
||||
|
||||
private val vm by viewModels<AddToAnytypeViewModel> { factory }
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View = ComposeView(requireContext()).apply {
|
||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
||||
setContent {
|
||||
MaterialTheme(
|
||||
typography = typography
|
||||
) {
|
||||
AddToAnytypeScreen(
|
||||
data = sharedData,
|
||||
onDoneClicked = { option ->
|
||||
when(option) {
|
||||
SAVE_AS_BOOKMARK -> vm.onCreateBookmark(url = sharedData.data)
|
||||
SAVE_AS_NOTE -> vm.onCreateNote(sharedData.data)
|
||||
}
|
||||
},
|
||||
onCancelClicked = {
|
||||
vm.onCancelClicked().also {
|
||||
dismiss()
|
||||
}
|
||||
},
|
||||
spaces = vm.spaceViews.collectAsStateWithLifecycle().value,
|
||||
onSelectSpaceClicked = { vm.onSelectSpaceClicked(it) }
|
||||
)
|
||||
LaunchedEffect(Unit) {
|
||||
vm.navigation.collect { nav ->
|
||||
when(nav) {
|
||||
is OpenObjectNavigation.OpenEditor -> {
|
||||
dismiss()
|
||||
findNavController().navigate(
|
||||
R.id.objectNavigation,
|
||||
bundleOf(
|
||||
EditorFragment.ID_KEY to nav.target
|
||||
)
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
vm.toasts.collect { toast ->
|
||||
toast(toast)
|
||||
}
|
||||
}
|
||||
LaunchedEffect(Unit) {
|
||||
vm.commands.collect { command ->
|
||||
proceedWithCommand(command)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun proceedWithCommand(command: AddToAnytypeViewModel.Command) {
|
||||
when (command) {
|
||||
AddToAnytypeViewModel.Command.Dismiss -> {
|
||||
dismiss()
|
||||
}
|
||||
is AddToAnytypeViewModel.Command.ObjectAddToSpaceToast -> {
|
||||
val name = command.spaceName ?: resources.getString(R.string.untitled)
|
||||
val msg = resources.getString(R.string.sharing_menu_toast_object_added, name)
|
||||
toast(msg = msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun injectDependencies() {
|
||||
componentManager().addToAnytypeComponent.get().inject(this)
|
||||
}
|
||||
|
||||
override fun releaseDependencies() {
|
||||
componentManager().addToAnytypeComponent.release()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val SHARING_DATE_KEY = "arg.sharing.data-key"
|
||||
fun new(data: String) : SharingFragment = SharingFragment().apply {
|
||||
arguments = bundleOf(SHARING_DATE_KEY to data)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -62,6 +62,7 @@ fun CreateSpaceScreen(
|
|||
val input = remember {
|
||||
mutableStateOf("")
|
||||
}
|
||||
val focusManager = LocalFocusManager.current
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
|
@ -84,7 +85,13 @@ fun CreateSpaceScreen(
|
|||
onSpaceIconClicked = onSpaceIconClicked
|
||||
)
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
SpaceNameInput(input = input)
|
||||
SpaceNameInput(
|
||||
input = input,
|
||||
onActionDone = {
|
||||
focusManager.clearFocus()
|
||||
onCreate(input.value)
|
||||
}
|
||||
)
|
||||
Divider()
|
||||
Section(title = stringResource(id = R.string.type))
|
||||
TypeOfSpace(spaceType = PRIVATE_SPACE_TYPE)
|
||||
|
@ -95,7 +102,10 @@ fun CreateSpaceScreen(
|
|||
Spacer(modifier = Modifier.height(78.dp))
|
||||
}
|
||||
CreateSpaceButton(
|
||||
onCreate = onCreate,
|
||||
onCreate = { name ->
|
||||
focusManager.clearFocus()
|
||||
onCreate(name)
|
||||
},
|
||||
input = input,
|
||||
modifier = Modifier.align(Alignment.BottomCenter),
|
||||
isLoading = isLoading
|
||||
|
@ -165,9 +175,9 @@ fun SpaceIcon(
|
|||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun SpaceNameInput(
|
||||
input: MutableState<String>
|
||||
input: MutableState<String>,
|
||||
onActionDone: () -> Unit
|
||||
) {
|
||||
val focusManager = LocalFocusManager.current
|
||||
val focusRequester = FocusRequester()
|
||||
Box(
|
||||
modifier = Modifier
|
||||
|
@ -178,9 +188,7 @@ fun SpaceNameInput(
|
|||
value = input.value,
|
||||
onValueChange = { input.value = it },
|
||||
keyboardActions = KeyboardActions(
|
||||
onDone = {
|
||||
focusManager.clearFocus()
|
||||
}
|
||||
onDone = { onActionDone() }
|
||||
),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.anytypeio.anytype.presentation.spaces.Command
|
|||
import com.anytypeio.anytype.presentation.spaces.SelectSpaceViewModel
|
||||
import com.anytypeio.anytype.ui.settings.typography
|
||||
import javax.inject.Inject
|
||||
import timber.log.Timber
|
||||
|
||||
class SelectSpaceFragment : BaseBottomSheetComposeFragment() {
|
||||
|
||||
|
@ -84,10 +85,14 @@ class SelectSpaceFragment : BaseBottomSheetComposeFragment() {
|
|||
findNavController().popBackStack()
|
||||
}
|
||||
is Command.SwitchToNewSpace -> {
|
||||
if (exitHomeWhenSpaceIsSelected == true) {
|
||||
findNavController().navigate(R.id.switchSpaceAction)
|
||||
} else {
|
||||
findNavController().popBackStack()
|
||||
try {
|
||||
if (exitHomeWhenSpaceIsSelected == true) {
|
||||
findNavController().navigate(R.id.switchSpaceAction)
|
||||
} else {
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Navigation error")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.compose.ui.unit.sp
|
||||
import coil.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.R
|
||||
import com.anytypeio.anytype.core_ui.extensions.throttledClick
|
||||
import com.anytypeio.anytype.core_ui.foundation.Dragger
|
||||
import com.anytypeio.anytype.core_ui.foundation.noRippleClickable
|
||||
import com.anytypeio.anytype.core_ui.views.Caption1Medium
|
||||
|
@ -154,7 +155,9 @@ private fun SelectSpaceSpaceItem(
|
|||
) {
|
||||
SpaceImageBlock(
|
||||
icon = item.view.icon,
|
||||
onSpaceIconClick = { onSpaceClicked(item.view) },
|
||||
onSpaceIconClick = throttledClick(
|
||||
onClick = { onSpaceClicked(item.view) }
|
||||
),
|
||||
gradientBackground = colorResource(id = R.color.default_gradient_background),
|
||||
gradientCornerRadius = 4.dp
|
||||
)
|
||||
|
|
|
@ -71,7 +71,6 @@ class EditorTemplateFragment : EditorFragment() {
|
|||
|
||||
private fun initializeBinding() {
|
||||
with(binding) {
|
||||
root.background = null
|
||||
if (fragmentType == TYPE_TEMPLATE_SELECT || fragmentType == TYPE_TEMPLATE_EDIT) {
|
||||
recycler.updateLayoutParams<ConstraintLayout.LayoutParams> {
|
||||
topMargin = dimen(R.dimen.default_toolbar_height)
|
||||
|
|
|
@ -57,7 +57,7 @@ class CollectionFragment : BaseComposeFragment() {
|
|||
onCreateObjectLongClicked = {
|
||||
val dialog = CreateObjectOfTypeFragment().apply {
|
||||
onTypeSelected = {
|
||||
vm.onAddClicked(it.uniqueKey)
|
||||
vm.onAddClicked(it)
|
||||
}
|
||||
}
|
||||
dialog.show(childFragmentManager, "fullscreen-widget-create-object-of-type-dialog")
|
||||
|
|
|
@ -134,7 +134,7 @@ fun ScreenContent(
|
|||
backClick = { vm.onPrevClicked() },
|
||||
homeClick = { vm.onHomeClicked() },
|
||||
searchClick = { vm.onSearchClicked() },
|
||||
addDocClick = { vm.onAddClicked() },
|
||||
addDocClick = { vm.onAddClicked(null) },
|
||||
onCreateObjectLongClicked = onCreateObjectLongClicked,
|
||||
onProfileClicked = vm::onProfileClicked,
|
||||
profileIcon = vm.icon.collectAsState().value
|
||||
|
|
|
@ -68,16 +68,6 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<com.anytypeio.anytype.core_ui.widgets.toolbar.ObjectTypesWidget
|
||||
android:id="@+id/objectTypesToolbar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/background_primary"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<com.anytypeio.anytype.core_ui.widgets.toolbar.MarkupColorToolbarWidget
|
||||
android:id="@+id/markupColorToolbar"
|
||||
android:layout_width="0dp"
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--typography, buttons 05.04-->
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_marginBottom="@dimen/dp_20"
|
||||
android:background="@drawable/rounded_rectangle_data_view_action"
|
||||
android:orientation="vertical">
|
||||
|
@ -18,6 +15,7 @@
|
|||
<TextView
|
||||
android:id="@+id/btnAdd"
|
||||
style="@style/TextView.UXStyle.Body"
|
||||
android:textColor="@color/text_primary"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
|
@ -29,8 +27,6 @@
|
|||
android:id="@+id/divider2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.5dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:background="@color/viewer_divider"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
@ -39,6 +35,7 @@
|
|||
<TextView
|
||||
android:id="@+id/btnUploadFromGallery"
|
||||
style="@style/TextView.UXStyle.Body"
|
||||
android:textColor="@color/text_primary"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
|
@ -50,8 +47,6 @@
|
|||
android:id="@+id/divider3"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.5dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:background="@color/viewer_divider"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
@ -60,6 +55,7 @@
|
|||
<TextView
|
||||
android:id="@+id/btnUploadFromStorage"
|
||||
style="@style/TextView.UXStyle.Body"
|
||||
android:textColor="@color/text_primary"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--typography, buttons 05.04-->
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -1,62 +1,67 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--typography, buttons 05.04-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context="com.anytypeio.anytype.ui.relations.add.AddFileRelationFragment">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="64dp">
|
||||
|
||||
<View
|
||||
android:id="@+id/dragger"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_width="@dimen/default_dragger_width"
|
||||
android:layout_height="@dimen/default_dragger_height"
|
||||
android:layout_marginTop="6dp"
|
||||
android:background="@drawable/dragger" />
|
||||
|
||||
<include
|
||||
android:id="@+id/searchBar"
|
||||
layout="@layout/widget_search_view"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<View
|
||||
android:id="@+id/dragger"
|
||||
android:layout_width="@dimen/default_dragger_width"
|
||||
android:layout_height="@dimen/default_dragger_height"
|
||||
android:layout_marginTop="6dp"
|
||||
android:background="@drawable/dragger"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<include
|
||||
android:id="@+id/searchBar"
|
||||
layout="@layout/widget_search_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/dragger" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvFiles"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_weight="1"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/dragger" />
|
||||
app:layout_constraintTop_toBottomOf="@+id/searchBar" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvFiles"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/searchBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_weight="1" />
|
||||
</LinearLayout>
|
||||
|
||||
<com.anytypeio.anytype.core_ui.widgets.ButtonPrimaryNumber
|
||||
android:id="@+id/btnAdd"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_marginStart="20dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
app:buttonTitle="@string/btn_apply_new_object"
|
||||
android:layout_gravity="bottom">
|
||||
</com.anytypeio.anytype.core_ui.widgets.ButtonPrimaryNumber>
|
||||
</LinearLayout>
|
||||
app:buttonTitle="@string/btn_add" />
|
||||
</FrameLayout>
|
|
@ -15,6 +15,16 @@ android {
|
|||
buildConfigField ANYTYPE_CLIPBOARD_LABEL_TYPE, ANYTYPE_CLIPBOARD_LABEL, ANYTYPE_CLIPBOARD_LABEL_VALUE
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(17)
|
||||
}
|
||||
|
||||
namespace 'com.anytypeio.anytype.clipboard'
|
||||
}
|
||||
|
||||
|
|
|
@ -391,7 +391,8 @@ data class Block(
|
|||
* @param style style for a block to create
|
||||
*/
|
||||
data class Text(
|
||||
val style: Style
|
||||
val style: Style,
|
||||
val text: String? = null
|
||||
) : Prototype()
|
||||
|
||||
data class File(
|
||||
|
|
|
@ -9,3 +9,7 @@ data class NetworkModeConfig(
|
|||
val userFilePath: String? = null,
|
||||
val storedFilePath: String? = null
|
||||
)
|
||||
|
||||
object NetworkModeConst {
|
||||
const val NODE_STAGING_ID = "N9DU6hLkTAbvcpji3TCKPPd3UQWKGyzUxGmgJEyvhByqAjfD"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
package com.anytypeio.anytype.core_models
|
||||
|
||||
enum class ObjectOrigin(val code: Int) {
|
||||
NONE(0),
|
||||
CLIPBOARD(1),
|
||||
DRAG_AND_DROP(2),
|
||||
IMPORT(3),
|
||||
WEB_CLIPPER(4),
|
||||
SHARING_EXTENSION(5),
|
||||
USE_CASE(6),
|
||||
BUILT_IN(7)
|
||||
}
|
|
@ -242,9 +242,13 @@ sealed class ObjectWrapper {
|
|||
|
||||
data class SpaceView(override val map: Struct) : ObjectWrapper() {
|
||||
private val default = map.withDefault { null }
|
||||
|
||||
val id: Id by default
|
||||
val name: String? by default
|
||||
val iconImage: String? get() = getValue(Relations.ICON_IMAGE)
|
||||
val iconOption: Double? by default
|
||||
val targetSpaceId: String? by default
|
||||
|
||||
val spaceAccountStatus: SpaceStatus
|
||||
get() {
|
||||
val code = getValue<Double?>(Relations.SPACE_ACCOUNT_STATUS)
|
||||
|
|
|
@ -24,6 +24,7 @@ object Relations {
|
|||
const val IS_HIDDEN = "isHidden"
|
||||
const val LAST_OPENED_DATE = "lastOpenedDate"
|
||||
const val LAST_MODIFIED_DATE = "lastModifiedDate"
|
||||
const val LAST_USED_DATE = "lastUsedDate"
|
||||
const val TYPE = "type"
|
||||
const val LINKS = "links"
|
||||
const val TARGET_OBJECT_TYPE = "targetObjectType"
|
||||
|
@ -68,6 +69,8 @@ object Relations {
|
|||
|
||||
const val BACKLINKS = "backlinks"
|
||||
|
||||
const val ORIGIN = "origin"
|
||||
|
||||
/**
|
||||
* Transitive relation key.
|
||||
*/
|
||||
|
|
|
@ -43,4 +43,12 @@ fun Map<Id, Struct>.unset(
|
|||
|
||||
fun Struct.mapToObjectWrapperType(): ObjectWrapper.Type? =
|
||||
if (containsKey(Relations.ID) && containsKey(Relations.UNIQUE_KEY)) ObjectWrapper.Type(this)
|
||||
else null
|
||||
else null
|
||||
|
||||
inline fun <reified T> Struct.getValues(key: String): List<T> {
|
||||
return when (val value = getOrDefault(key, emptyList<T>())) {
|
||||
is T -> listOf(value)
|
||||
is List<*> -> value.typeOf()
|
||||
else -> emptyList()
|
||||
}
|
||||
}
|
|
@ -18,6 +18,16 @@ android {
|
|||
viewBinding true
|
||||
compose true
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(17)
|
||||
}
|
||||
|
||||
namespace 'com.anytypeio.anytype.core_ui'
|
||||
}
|
||||
|
||||
|
|
|
@ -298,9 +298,12 @@ fun SyncStatusView?.getLabelText(context: Context): String = when (this) {
|
|||
SyncStatusView.Unknown -> context.getString(R.string.sync_status_unknown)
|
||||
SyncStatusView.Offline -> context.getString(R.string.sync_status_offline)
|
||||
SyncStatusView.Syncing -> context.getString(R.string.sync_status_syncing)
|
||||
is SyncStatusView.Synced -> context.getString(R.string.sync_status_synced)
|
||||
SyncStatusView.Failed -> context.getString(R.string.sync_status_failed)
|
||||
SyncStatusView.IncompatibleVersion -> context.getString(R.string.sync_status_incompatible)
|
||||
SyncStatusView.Synced.LocalOnly -> context.getString(R.string.sync_status_local_only)
|
||||
SyncStatusView.Synced.AnyNetwork -> context.getString(R.string.sync_status_synced)
|
||||
SyncStatusView.Synced.SelfHostedNetwork -> context.getString(R.string.sync_status_synced)
|
||||
SyncStatusView.Synced.StagingNetwork -> context.getString(R.string.sync_status_synced)
|
||||
else -> ""
|
||||
}
|
||||
|
||||
|
|
|
@ -1273,7 +1273,12 @@ class BlockAdapter(
|
|||
item = blocks[position] as BlockView.DataView.Deleted
|
||||
)
|
||||
}
|
||||
else -> throw IllegalStateException("Unexpected view holder: $holder")
|
||||
is Unsupported -> {
|
||||
holder.bind(item = blocks[position] as BlockView.Unsupported)
|
||||
}
|
||||
else -> {
|
||||
Timber.e("Unexpected view holder: $holder")
|
||||
}
|
||||
}
|
||||
checkIfDecorationChanged(holder, payloads.typeOf(), position)
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ import android.view.View
|
|||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.anytypeio.anytype.core_models.Relation
|
||||
import com.anytypeio.anytype.core_models.Relations
|
||||
import com.anytypeio.anytype.core_models.ThemeColor
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
import com.anytypeio.anytype.core_ui.databinding.ItemRelationListRelationCheckboxBinding
|
||||
import com.anytypeio.anytype.core_ui.databinding.ItemRelationListRelationDefaultBinding
|
||||
|
@ -18,7 +20,6 @@ import com.anytypeio.anytype.core_ui.widgets.RelationObjectItem
|
|||
import com.anytypeio.anytype.core_ui.widgets.text.TagWidget
|
||||
import com.anytypeio.anytype.core_utils.ext.gone
|
||||
import com.anytypeio.anytype.core_utils.ext.visible
|
||||
import com.anytypeio.anytype.core_models.ThemeColor
|
||||
import com.anytypeio.anytype.presentation.relations.ObjectRelationView
|
||||
import com.anytypeio.anytype.presentation.sets.model.ObjectView
|
||||
|
||||
|
@ -37,7 +38,12 @@ sealed class ListRelationViewHolder(
|
|||
fun bind(item: ObjectRelationView) {
|
||||
tvTitle.text = item.name
|
||||
tvValue.apply {
|
||||
text = item.value
|
||||
if (item.key == Relations.ORIGIN) {
|
||||
val code = item.value?.toInt() ?: -1
|
||||
setText(code.resRelationOrigin())
|
||||
} else {
|
||||
text = item.value
|
||||
}
|
||||
if (item is ObjectRelationView.Default) {
|
||||
when (item.format) {
|
||||
Relation.Format.SHORT_TEXT -> setHint(R.string.enter_text)
|
||||
|
@ -51,7 +57,7 @@ sealed class ListRelationViewHolder(
|
|||
}
|
||||
}
|
||||
}
|
||||
setLockIcon(tvTitle, item.readOnly)
|
||||
setLockIcon(tvTitle, item)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -64,7 +70,7 @@ sealed class ListRelationViewHolder(
|
|||
fun bind(item: ObjectRelationView.Checkbox) = with(itemView) {
|
||||
tvTitle.text = item.name
|
||||
ivCheckbox.isSelected = item.isChecked
|
||||
setLockIcon(tvTitle, item.system)
|
||||
setLockIcon(tvTitle, item)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,7 +97,7 @@ sealed class ListRelationViewHolder(
|
|||
text = null
|
||||
}
|
||||
}
|
||||
setLockIcon(tvTitle, item.system)
|
||||
setLockIcon(tvTitle, item)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +114,7 @@ sealed class ListRelationViewHolder(
|
|||
} else {
|
||||
placeholder.gone()
|
||||
}
|
||||
setLockIcon(tvTitle, item.system)
|
||||
setLockIcon(tvTitle, item)
|
||||
for (i in 0..MAX_VISIBLE_TAGS_INDEX) getViewByIndex(i)?.gone()
|
||||
item.tags.forEachIndexed { index, tagView ->
|
||||
when (index) {
|
||||
|
@ -150,7 +156,7 @@ sealed class ListRelationViewHolder(
|
|||
} else {
|
||||
placeholder.gone()
|
||||
}
|
||||
setLockIcon(tvTitle, item.system)
|
||||
setLockIcon(tvTitle, item)
|
||||
for (i in 0..MAX_VISIBLE_OBJECTS_INDEX) getViewByIndex(i)?.gone()
|
||||
item.objects.forEachIndexed { index, objectView ->
|
||||
when (index) {
|
||||
|
@ -196,7 +202,7 @@ sealed class ListRelationViewHolder(
|
|||
} else {
|
||||
placeholder.gone()
|
||||
}
|
||||
setLockIcon(tvTitle, item.system)
|
||||
setLockIcon(tvTitle, item)
|
||||
item.files.forEachIndexed { index, fileView ->
|
||||
when (index) {
|
||||
in 0..MAX_VISIBLE_FILES_INDEX -> {
|
||||
|
@ -237,12 +243,26 @@ sealed class ListRelationViewHolder(
|
|||
itemView.setBlockBackgroundColor(color)
|
||||
}
|
||||
|
||||
fun setLockIcon(view: TextView, isReadOnly: Boolean) {
|
||||
if (isReadOnly) {
|
||||
fun setLockIcon(view: TextView, item: ObjectRelationView) {
|
||||
if (item.readOnly) {
|
||||
view.setCompoundDrawablesWithIntrinsicBounds(systemIconDrawable, null, null, null)
|
||||
view.visible()
|
||||
} else {
|
||||
view.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Int.resRelationOrigin() : Int {
|
||||
return when(this) {
|
||||
0 -> R.string.relation_origin_none
|
||||
1 -> R.string.relation_origin_clipboard
|
||||
2 -> R.string.relation_origin_dnd
|
||||
3 -> R.string.relation_origin_imported_object
|
||||
4 -> R.string.relation_origin_web_clipper
|
||||
5 -> R.string.relation_origin_mobile_sharing_extension
|
||||
6 -> R.string.relation_origin_use_case
|
||||
7 -> R.string.relation_origin_library_installed
|
||||
else -> R.string.unknown
|
||||
}
|
||||
}
|
|
@ -320,8 +320,8 @@ class FeaturedRelationGroupWidget : ConstraintLayout {
|
|||
maxLines = 1
|
||||
ellipsize = TextUtils.TruncateAt.END
|
||||
}
|
||||
if (relation.value == null) {
|
||||
view.alpha = 0.5f
|
||||
view.setOnClickListener {
|
||||
click(ListenerType.Relation.Featured(relation))
|
||||
}
|
||||
addView(view)
|
||||
ids.add(view.id)
|
||||
|
@ -339,8 +339,8 @@ class FeaturedRelationGroupWidget : ConstraintLayout {
|
|||
maxLines = 1
|
||||
ellipsize = TextUtils.TruncateAt.END
|
||||
}
|
||||
if (relation.value == null) {
|
||||
view.alpha = 0.5f
|
||||
view.setOnClickListener {
|
||||
click(ListenerType.Relation.Featured(relation))
|
||||
}
|
||||
addView(view)
|
||||
ids.add(view.id)
|
||||
|
|
|
@ -27,10 +27,6 @@ class StatusBadgeWidget @JvmOverloads constructor(
|
|||
visible()
|
||||
tint(color = context.color(R.color.palette_system_red))
|
||||
}
|
||||
is SyncStatusView.Synced -> {
|
||||
visible()
|
||||
tint(color = context.color(R.color.palette_system_green))
|
||||
}
|
||||
SyncStatusView.Syncing -> {
|
||||
visible()
|
||||
tint(color = context.color(R.color.palette_system_amber_100))
|
||||
|
@ -38,6 +34,15 @@ class StatusBadgeWidget @JvmOverloads constructor(
|
|||
SyncStatusView.Unknown, SyncStatusView.Offline, null -> {
|
||||
gone()
|
||||
}
|
||||
SyncStatusView.Synced.LocalOnly -> {
|
||||
gone()
|
||||
}
|
||||
SyncStatusView.Synced.AnyNetwork,
|
||||
SyncStatusView.Synced.SelfHostedNetwork,
|
||||
SyncStatusView.Synced.StagingNetwork -> {
|
||||
visible()
|
||||
tint(color = context.color(R.color.palette_system_green))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,6 +24,7 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil.compose.rememberAsyncImagePainter
|
||||
import com.anytypeio.anytype.core_ui.R
|
||||
|
@ -31,8 +32,30 @@ import com.anytypeio.anytype.core_ui.foundation.noRippleThrottledClickable
|
|||
import com.anytypeio.anytype.core_ui.views.Caption1Medium
|
||||
import com.anytypeio.anytype.emojifier.Emojifier
|
||||
import com.anytypeio.anytype.presentation.editor.EditorViewModel
|
||||
import com.anytypeio.anytype.presentation.objects.ObjectTypeView
|
||||
|
||||
|
||||
@Preview(showBackground = true, apiLevel = 33)
|
||||
@Composable
|
||||
fun MyChooseTypeHorizontalWidget() {
|
||||
val state = EditorViewModel.TypesWidgetState(
|
||||
visible = true,
|
||||
items = listOf(
|
||||
EditorViewModel.TypesWidgetItem.Search,
|
||||
EditorViewModel.TypesWidgetItem.Type(
|
||||
item = ObjectTypeView(
|
||||
emoji = "👍",
|
||||
name = "Like",
|
||||
id = "12312",
|
||||
description = null,
|
||||
key = "dd"
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
ChooseTypeHorizontalWidget(state = state, onTypeClicked = {})
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ChooseTypeHorizontalWidget(
|
||||
state: EditorViewModel.TypesWidgetState,
|
||||
|
@ -43,7 +66,8 @@ fun ChooseTypeHorizontalWidget(
|
|||
modifier = Modifier
|
||||
.height(52.dp)
|
||||
.fillMaxWidth()
|
||||
.background(color = colorResource(id = R.color.background_primary))
|
||||
.background(color = colorResource(id = R.color.background_primary)),
|
||||
contentAlignment = Alignment.CenterStart
|
||||
) {
|
||||
LazyRow(
|
||||
contentPadding = PaddingValues(
|
||||
|
|
11
core-ui/src/main/res/drawable/ic_variant_empty.xml
Normal file
11
core-ui/src/main/res/drawable/ic_variant_empty.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M12,12m-11.25,0a11.25,11.25 0,1 1,22.5 0a11.25,11.25 0,1 1,-22.5 0"
|
||||
android:strokeWidth="1.5"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="@color/glyph_inactive"/>
|
||||
</vector>
|
9
core-ui/src/main/res/drawable/ic_variant_selected.xml
Normal file
9
core-ui/src/main/res/drawable/ic_variant_selected.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M12,12m-12,0a12,12 0,1 1,24 0a12,12 0,1 1,-24 0"
|
||||
android:fillColor="@color/glyph_button"/>
|
||||
</vector>
|
5
core-ui/src/main/res/drawable/ic_variant_selector.xml
Normal file
5
core-ui/src/main/res/drawable/ic_variant_selector.xml
Normal file
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/ic_variant_empty" android:state_selected="false" />
|
||||
<item android:drawable="@drawable/ic_variant_selected" android:state_selected="true" />
|
||||
</selector>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/white" />
|
||||
<solid android:color="@color/background_secondary" />
|
||||
<corners android:radius="10dp" />
|
||||
</shape>
|
|
@ -34,7 +34,7 @@
|
|||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:text="@string/select_objects"
|
||||
android:text="@string/no_value"
|
||||
android:visibility="gone"
|
||||
android:paddingEnd="@dimen/dp_12"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
|
||||
<TextView
|
||||
android:id="@+id/fileSelectionIndex"
|
||||
style="@style/SelectedRelationCircleBadgeStyle"
|
||||
style="@style/RelationCircleBadgeStyle"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:visibility="invisible"
|
||||
|
|
|
@ -27,12 +27,12 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
app:checkboxSize="24dp"
|
||||
app:emojiSize="28dp"
|
||||
app:hasEmojiRounded12Background="true"
|
||||
app:imageCornerRadius="@dimen/list_item_object_image_corner_radius"
|
||||
app:imageSize="@dimen/dp_48"
|
||||
app:initialTextSize="28sp"
|
||||
app:checkboxSize="24dp"
|
||||
app:imageCornerRadius="@dimen/list_item_object_image_corner_radius"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/btnRemoveObject"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
|
@ -40,37 +40,39 @@
|
|||
tools:background="@drawable/circle_solid_default" />
|
||||
|
||||
<TextView
|
||||
android:hint="@string/untitled"
|
||||
android:id="@+id/tvTitle"
|
||||
style="@style/TextView.ContentStyle.PreviewTitles.2.Medium"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginTop="13dp"
|
||||
style="@style/TextView.ContentStyle.PreviewTitles.2.Medium"
|
||||
android:ellipsize="end"
|
||||
android:hint="@string/untitled"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
app:layout_constraintBottom_toTopOf="@+id/tvSubtitle"
|
||||
app:layout_constraintEnd_toStartOf="@+id/btnDragAndDropObject"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconWidget"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.5"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
app:layout_goneMarginEnd="0dp"
|
||||
tools:text="Charlie Chaplin" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvSubtitle"
|
||||
style="@style/TextView.ContentStyle.Relations.2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="12dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:singleLine="true"
|
||||
style="@style/TextView.ContentStyle.Relations.2"
|
||||
android:textColor="@color/text_secondary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/btnDragAndDropObject"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconWidget"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tvTitle"
|
||||
app:layout_constraintVertical_bias="0.5"
|
||||
app:layout_goneMarginEnd="0dp"
|
||||
tools:text="Actor" />
|
||||
|
||||
|
|
|
@ -463,6 +463,14 @@
|
|||
<item name="android:background">@drawable/ic_tag_selected_selector</item>
|
||||
</style>
|
||||
|
||||
<style name="RelationCircleBadgeStyle" parent="TextView.UXStyle.Body">
|
||||
<item name="android:textSize">14sp</item>
|
||||
<item name="android:textColor">@color/button_text</item>
|
||||
<item name="android:layout_gravity">center_vertical|end</item>
|
||||
<item name="android:gravity">center</item>
|
||||
<item name="android:background">@drawable/ic_variant_selector</item>
|
||||
</style>
|
||||
|
||||
<style name="GridCellTagStyle" parent="TextView.ContentStyle.Relations.2">
|
||||
<item name="android:background">@drawable/rect_dv_cell_tag_item</item>
|
||||
<item name="android:singleLine">true</item>
|
||||
|
|
|
@ -12,6 +12,16 @@ android {
|
|||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(17)
|
||||
}
|
||||
|
||||
namespace 'com.anytypeio.anytype.core_utils'
|
||||
}
|
||||
|
||||
|
|
|
@ -116,4 +116,23 @@ object MimeTypes {
|
|||
"application/x-zip",
|
||||
"application/octet-stream"
|
||||
)
|
||||
|
||||
val MIME_EXTRA_IMAGE_VIDEO = arrayOf(
|
||||
"video/mp4",
|
||||
"video/3gpp",
|
||||
"video/3gpp2",
|
||||
"video/H261",
|
||||
"video/H263",
|
||||
"video/mpv",
|
||||
"video/ogg",
|
||||
"video/x-msvideo",
|
||||
"image/jpeg",
|
||||
"image/png",
|
||||
"image/svg+xml",
|
||||
"image/webp",
|
||||
"image/gif",
|
||||
"image/avif",
|
||||
"image/apng",
|
||||
"image/bmp"
|
||||
)
|
||||
}
|
|
@ -41,6 +41,7 @@ import androidx.navigation.NavDirections
|
|||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.anytypeio.anytype.core_utils.const.FileConstants.REQUEST_FILE_SAF_CODE
|
||||
import com.anytypeio.anytype.core_utils.const.FileConstants.REQUEST_MEDIA_CODE
|
||||
import com.anytypeio.anytype.core_utils.const.MimeTypes.MIME_EXTRA_IMAGE_VIDEO
|
||||
import com.anytypeio.anytype.core_utils.const.MimeTypes.MIME_EXTRA_YAML
|
||||
import com.anytypeio.anytype.core_utils.ui.BaseBottomSheetComposeFragment
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
|
@ -279,37 +280,51 @@ fun String.normalizeUrl(): String =
|
|||
* https://app.clickup.com/t/2cbqneb
|
||||
*/
|
||||
fun Fragment.startFilePicker(mime: Mimetype, requestCode: Int? = null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
type = mime.value
|
||||
if (mime == Mimetype.MIME_YAML) {
|
||||
putExtra(Intent.EXTRA_MIME_TYPES, MIME_EXTRA_YAML)
|
||||
}
|
||||
}
|
||||
val code = if (mime == Mimetype.MIME_FILE_ALL) {
|
||||
REQUEST_FILE_SAF_CODE
|
||||
} else {
|
||||
REQUEST_MEDIA_CODE
|
||||
}
|
||||
startActivityForResult(intent, requestCode ?: code)
|
||||
} else {
|
||||
val intent =
|
||||
if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
|
||||
Intent(Intent.ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
|
||||
when (mime) {
|
||||
Mimetype.MIME_IMAGE_AND_VIDEO -> startMediaPicker(mime, requestCode)
|
||||
else -> {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
type = mime.value
|
||||
if (mime == Mimetype.MIME_YAML) {
|
||||
putExtra(Intent.EXTRA_MIME_TYPES, MIME_EXTRA_YAML)
|
||||
}
|
||||
}
|
||||
val code = if (mime == Mimetype.MIME_FILE_ALL) {
|
||||
REQUEST_FILE_SAF_CODE
|
||||
} else {
|
||||
REQUEST_MEDIA_CODE
|
||||
}
|
||||
startActivityForResult(intent, requestCode ?: code)
|
||||
} else {
|
||||
Intent(Intent.ACTION_PICK, MediaStore.Video.Media.INTERNAL_CONTENT_URI)
|
||||
val intent =
|
||||
if (Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED) {
|
||||
Intent(Intent.ACTION_PICK, MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
|
||||
} else {
|
||||
Intent(Intent.ACTION_PICK, MediaStore.Video.Media.INTERNAL_CONTENT_URI)
|
||||
}
|
||||
intent.apply {
|
||||
type = mime.value
|
||||
action = Intent.ACTION_GET_CONTENT
|
||||
putExtra("return-data", true)
|
||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
}
|
||||
startActivityForResult(intent, requestCode ?: REQUEST_MEDIA_CODE)
|
||||
}
|
||||
intent.apply {
|
||||
type = mime.value
|
||||
action = Intent.ACTION_GET_CONTENT
|
||||
putExtra("return-data", true)
|
||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
}
|
||||
startActivityForResult(intent, requestCode ?: REQUEST_MEDIA_CODE)
|
||||
}
|
||||
}
|
||||
|
||||
private fun Fragment.startMediaPicker(mime: Mimetype, requestCode: Int? = null) {
|
||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
|
||||
addCategory(Intent.CATEGORY_OPENABLE)
|
||||
type = mime.value
|
||||
putExtra(Intent.EXTRA_MIME_TYPES, MIME_EXTRA_IMAGE_VIDEO)
|
||||
}
|
||||
startActivityForResult(intent, requestCode ?: REQUEST_MEDIA_CODE)
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this class for picking images from external storage
|
||||
*/
|
||||
|
|
|
@ -17,6 +17,16 @@ android {
|
|||
}
|
||||
includeDependenciesReport = true
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(17)
|
||||
}
|
||||
|
||||
namespace 'com.anytypeio.anytype.crash_reporting'
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import com.anytypeio.anytype.core_models.DVFilter
|
|||
import com.anytypeio.anytype.core_models.DVSort
|
||||
import com.anytypeio.anytype.core_models.DVViewer
|
||||
import com.anytypeio.anytype.core_models.DVViewerType
|
||||
import com.anytypeio.anytype.core_models.FileLimits
|
||||
import com.anytypeio.anytype.core_models.Hash
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.Key
|
||||
|
@ -209,10 +208,12 @@ class BlockDataRepository(
|
|||
|
||||
override suspend fun createBookmarkObject(
|
||||
space: Id,
|
||||
url: Url
|
||||
url: Url,
|
||||
details: Struct
|
||||
): Id = remote.createBookmarkObject(
|
||||
space = space,
|
||||
url = url
|
||||
url = url,
|
||||
details = details
|
||||
)
|
||||
|
||||
override suspend fun fetchBookmarkObject(ctx: Id, url: Url) = remote.fetchBookmarkObject(
|
||||
|
|
|
@ -9,7 +9,6 @@ import com.anytypeio.anytype.core_models.DVFilter
|
|||
import com.anytypeio.anytype.core_models.DVSort
|
||||
import com.anytypeio.anytype.core_models.DVViewer
|
||||
import com.anytypeio.anytype.core_models.DVViewerType
|
||||
import com.anytypeio.anytype.core_models.FileLimits
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.Key
|
||||
import com.anytypeio.anytype.core_models.NodeUsageInfo
|
||||
|
@ -72,7 +71,7 @@ interface BlockRemote {
|
|||
suspend fun uploadBlock(command: Command.UploadBlock): Payload
|
||||
suspend fun setupBookmark(command: Command.SetupBookmark): Payload
|
||||
suspend fun createAndFetchBookmarkBlock(command: Command.CreateBookmark): Payload
|
||||
suspend fun createBookmarkObject(space: Id, url: Url): Id
|
||||
suspend fun createBookmarkObject(space: Id, url: Url, details: Struct): Id
|
||||
suspend fun fetchBookmarkObject(ctx: Id, url: Url)
|
||||
suspend fun undo(command: Command.Undo): Payload
|
||||
suspend fun importUseCaseSkip(space: Id)
|
||||
|
|
|
@ -23,5 +23,14 @@ dependencies {
|
|||
}
|
||||
|
||||
android {
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(17)
|
||||
}
|
||||
|
||||
namespace 'com.anytypeio.anytype.device'
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package com.anytypeio.anytype.domain.account
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
interface AwaitAccountStartManager {
|
||||
fun isStarted(): Flow<Boolean>
|
||||
fun setIsStarted(isStarted: Boolean)
|
||||
object Default: AwaitAccountStartManager {
|
||||
private val isStarted = MutableStateFlow(false)
|
||||
override fun isStarted(): Flow<Boolean> = isStarted
|
||||
override fun setIsStarted(isStarted: Boolean) {
|
||||
this.isStarted.value = isStarted
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package com.anytypeio.anytype.domain.auth.interactor
|
||||
|
||||
import com.anytypeio.anytype.core_models.Command
|
||||
import com.anytypeio.anytype.domain.account.AwaitAccountStartManager
|
||||
import com.anytypeio.anytype.domain.auth.repo.AuthRepository
|
||||
import com.anytypeio.anytype.domain.base.BaseUseCase
|
||||
import com.anytypeio.anytype.domain.base.Either
|
||||
|
@ -25,7 +26,8 @@ class LaunchAccount @Inject constructor(
|
|||
private val featuresConfigProvider: FeaturesConfigProvider,
|
||||
private val spaceManager: SpaceManager,
|
||||
private val metricsProvider: MetricsProvider,
|
||||
private val settings: UserSettingsRepository
|
||||
private val settings: UserSettingsRepository,
|
||||
private val awaitAccountStartManager: AwaitAccountStartManager
|
||||
) : BaseUseCase<String, BaseUseCase.None>(context) {
|
||||
|
||||
override suspend fun run(params: None) = try {
|
||||
|
@ -57,6 +59,7 @@ class LaunchAccount @Inject constructor(
|
|||
} else {
|
||||
spaceManager.set(setup.config.space)
|
||||
}
|
||||
awaitAccountStartManager.setIsStarted(true)
|
||||
Either.Right(setup.config.analytics)
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.anytypeio.anytype.domain.auth.interactor
|
||||
|
||||
import com.anytypeio.anytype.domain.account.AwaitAccountStartManager
|
||||
import com.anytypeio.anytype.domain.auth.repo.AuthRepository
|
||||
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
||||
import com.anytypeio.anytype.domain.base.Interactor
|
||||
|
@ -16,6 +17,7 @@ class Logout @Inject constructor(
|
|||
private val config: ConfigStorage,
|
||||
private val user: UserSettingsRepository,
|
||||
private val spaceManager: SpaceManager,
|
||||
private val awaitAccountStartManager: AwaitAccountStartManager,
|
||||
dispatchers: AppCoroutineDispatchers,
|
||||
) : Interactor<Logout.Params>(context = dispatchers.io) {
|
||||
|
||||
|
@ -24,6 +26,7 @@ class Logout @Inject constructor(
|
|||
user.clear()
|
||||
config.clear()
|
||||
spaceManager.clear()
|
||||
awaitAccountStartManager.setIsStarted(false)
|
||||
}
|
||||
|
||||
class Params(
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.anytypeio.anytype.domain.auth.interactor
|
|||
|
||||
import com.anytypeio.anytype.core_models.Command
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.domain.account.AwaitAccountStartManager
|
||||
import com.anytypeio.anytype.domain.auth.repo.AuthRepository
|
||||
import com.anytypeio.anytype.domain.base.BaseUseCase
|
||||
import com.anytypeio.anytype.domain.config.ConfigStorage
|
||||
|
@ -17,7 +18,8 @@ class ResumeAccount(
|
|||
private val pathProvider: PathProvider,
|
||||
private val configStorage: ConfigStorage,
|
||||
private val featuresConfigProvider: FeaturesConfigProvider,
|
||||
private val metricsProvider: MetricsProvider
|
||||
private val metricsProvider: MetricsProvider,
|
||||
private val awaitAccountStartManager: AwaitAccountStartManager
|
||||
) : BaseUseCase<Id, BaseUseCase.None>() {
|
||||
|
||||
override suspend fun run(params: None) = proceedWithResuming()
|
||||
|
@ -40,7 +42,7 @@ class ResumeAccount(
|
|||
networkMode = networkMode.networkMode,
|
||||
networkConfigFilePath = networkMode.storedFilePath
|
||||
)
|
||||
repository.selectAccount(command).let { setup ->
|
||||
val result = repository.selectAccount(command).let { setup ->
|
||||
featuresConfigProvider.set(
|
||||
enableDataView = setup.features.enableDataView ?: false,
|
||||
enableDebug = setup.features.enableDebug ?: false,
|
||||
|
@ -50,5 +52,7 @@ class ResumeAccount(
|
|||
configStorage.set(config = setup.config)
|
||||
setup.account.id
|
||||
}
|
||||
awaitAccountStartManager.setIsStarted(true)
|
||||
result
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package com.anytypeio.anytype.domain.auth.interactor
|
|||
import com.anytypeio.anytype.core_models.AccountStatus
|
||||
import com.anytypeio.anytype.core_models.Command
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.domain.account.AwaitAccountStartManager
|
||||
import com.anytypeio.anytype.domain.auth.repo.AuthRepository
|
||||
import com.anytypeio.anytype.domain.base.BaseUseCase
|
||||
import com.anytypeio.anytype.domain.config.ConfigStorage
|
||||
|
@ -17,7 +18,8 @@ class SelectAccount @Inject constructor(
|
|||
private val repository: AuthRepository,
|
||||
private val configStorage: ConfigStorage,
|
||||
private val featuresConfigProvider: FeaturesConfigProvider,
|
||||
private val metricsProvider: MetricsProvider
|
||||
private val metricsProvider: MetricsProvider,
|
||||
private val awaitAccountStartManager: AwaitAccountStartManager
|
||||
) : BaseUseCase<StartAccountResult, SelectAccount.Params>() {
|
||||
|
||||
override suspend fun run(params: Params) = safe {
|
||||
|
@ -46,6 +48,7 @@ class SelectAccount @Inject constructor(
|
|||
enableSpaces = setup.features.enableSpaces ?: false
|
||||
)
|
||||
configStorage.set(config = setup.config)
|
||||
awaitAccountStartManager.setIsStarted(true)
|
||||
StartAccountResult(setup.config.analytics, setup.status)
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import com.anytypeio.anytype.core_models.DVFilter
|
|||
import com.anytypeio.anytype.core_models.DVSort
|
||||
import com.anytypeio.anytype.core_models.DVViewer
|
||||
import com.anytypeio.anytype.core_models.DVViewerType
|
||||
import com.anytypeio.anytype.core_models.FileLimits
|
||||
import com.anytypeio.anytype.core_models.Hash
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.Key
|
||||
|
@ -127,7 +126,7 @@ interface BlockRepository {
|
|||
/**
|
||||
* Creates bookmark object from url and returns its id.
|
||||
*/
|
||||
suspend fun createBookmarkObject(space: Id, url: Url): Id
|
||||
suspend fun createBookmarkObject(space: Id, url: Url, details: Struct): Id
|
||||
|
||||
suspend fun fetchBookmarkObject(ctx: Id, url: Url)
|
||||
|
||||
|
|
|
@ -6,8 +6,10 @@ import com.anytypeio.anytype.core_models.DVFilterCondition
|
|||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.InternalFlags
|
||||
import com.anytypeio.anytype.core_models.Key
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.Relation
|
||||
import com.anytypeio.anytype.core_models.RelationFormat
|
||||
import com.anytypeio.anytype.core_models.Relations
|
||||
import com.anytypeio.anytype.core_models.Struct
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.core_models.primitives.TypeKey
|
||||
|
@ -68,10 +70,9 @@ class CreateDataViewObject @Inject constructor(
|
|||
}
|
||||
is Params.Collection -> {
|
||||
val command = Command.CreateObject(
|
||||
template = params.templateId,
|
||||
prefilled = resolveSetByRelationPrefilledObjectData(
|
||||
filters = emptyList(),
|
||||
relations = emptyList()
|
||||
template = params.template,
|
||||
prefilled = resolveCollectionPrefilledObjectData(
|
||||
filters = params.filters
|
||||
),
|
||||
internalFlags = listOf(InternalFlags.ShouldSelectTemplate),
|
||||
space = space,
|
||||
|
@ -91,8 +92,8 @@ class CreateDataViewObject @Inject constructor(
|
|||
filters: List<DVFilter>
|
||||
): Struct = buildMap {
|
||||
filters.forEach { filter ->
|
||||
val relation = storeOfRelations.getByKey(filter.relation)
|
||||
if (relation != null && relation.isReadOnly == false) {
|
||||
val relation = storeOfRelations.getByKey(filter.relation) ?: return@forEach
|
||||
if (relation.isCanBeAddedToObject()) {
|
||||
if (filter.condition == DVFilterCondition.ALL_IN || filter.condition == DVFilterCondition.IN || filter.condition == DVFilterCondition.EQUAL) {
|
||||
filter.value?.let { put(filter.relation, it) }
|
||||
}
|
||||
|
@ -130,6 +131,23 @@ class CreateDataViewObject @Inject constructor(
|
|||
emptyMap()
|
||||
}
|
||||
|
||||
private suspend fun resolveCollectionPrefilledObjectData(
|
||||
filters: List<DVFilter>
|
||||
): Struct = buildMap {
|
||||
filters.forEach { filter ->
|
||||
val relation = storeOfRelations.getByKey(filter.relation) ?: return@forEach
|
||||
if (relation.isCanBeAddedToObject()) {
|
||||
if (
|
||||
filter.condition == DVFilterCondition.ALL_IN
|
||||
|| filter.condition == DVFilterCondition.IN
|
||||
|| filter.condition == DVFilterCondition.EQUAL
|
||||
) {
|
||||
filter.value?.let { put(filter.relation, it) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveDefaultValueByFormat(format: RelationFormat): Any? {
|
||||
when (format) {
|
||||
Relation.Format.LONG_TEXT,
|
||||
|
@ -168,7 +186,8 @@ class CreateDataViewObject @Inject constructor(
|
|||
|
||||
data class Collection(
|
||||
val type: TypeKey,
|
||||
val templateId: Id?
|
||||
val filters: List<DVFilter>,
|
||||
val template: Id?
|
||||
) : Params()
|
||||
}
|
||||
|
||||
|
@ -181,4 +200,8 @@ class CreateDataViewObject @Inject constructor(
|
|||
companion object {
|
||||
const val EMPTY_STRING_VALUE = ""
|
||||
}
|
||||
}
|
||||
|
||||
private fun ObjectWrapper.Relation.isCanBeAddedToObject(): Boolean {
|
||||
return !isReadonlyValue && !Relations.systemRelationKeys.contains(key)
|
||||
}
|
|
@ -1,26 +1,30 @@
|
|||
package com.anytypeio.anytype.domain.objects
|
||||
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.Struct
|
||||
import com.anytypeio.anytype.core_models.Url
|
||||
import com.anytypeio.anytype.domain.base.BaseUseCase
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Use-case for creating bookmark object from url.
|
||||
*/
|
||||
class CreateBookmarkObject(
|
||||
class CreateBookmarkObject @Inject constructor(
|
||||
private val repo: BlockRepository
|
||||
) : BaseUseCase<Id, CreateBookmarkObject.Params>() {
|
||||
|
||||
override suspend fun run(params: Params) = safe {
|
||||
repo.createBookmarkObject(
|
||||
space = params.space,
|
||||
url = params.url
|
||||
url = params.url,
|
||||
details = params.details
|
||||
)
|
||||
}
|
||||
|
||||
data class Params(
|
||||
val space: Id,
|
||||
val url: Url
|
||||
val url: Url,
|
||||
val details: Struct = emptyMap()
|
||||
)
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.anytypeio.anytype.domain.objects
|
||||
|
||||
import com.anytypeio.anytype.core_models.Block
|
||||
import com.anytypeio.anytype.core_models.Command
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.NO_VALUE
|
||||
import com.anytypeio.anytype.core_models.ObjectTypeUniqueKeys
|
||||
import com.anytypeio.anytype.core_models.Position
|
||||
import com.anytypeio.anytype.core_models.Struct
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
import com.anytypeio.anytype.core_models.primitives.TypeKey
|
||||
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
||||
import com.anytypeio.anytype.domain.base.ResultInteractor
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
class CreatePrefilledNote @Inject constructor(
|
||||
private val repo: BlockRepository,
|
||||
dispatchers: AppCoroutineDispatchers
|
||||
) : ResultInteractor<CreatePrefilledNote.Params, Id>(dispatchers.io) {
|
||||
|
||||
override suspend fun doWork(params: Params): Id {
|
||||
val obj = repo.createObject(
|
||||
Command.CreateObject(
|
||||
typeKey = TypeKey(ObjectTypeUniqueKeys.NOTE),
|
||||
space = SpaceId(params.space),
|
||||
template = null,
|
||||
internalFlags = emptyList(),
|
||||
prefilled = params.details
|
||||
)
|
||||
)
|
||||
repo.create(
|
||||
command = Command.Create(
|
||||
context = obj.id,
|
||||
prototype = Block.Prototype.Text(
|
||||
style = Block.Content.Text.Style.P,
|
||||
text = params.text
|
||||
),
|
||||
position = Position.NONE,
|
||||
target = NO_VALUE
|
||||
)
|
||||
)
|
||||
return obj.id
|
||||
}
|
||||
|
||||
data class Params(
|
||||
val space: Id,
|
||||
val text: String,
|
||||
val details: Struct
|
||||
)
|
||||
}
|
|
@ -3,6 +3,7 @@ package com.anytypeio.anytype.domain.page
|
|||
import com.anytypeio.anytype.core_models.Command
|
||||
import com.anytypeio.anytype.core_models.Id
|
||||
import com.anytypeio.anytype.core_models.InternalFlags
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.Payload
|
||||
import com.anytypeio.anytype.core_models.Struct
|
||||
import com.anytypeio.anytype.core_models.primitives.SpaceId
|
||||
|
@ -66,7 +67,8 @@ class CreateObject @Inject constructor(
|
|||
objectId = result.id,
|
||||
event = result.event,
|
||||
appliedTemplate = template,
|
||||
typeKey = typeKey
|
||||
typeKey = typeKey,
|
||||
obj = ObjectWrapper.Basic(result.details)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -81,6 +83,7 @@ class CreateObject @Inject constructor(
|
|||
val objectId: Id,
|
||||
val event: Payload,
|
||||
val appliedTemplate: String? = null,
|
||||
val typeKey: TypeKey
|
||||
val typeKey: TypeKey,
|
||||
val obj: ObjectWrapper.Basic
|
||||
)
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package com.anytypeio.anytype.domain.spaces
|
||||
|
||||
import com.anytypeio.anytype.core_models.DVFilter
|
||||
import com.anytypeio.anytype.core_models.DVFilterCondition
|
||||
import com.anytypeio.anytype.core_models.DVSort
|
||||
import com.anytypeio.anytype.core_models.DVSortType
|
||||
import com.anytypeio.anytype.core_models.ObjectType
|
||||
import com.anytypeio.anytype.core_models.ObjectWrapper
|
||||
import com.anytypeio.anytype.core_models.Relations
|
||||
import com.anytypeio.anytype.core_models.restrictions.SpaceStatus
|
||||
import com.anytypeio.anytype.domain.base.AppCoroutineDispatchers
|
||||
import com.anytypeio.anytype.domain.base.ResultInteractor
|
||||
import com.anytypeio.anytype.domain.block.repo.BlockRepository
|
||||
import javax.inject.Inject
|
||||
|
||||
class GetSpaceViews @Inject constructor(
|
||||
private val repo: BlockRepository,
|
||||
dispatchers: AppCoroutineDispatchers
|
||||
): ResultInteractor<Unit, List<ObjectWrapper.SpaceView>>(dispatchers.io) {
|
||||
override suspend fun doWork(params: Unit): List<ObjectWrapper.SpaceView> {
|
||||
val result = repo.searchObjects(
|
||||
keys = listOf(
|
||||
Relations.ID,
|
||||
Relations.TARGET_SPACE_ID,
|
||||
Relations.NAME,
|
||||
Relations.ICON_IMAGE,
|
||||
Relations.ICON_OPTION,
|
||||
Relations.SPACE_ACCOUNT_STATUS
|
||||
),
|
||||
filters = listOf(
|
||||
DVFilter(
|
||||
relation = Relations.LAYOUT,
|
||||
value = ObjectType.Layout.SPACE_VIEW.code.toDouble(),
|
||||
condition = DVFilterCondition.EQUAL
|
||||
),
|
||||
DVFilter(
|
||||
relation = Relations.SPACE_ACCOUNT_STATUS,
|
||||
value = SpaceStatus.SPACE_DELETED.code.toDouble(),
|
||||
condition = DVFilterCondition.NOT_EQUAL
|
||||
),
|
||||
DVFilter(
|
||||
relation = Relations.SPACE_LOCAL_STATUS,
|
||||
value = SpaceStatus.OK.code.toDouble(),
|
||||
condition = DVFilterCondition.EQUAL
|
||||
)
|
||||
),
|
||||
sorts = listOf(
|
||||
DVSort(
|
||||
relationKey = Relations.LAST_OPENED_DATE,
|
||||
type = DVSortType.DESC,
|
||||
includeTime = true
|
||||
)
|
||||
),
|
||||
limit = 0
|
||||
)
|
||||
return result.map {
|
||||
ObjectWrapper.SpaceView(it)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,29 +1,20 @@
|
|||
package com.anytypeio.anytype.domain.auth
|
||||
|
||||
import com.anytypeio.anytype.core_models.CoroutineTestRule
|
||||
import com.anytypeio.anytype.core_models.StubAccount
|
||||
import com.anytypeio.anytype.core_models.StubAccountSetup
|
||||
import com.anytypeio.anytype.core_models.StubConfig
|
||||
import com.anytypeio.anytype.domain.account.AwaitAccountStartManager
|
||||
import com.anytypeio.anytype.domain.auth.interactor.ResumeAccount
|
||||
import com.anytypeio.anytype.domain.auth.repo.AuthRepository
|
||||
import com.anytypeio.anytype.domain.base.BaseUseCase
|
||||
import com.anytypeio.anytype.domain.config.ConfigStorage
|
||||
import com.anytypeio.anytype.domain.config.FeaturesConfigProvider
|
||||
import com.anytypeio.anytype.domain.device.PathProvider
|
||||
import com.anytypeio.anytype.domain.platform.MetricsProvider
|
||||
import com.anytypeio.anytype.domain.workspace.WorkspaceManager
|
||||
import com.anytypeio.anytype.test_utils.MockDataFactory
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.mockito.kotlin.doReturn
|
||||
import org.mockito.kotlin.stub
|
||||
import org.mockito.kotlin.times
|
||||
import org.mockito.kotlin.verifyBlocking
|
||||
|
||||
class ResumeAccountTest {
|
||||
|
||||
|
@ -49,6 +40,9 @@ class ResumeAccountTest {
|
|||
@Mock
|
||||
lateinit var metricsProvider: MetricsProvider
|
||||
|
||||
@Mock
|
||||
lateinit var awaitAccountStartManager: AwaitAccountStartManager
|
||||
|
||||
lateinit var resumeAccount: ResumeAccount
|
||||
|
||||
private val config = StubConfig()
|
||||
|
@ -61,7 +55,8 @@ class ResumeAccountTest {
|
|||
configStorage = configStorage,
|
||||
featuresConfigProvider = featuresConfigProvider,
|
||||
pathProvider = pathProvider,
|
||||
metricsProvider = metricsProvider
|
||||
metricsProvider = metricsProvider,
|
||||
awaitAccountStartManager = awaitAccountStartManager
|
||||
)
|
||||
}
|
||||
}
|
|
@ -9,6 +9,7 @@ import com.anytypeio.anytype.core_models.FeaturesConfig
|
|||
import com.anytypeio.anytype.core_models.NetworkMode
|
||||
import com.anytypeio.anytype.core_models.NetworkModeConfig
|
||||
import com.anytypeio.anytype.core_models.StubConfig
|
||||
import com.anytypeio.anytype.domain.account.AwaitAccountStartManager
|
||||
import com.anytypeio.anytype.domain.auth.interactor.SelectAccount
|
||||
import com.anytypeio.anytype.domain.auth.repo.AuthRepository
|
||||
import com.anytypeio.anytype.domain.base.Either
|
||||
|
@ -52,6 +53,9 @@ class StartAccountTest {
|
|||
@Mock
|
||||
lateinit var metricsProvider: MetricsProvider
|
||||
|
||||
@Mock
|
||||
lateinit var awaitAccountStartManager: AwaitAccountStartManager
|
||||
|
||||
lateinit var selectAccount: SelectAccount
|
||||
|
||||
private val config = StubConfig()
|
||||
|
@ -66,7 +70,8 @@ class StartAccountTest {
|
|||
repository = repo,
|
||||
configStorage = configStorage,
|
||||
featuresConfigProvider = featuresConfigProvider,
|
||||
metricsProvider = metricsProvider
|
||||
metricsProvider = metricsProvider,
|
||||
awaitAccountStartManager = awaitAccountStartManager
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -211,9 +211,9 @@ class GetObjectTypeTest {
|
|||
}
|
||||
|
||||
private fun stubGetObjectTypes(types: List<ObjectWrapper.Type>) {
|
||||
usecase.stub {
|
||||
repo.stub {
|
||||
onBlocking {
|
||||
repo.searchObjects(
|
||||
searchObjects(
|
||||
filters = emptyList(),
|
||||
keys = listOf(Relations.ID),
|
||||
sorts = emptyList(),
|
||||
|
|
|
@ -1,29 +1,33 @@
|
|||
[versions]
|
||||
middlewareVersion = "v0.30.0-rc3"
|
||||
kotlinVersion = '1.7.10'
|
||||
middlewareVersion = "v0.30.3"
|
||||
kotlinVersion = '1.8.22'
|
||||
|
||||
androidxCoreVersion = "1.10.1"
|
||||
androidxCoreVersion = "1.12.0"
|
||||
|
||||
androidxComposeVersion = '1.5.0'
|
||||
composeKotlinCompilerVersion = '1.3.1'
|
||||
composeMaterial3Version = '1.1.1'
|
||||
composeKotlinCompilerVersion = '1.4.8'
|
||||
composeMaterial3Version = '1.1.2'
|
||||
composeMaterialVersion = '1.5.0'
|
||||
composeConstraintLayoutVersion = '1.0.1'
|
||||
|
||||
activityComposeVersion = '1.7.2'
|
||||
dokkaVersion = '1.8.20'
|
||||
|
||||
activityComposeVersion = '1.8.1'
|
||||
composeReorderableVersion = '0.9.6'
|
||||
accompanistVersion = "0.30.0"
|
||||
appcompatVersion = '1.6.1'
|
||||
fragmentVersion = "1.6.1"
|
||||
androidXAnnotationVersion = '1.7.0'
|
||||
fragmentVersion = "1.6.2"
|
||||
exoplayerVersion = "2.19.1"
|
||||
wireVersion = "4.5.2"
|
||||
glideVersion = "4.14.2"
|
||||
mockitoKotlinVersion = "4.1.0"
|
||||
mockitoKotlinVersion = "5.1.0"
|
||||
junitVersion = '4.13.2'
|
||||
androidJunitVersion = "1.1.4"
|
||||
runnerVersion = "1.5.0"
|
||||
mockitoAndroidVersion = '4.10.0'
|
||||
kotlinCoroutinesVersion = '1.6.4'
|
||||
coroutineTestingVersion = '1.6.4'
|
||||
androidxTestCoreVersion = '1.5.0'
|
||||
androidxCoreTestingVersion = '2.2.0'
|
||||
androidxSecurityCryptoVersion = '1.0.0'
|
||||
|
@ -33,10 +37,10 @@ recyclerviewVersion = '1.3.2'
|
|||
cardviewVersion = '1.0.0'
|
||||
emojiCompatVersion = '1.1.0'
|
||||
viewPager2Version = '1.0.0'
|
||||
lifecycleVersion = '2.6.1'
|
||||
lifecycleRuntimeComposeVersion = '2.7.0-alpha01'
|
||||
navigationVersion = '2.7.4'
|
||||
navigationComposeVersion = '2.7.4'
|
||||
lifecycleVersion = '2.6.2'
|
||||
lifecycleRuntimeComposeVersion = '2.7.0-rc01'
|
||||
navigationVersion = '2.7.5'
|
||||
navigationComposeVersion = '2.7.5'
|
||||
shimmerLayoutVersion = '0.5.0'
|
||||
photoViewVersion = '2.3.0'
|
||||
daggerVersion = '2.45'
|
||||
|
@ -52,7 +56,6 @@ robolectricLatestVersion = '4.10.3'
|
|||
kluentVersion = '1.14'
|
||||
timberJunitVersion = '1.0.1'
|
||||
turbineVersion = '0.12.1'
|
||||
coroutineTestingVersion = '1.6.4'
|
||||
liveDataTestingVersion = '1.2.0'
|
||||
espressoVersion = '3.5.1'
|
||||
disableAnimationVersion = '2.0.0'
|
||||
|
@ -84,7 +87,7 @@ composeReorderable = { module = "org.burnoutcrew.composereorderable:reorderable"
|
|||
composeConstraintLayout = { module = "androidx.constraintlayout:constraintlayout-compose", version.ref = "composeConstraintLayoutVersion" }
|
||||
kotlinxSerializationJson = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version = "1.4.1" }
|
||||
appcompat = { module = "androidx.appcompat:appcompat", version.ref = "appcompatVersion" }
|
||||
androidAnnotations = { module = "androidx.annotation:annotation", version.ref = "appcompatVersion" }
|
||||
androidAnnotations = { module = "androidx.annotation:annotation", version.ref = "androidXAnnotationVersion" }
|
||||
design = { module = "com.google.android.material:material", version = "1.7.0" }
|
||||
fragment = { module = "androidx.fragment:fragment-ktx", version.ref = "fragmentVersion" }
|
||||
fragmentTesting = { module = "androidx.fragment:fragment-testing", version.ref = "fragmentVersion" }
|
||||
|
@ -162,12 +165,12 @@ appUpdater = { module = "com.github.PLPsiSoft:AndroidAppUpdater", version = "991
|
|||
[bundles]
|
||||
|
||||
[plugins]
|
||||
application = { id = "com.android.application", version = "8.1.4" }
|
||||
library = { id = "com.android.library", version = "8.1.4" }
|
||||
application = { id = "com.android.application", version = "8.2.0" }
|
||||
library = { id = "com.android.library", version = "8.2.0" }
|
||||
kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlinVersion" }
|
||||
dokka = { id = "org.jetbrains.dokka", version.ref = "kotlinVersion" }
|
||||
dokka = { id = "org.jetbrains.dokka", version.ref = "dokkaVersion" }
|
||||
kserialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlinVersion" }
|
||||
wire = { id = "com.squareup.wire", version = "4.4.3" }
|
||||
firebaseDistribution = { id = "com.google.firebase.appdistribution", version = "3.1.1" }
|
||||
firebaseDistribution = { id = "com.google.firebase.appdistribution", version = "4.0.1" }
|
||||
kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlinVersion" }
|
||||
gms = { id = "com.google.gms.google-services", version = "4.3.15" }
|
||||
gms = { id = "com.google.gms.google-services", version = "4.4.0" }
|
3
gradle/wrapper/gradle-wrapper.properties
vendored
3
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,5 +1,6 @@
|
|||
#Thu Dec 14 17:20:55 CET 2023
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
|
|
@ -16,5 +16,14 @@ dependencies {
|
|||
}
|
||||
|
||||
android {
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(17)
|
||||
}
|
||||
|
||||
namespace 'com.anytypeio.anytype.emojifier'
|
||||
}
|
|
@ -42,7 +42,7 @@ object Emojifier {
|
|||
try {
|
||||
var result = search(unicode)
|
||||
if (result == null) {
|
||||
if (unicode.last() == SEPARATOR) {
|
||||
if (unicode.lastOrNull() == SEPARATOR) {
|
||||
val sb = StringBuilder()
|
||||
unicode.forEachIndexed { index, char ->
|
||||
if (index < unicode.length.dec()) sb.append(char)
|
||||
|
|
|
@ -7,6 +7,14 @@ android {
|
|||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(17)
|
||||
}
|
||||
namespace 'com.anytypeio.anytype.library_page_icon_picker_widget'
|
||||
}
|
||||
|
||||
|
|
|
@ -20,5 +20,13 @@ dependencies {
|
|||
}
|
||||
|
||||
android {
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(17)
|
||||
}
|
||||
namespace 'com.anytypeio.anytype.library_syntax_highlighter'
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user