Skip to content

Commit a499dc4

Browse files
authored
Merge branch 'develop' into renovate/kotlin
2 parents 1afef53 + 4587b51 commit a499dc4

File tree

483 files changed

+4854
-1861
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

483 files changed

+4854
-1861
lines changed

.github/workflows/danger.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
- run: |
1414
npm install --save-dev @babel/plugin-transform-flow-strip-types
1515
- name: Danger
16-
uses: danger/[email protected].7
16+
uses: danger/[email protected].8
1717
with:
1818
args: "--dangerfile ./tools/danger/dangerfile.js"
1919
env:

.github/workflows/quality.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ jobs:
7070
yarn add danger-plugin-lint-report --dev
7171
- name: Danger lint
7272
if: always()
73-
uses: danger/[email protected].7
73+
uses: danger/[email protected].8
7474
with:
7575
args: "--dangerfile ./tools/danger/dangerfile-lint.js"
7676
env:

CHANGES.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
1+
Changes in Element X v0.1.2 (2023-08-16)
2+
========================================
3+
4+
Bugfixes 🐛
5+
----------
6+
- Filter push notifications using push rules. ([#640](https://github.com/vector-im/element-x-android/issues/640))
7+
- Use `for` instead of `forEach` in `DefaultDiffCacheInvalidator` to improve performance. ([#1035](https://github.com/vector-im/element-x-android/issues/1035))
8+
9+
In development 🚧
10+
----------------
11+
- [Poll] Render start event in the timeline ([#1031](https://github.com/vector-im/element-x-android/issues/1031))
12+
13+
Other changes
14+
-------------
15+
- Add Button component based on Compound designs ([#1021](https://github.com/vector-im/element-x-android/issues/1021))
16+
- Compound: implement dialogs. ([#1043](https://github.com/vector-im/element-x-android/issues/1043))
17+
- Compound: customise `IconButton` component. ([#1049](https://github.com/vector-im/element-x-android/issues/1049))
18+
- Compound: implement `DropdownMenu` customisations. ([#1050](https://github.com/vector-im/element-x-android/issues/1050))
19+
- Compound: implement Snackbar component. ([#1054](https://github.com/vector-im/element-x-android/issues/1054))
20+
21+
122
Changes in Element X v0.1.0 (2023-07-19)
223
========================================
324

app/src/main/kotlin/io/element/android/x/ElementXApplication.kt

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ import io.element.android.x.di.DaggerAppComponent
2424
import io.element.android.x.info.logApplicationInfo
2525
import io.element.android.x.initializer.CrashInitializer
2626
import io.element.android.x.initializer.EmojiInitializer
27-
import io.element.android.x.initializer.MatrixInitializer
28-
import io.element.android.x.initializer.TimberInitializer
27+
import io.element.android.x.initializer.TracingInitializer
2928

3029
class ElementXApplication : Application(), DaggerComponentOwner {
3130

@@ -39,8 +38,7 @@ class ElementXApplication : Application(), DaggerComponentOwner {
3938
appComponent = DaggerAppComponent.factory().create(applicationContext)
4039
AppInitializer.getInstance(this).apply {
4140
initializeComponent(CrashInitializer::class.java)
42-
initializeComponent(TimberInitializer::class.java)
43-
initializeComponent(MatrixInitializer::class.java)
41+
initializeComponent(TracingInitializer::class.java)
4442
initializeComponent(EmojiInitializer::class.java)
4543
}
4644
logApplicationInfo()

app/src/main/kotlin/io/element/android/x/di/AppBindings.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@
1717
package io.element.android.x.di
1818

1919
import com.squareup.anvil.annotations.ContributesTo
20+
import io.element.android.features.rageshake.api.reporter.BugReporter
2021
import io.element.android.libraries.designsystem.utils.SnackbarDispatcher
2122
import io.element.android.libraries.di.AppScope
23+
import io.element.android.libraries.matrix.api.tracing.TracingService
2224

2325
@ContributesTo(AppScope::class)
2426
interface AppBindings {
2527
fun mainDaggerComponentOwner(): MainDaggerComponentsOwner
2628
fun snackbarDispatcher(): SnackbarDispatcher
29+
fun tracingService(): TracingService
30+
fun bugReporter(): BugReporter
2731
}

app/src/main/kotlin/io/element/android/x/initializer/MatrixInitializer.kt

Lines changed: 0 additions & 36 deletions
This file was deleted.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright (c) 2022 New Vector Ltd
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.element.android.x.initializer
18+
19+
import android.content.Context
20+
import androidx.startup.Initializer
21+
import io.element.android.libraries.architecture.bindings
22+
import io.element.android.libraries.matrix.api.tracing.TracingConfiguration
23+
import io.element.android.libraries.matrix.api.tracing.TracingFilterConfigurations
24+
import io.element.android.libraries.matrix.api.tracing.WriteToFilesConfiguration
25+
import io.element.android.x.BuildConfig
26+
import io.element.android.x.di.AppBindings
27+
import timber.log.Timber
28+
29+
class TracingInitializer : Initializer<Unit> {
30+
31+
override fun create(context: Context) {
32+
val appBindings = context.bindings<AppBindings>()
33+
val tracingService = appBindings.tracingService()
34+
val bugReporter = appBindings.bugReporter()
35+
Timber.plant(tracingService.createTimberTree())
36+
val tracingConfiguration = if (BuildConfig.DEBUG) {
37+
TracingConfiguration(
38+
filterConfiguration = TracingFilterConfigurations.debug,
39+
writesToLogcat = true,
40+
writesToFilesConfiguration = WriteToFilesConfiguration.Disabled
41+
)
42+
} else {
43+
TracingConfiguration(
44+
filterConfiguration = TracingFilterConfigurations.release,
45+
writesToLogcat = false,
46+
writesToFilesConfiguration = WriteToFilesConfiguration.Enabled(
47+
directory = bugReporter.logDirectory().absolutePath,
48+
filenamePrefix = "logs"
49+
)
50+
)
51+
}
52+
bugReporter.cleanLogDirectoryIfNeeded()
53+
tracingService.setupTracing(tracingConfiguration)
54+
}
55+
56+
override fun dependencies(): List<Class<out Initializer<*>>> = mutableListOf()
57+
}

appnav/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ dependencies {
6565
testImplementation(libs.test.truth)
6666
testImplementation(libs.test.turbine)
6767
testImplementation(projects.libraries.matrix.test)
68+
testImplementation(projects.features.networkmonitor.test)
69+
testImplementation(projects.tests.testutils)
6870
testImplementation(projects.features.rageshake.test)
6971
testImplementation(projects.features.rageshake.impl)
7072
testImplementation(projects.services.appnavstate.test)

appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,12 @@ import io.element.android.libraries.matrix.ui.di.MatrixUIBindings
6969
import io.element.android.libraries.push.api.notifications.NotificationDrawerManager
7070
import io.element.android.services.appnavstate.api.AppNavigationStateService
7171
import kotlinx.coroutines.CoroutineScope
72+
import kotlinx.coroutines.FlowPreview
7273
import kotlinx.coroutines.flow.combine
73-
import kotlinx.coroutines.flow.distinctUntilChanged
74+
import kotlinx.coroutines.flow.debounce
7475
import kotlinx.coroutines.launch
7576
import kotlinx.parcelize.Parcelize
77+
import timber.log.Timber
7678

7779
@ContributesNode(AppScope::class)
7880
class LoggedInFlowNode @AssistedInject constructor(
@@ -123,7 +125,6 @@ class LoggedInFlowNode @AssistedInject constructor(
123125

124126
override fun onBuilt() {
125127
super.onBuilt()
126-
127128
lifecycle.subscribe(
128129
onCreate = {
129130
plugins<LifecycleCallback>().forEach { it.onFlowCreated(id, inputs.matrixClient) }
@@ -138,13 +139,11 @@ class LoggedInFlowNode @AssistedInject constructor(
138139
backstack.push(NavTarget.Ftue)
139140
}
140141
},
141-
onStart = {
142-
lifecycleScope.launch {
143-
syncService.startSync()
144-
}
145-
},
146142
onStop = {
147-
syncService.stopSync()
143+
//Counterpart startSync is done in observeSyncStateAndNetworkStatus method.
144+
coroutineScope.launch {
145+
syncService.stopSync()
146+
}
148147
},
149148
onDestroy = {
150149
plugins<LifecycleCallback>().forEach { it.onFlowReleased(id, inputs.matrixClient) }
@@ -153,22 +152,23 @@ class LoggedInFlowNode @AssistedInject constructor(
153152
loggedInFlowProcessor.stopObserving()
154153
}
155154
)
156-
157155
observeSyncStateAndNetworkStatus()
158156
}
159157

158+
@OptIn(FlowPreview::class)
160159
private fun observeSyncStateAndNetworkStatus() {
161160
lifecycleScope.launch {
162-
repeatOnLifecycle(Lifecycle.State.RESUMED) {
161+
repeatOnLifecycle(Lifecycle.State.STARTED) {
163162
combine(
164-
syncService.syncState,
163+
// small debounce to avoid spamming startSync when the state is changing quickly in case of error.
164+
syncService.syncState.debounce(100),
165165
networkMonitor.connectivity
166166
) { syncState, networkStatus ->
167-
syncState == SyncState.Error && networkStatus == NetworkStatus.Online
167+
Pair(syncState, networkStatus)
168168
}
169-
.distinctUntilChanged()
170-
.collect { restartSync ->
171-
if (restartSync) {
169+
.collect { (syncState, networkStatus) ->
170+
Timber.d("Sync state: $syncState, network status: $networkStatus")
171+
if (syncState != SyncState.Running && networkStatus == NetworkStatus.Online) {
172172
syncService.startSync()
173173
}
174174
}
@@ -351,3 +351,4 @@ class LoggedInFlowNode @AssistedInject constructor(
351351
backstack.push(NavTarget.InviteList)
352352
}
353353
}
354+

appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInPresenter.kt

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,27 @@ import android.os.Build
2121
import androidx.compose.runtime.Composable
2222
import androidx.compose.runtime.LaunchedEffect
2323
import androidx.compose.runtime.collectAsState
24+
import androidx.compose.runtime.getValue
25+
import androidx.compose.runtime.mutableStateOf
26+
import androidx.compose.runtime.remember
27+
import androidx.compose.runtime.setValue
28+
import io.element.android.features.networkmonitor.api.NetworkMonitor
29+
import io.element.android.features.networkmonitor.api.NetworkStatus
2430
import io.element.android.libraries.architecture.Presenter
2531
import io.element.android.libraries.matrix.api.MatrixClient
32+
import io.element.android.libraries.matrix.api.roomlist.RoomListService
2633
import io.element.android.libraries.permissions.api.PermissionsPresenter
2734
import io.element.android.libraries.permissions.noop.NoopPermissionsPresenter
2835
import io.element.android.libraries.push.api.PushService
36+
import kotlinx.coroutines.delay
2937
import javax.inject.Inject
3038

39+
private const val DELAY_BEFORE_SHOWING_SYNC_SPINNER_IN_MILLIS = 1500L
40+
3141
class LoggedInPresenter @Inject constructor(
3242
private val matrixClient: MatrixClient,
3343
private val permissionsPresenterFactory: PermissionsPresenter.Factory,
44+
private val networkMonitor: NetworkMonitor,
3445
private val pushService: PushService,
3546
) : Presenter<LoggedInState> {
3647

@@ -53,18 +64,25 @@ class LoggedInPresenter @Inject constructor(
5364
pushService.registerWith(matrixClient, pushProvider, distributor)
5465
}
5566

56-
val syncState = matrixClient.syncService().syncState.collectAsState()
67+
val roomListState by matrixClient.roomListService.state.collectAsState()
68+
val networkStatus by networkMonitor.connectivity.collectAsState()
5769
val permissionsState = postNotificationPermissionsPresenter.present()
58-
59-
// fun handleEvents(event: LoggedInEvents) {
60-
// when (event) {
61-
// }
62-
// }
63-
70+
var showSyncSpinner by remember {
71+
mutableStateOf(false)
72+
}
73+
LaunchedEffect(roomListState, networkStatus) {
74+
showSyncSpinner = when {
75+
networkStatus == NetworkStatus.Offline -> false
76+
roomListState == RoomListService.State.Running -> false
77+
else -> {
78+
delay(DELAY_BEFORE_SHOWING_SYNC_SPINNER_IN_MILLIS)
79+
true
80+
}
81+
}
82+
}
6483
return LoggedInState(
65-
syncState = syncState.value,
84+
showSyncSpinner = showSyncSpinner,
6685
permissionsState = permissionsState,
67-
// eventSink = ::handleEvents
6886
)
6987
}
7088
}

appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInState.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,9 @@
1616

1717
package io.element.android.appnav.loggedin
1818

19-
import io.element.android.libraries.matrix.api.sync.SyncState
2019
import io.element.android.libraries.permissions.api.PermissionsState
2120

2221
data class LoggedInState(
23-
val syncState: SyncState,
22+
val showSyncSpinner: Boolean,
2423
val permissionsState: PermissionsState,
25-
// val eventSink: (LoggedInEvents) -> Unit
2624
)

appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInStateProvider.kt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,20 @@
1717
package io.element.android.appnav.loggedin
1818

1919
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
20-
import io.element.android.libraries.matrix.api.sync.SyncState
2120
import io.element.android.libraries.permissions.api.createDummyPostNotificationPermissionsState
2221

2322
open class LoggedInStateProvider : PreviewParameterProvider<LoggedInState> {
2423
override val values: Sequence<LoggedInState>
2524
get() = sequenceOf(
26-
aLoggedInState(),
27-
aLoggedInState(syncState = SyncState.Idle),
25+
aLoggedInState(false),
26+
aLoggedInState(true),
2827
// Add other state here
2928
)
3029
}
3130

3231
fun aLoggedInState(
33-
syncState: SyncState = SyncState.Running,
32+
showSyncSpinner: Boolean = true,
3433
) = LoggedInState(
35-
syncState = syncState,
34+
showSyncSpinner = showSyncSpinner,
3635
permissionsState = createDummyPostNotificationPermissionsState(),
37-
// eventSink = {}
3836
)

appnav/src/main/kotlin/io/element/android/appnav/loggedin/LoggedInView.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ fun LoggedInView(
4747
modifier = Modifier
4848
.padding(top = 8.dp)
4949
.align(Alignment.TopCenter),
50-
syncState = state.syncState,
50+
isVisible = state.showSyncSpinner,
5151
)
5252
PermissionsView(
5353
state = state.permissionsState,

0 commit comments

Comments
 (0)