diff --git a/.github/workflows/triage-move-labelled.yml b/.github/workflows/triage-move-labelled.yml
index 39f7a5de09..67c4e9dbab 100644
--- a/.github/workflows/triage-move-labelled.yml
+++ b/.github/workflows/triage-move-labelled.yml
@@ -34,7 +34,7 @@ jobs:
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
- mutation add_to_project($projectid:String!,$contentid:String!) {
+ mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
projectNextItem {
id
@@ -47,45 +47,30 @@ jobs:
PROJECT_ID: "PN_kwDOAM0swc0sUA"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
- spaces_issues_to_old_board:
- name: Spaces issues to old Delight project board
- runs-on: ubuntu-latest
- if: >
- contains(github.event.issue.labels.*.name, 'A-Spaces') ||
- contains(github.event.issue.labels.*.name, 'A-Space-Settings') ||
- contains(github.event.issue.labels.*.name, 'A-Subspaces')
- steps:
- - uses: konradpabjan/move-labeled-or-milestoned-issue@219d384e03fa4b6460cd24f9f37d19eb033a4338
- with:
- action-token: "${{ secrets.ELEMENT_BOT_TOKEN }}"
- project-url: "https://github.com/orgs/vector-im/projects/6"
- column-name: "đź“Ą Inbox"
- label-name: "A-Spaces"
-
- spaces_issues_to_new_board:
- name: Spaces issues to new Delight project board
- runs-on: ubuntu-latest
- if: >
- contains(github.event.issue.labels.*.name, 'A-Spaces') ||
- contains(github.event.issue.labels.*.name, 'A-Space-Settings') ||
- contains(github.event.issue.labels.*.name, 'A-Subspaces')
- steps:
- - uses: octokit/graphql-action@v2.x
- with:
- headers: '{"GraphQL-Features": "projects_next_graphql"}'
- query: |
- mutation add_to_project($projectid:String!,$contentid:String!) {
- addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
- projectNextItem {
- id
- }
- }
- }
- projectid: ${{ env.PROJECT_ID }}
- contentid: ${{ github.event.issue.node_id }}
- env:
- PROJECT_ID: "PN_kwDOAM0swc1HvQ"
- GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
+# delight_issues_to_board:
+# name: Spaces issues to new Delight project board
+# runs-on: ubuntu-latest
+# if: >
+# contains(github.event.issue.labels.*.name, 'A-Spaces') ||
+# contains(github.event.issue.labels.*.name, 'A-Space-Settings') ||
+# contains(github.event.issue.labels.*.name, 'A-Subspaces')
+# steps:
+# - uses: octokit/graphql-action@v2.x
+# with:
+# headers: '{"GraphQL-Features": "projects_next_graphql"}'
+# query: |
+# mutation add_to_project($projectid:ID!,$contentid:ID!) {
+# addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
+# projectNextItem {
+# id
+# }
+# }
+# }
+# projectid: ${{ env.PROJECT_ID }}
+# contentid: ${{ github.event.issue.node_id }}
+# env:
+# PROJECT_ID: "PN_kwDOAM0swc1HvQ"
+# GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
move_voice-message_issues:
name: A-Voice Messages to voice message board
@@ -97,7 +82,7 @@ jobs:
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
- mutation add_to_project($projectid:String!,$contentid:String!) {
+ mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
projectNextItem {
id
@@ -120,7 +105,7 @@ jobs:
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
- mutation add_to_project($projectid:String!,$contentid:String!) {
+ mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
projectNextItem {
id
@@ -132,3 +117,26 @@ jobs:
env:
PROJECT_ID: "PN_kwDOAM0swc0rRA"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
+
+ move_message_bubbles_issues:
+ name: A-Message-Bubbles to Message bubbles board
+ runs-on: ubuntu-latest
+ if: >
+ contains(github.event.issue.labels.*.name, 'A-Message-Bubbles')
+ steps:
+ - uses: octokit/graphql-action@v2.x
+ with:
+ headers: '{"GraphQL-Features": "projects_next_graphql"}'
+ query: |
+ mutation add_to_project($projectid:ID!,$contentid:ID!) {
+ addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
+ projectNextItem {
+ id
+ }
+ }
+ }
+ projectid: ${{ env.PROJECT_ID }}
+ contentid: ${{ github.event.issue.node_id }}
+ env:
+ PROJECT_ID: "PN_kwDOAM0swc3m-g"
+ GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
diff --git a/changelog.d/4278.feature b/changelog.d/4278.feature
new file mode 100644
index 0000000000..fe82755186
--- /dev/null
+++ b/changelog.d/4278.feature
@@ -0,0 +1 @@
+Updates URL previews to match latest designs
\ No newline at end of file
diff --git a/changelog.d/4638.feature b/changelog.d/4638.feature
new file mode 100644
index 0000000000..0f8bd36465
--- /dev/null
+++ b/changelog.d/4638.feature
@@ -0,0 +1 @@
+Add a help section in the settings.
\ No newline at end of file
diff --git a/changelog.d/4660.feature b/changelog.d/4660.feature
new file mode 100644
index 0000000000..4eca82eaf5
--- /dev/null
+++ b/changelog.d/4660.feature
@@ -0,0 +1 @@
+Create a legal screen in the setting to group all the different policies.
\ No newline at end of file
diff --git a/changelog.d/4666.misc b/changelog.d/4666.misc
new file mode 100644
index 0000000000..9401963de5
--- /dev/null
+++ b/changelog.d/4666.misc
@@ -0,0 +1 @@
+Add automation to move message bubbles issues to message bubbles board.
diff --git a/changelog.d/4671.misc b/changelog.d/4671.misc
new file mode 100644
index 0000000000..1d2282038e
--- /dev/null
+++ b/changelog.d/4671.misc
@@ -0,0 +1 @@
+Fix graphql warning in issue workflow automation
diff --git a/dependencies.gradle b/dependencies.gradle
index aa57546de0..4a076a23bd 100644
--- a/dependencies.gradle
+++ b/dependencies.gradle
@@ -7,7 +7,7 @@ ext.versions = [
'targetCompat' : JavaVersion.VERSION_11,
]
-def gradle = "7.0.3"
+def gradle = "7.0.4"
// Ref: https://kotlinlang.org/releases.html
def kotlin = "1.5.31"
def kotlinCoroutines = "1.5.2"
@@ -19,7 +19,7 @@ def moshi = "1.12.0"
def lifecycle = "2.4.0"
def flowBinding = "1.2.0"
def epoxy = "4.6.2"
-def mavericks = "2.4.0"
+def mavericks = "2.5.0"
def glide = "4.12.0"
def bigImageViewer = "1.8.1"
def jjwt = "0.11.2"
diff --git a/library/ui-styles/src/main/res/values/dimens.xml b/library/ui-styles/src/main/res/values/dimens.xml
index 519920786c..864f3d3d7f 100644
--- a/library/ui-styles/src/main/res/values/dimens.xml
+++ b/library/ui-styles/src/main/res/values/dimens.xml
@@ -39,4 +39,7 @@
320dp
+
+
+ 8dp
\ No newline at end of file
diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle
index cec5982658..477f971e04 100644
--- a/matrix-sdk-android/build.gradle
+++ b/matrix-sdk-android/build.gradle
@@ -9,7 +9,7 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath "io.realm:realm-gradle-plugin:10.8.1"
+ classpath "io.realm:realm-gradle-plugin:10.9.0"
}
}
@@ -158,7 +158,7 @@ dependencies {
implementation libs.apache.commonsImaging
// Phone number https://github.com/google/libphonenumber
- implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.38'
+ implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.39'
testImplementation libs.tests.junit
testImplementation 'org.robolectric:robolectric:4.7.3'
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/terms/TermsService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/terms/TermsService.kt
index 10ce0829d0..e64cf1872e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/terms/TermsService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/terms/TermsService.kt
@@ -16,6 +16,8 @@
package org.matrix.android.sdk.api.session.terms
+import org.matrix.android.sdk.internal.session.terms.TermsResponse
+
interface TermsService {
enum class ServiceType {
IntegrationManager,
@@ -28,4 +30,10 @@ interface TermsService {
baseUrl: String,
agreedUrls: List,
token: String?)
+
+ /**
+ * Get the homeserver terms, from the register API.
+ * Will be updated once https://github.com/matrix-org/matrix-doc/pull/3012 will be implemented.
+ */
+ suspend fun getHomeserverTerms(baseUrl: String): TermsResponse
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/DefaultTermsService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/DefaultTermsService.kt
index d40fd8d076..c52c6a404e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/DefaultTermsService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/DefaultTermsService.kt
@@ -18,10 +18,13 @@ package org.matrix.android.sdk.internal.session.terms
import dagger.Lazy
import okhttp3.OkHttpClient
+import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
+import org.matrix.android.sdk.api.failure.toRegistrationFlowResponse
import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.terms.GetTermsResponse
import org.matrix.android.sdk.api.session.terms.TermsService
+import org.matrix.android.sdk.api.util.JsonDict
import org.matrix.android.sdk.internal.di.UnauthenticatedWithCertificate
import org.matrix.android.sdk.internal.network.NetworkConstants
import org.matrix.android.sdk.internal.network.RetrofitFactory
@@ -55,6 +58,27 @@ internal class DefaultTermsService @Inject constructor(
return GetTermsResponse(termsResponse, getAlreadyAcceptedTermUrlsFromAccountData())
}
+ /**
+ * We use a trick here to get the homeserver T&C, we use the register API
+ */
+ override suspend fun getHomeserverTerms(baseUrl: String): TermsResponse {
+ return try {
+ executeRequest(null) {
+ termsAPI.register(baseUrl + NetworkConstants.URI_API_PREFIX_PATH_R0 + "register")
+ }
+ // Return empty result if it succeed, but it should never happen
+ TermsResponse()
+ } catch (throwable: Throwable) {
+ @Suppress("UNCHECKED_CAST")
+ TermsResponse(
+ policies = (throwable.toRegistrationFlowResponse()
+ ?.params
+ ?.get(LoginFlowTypes.TERMS) as? JsonDict)
+ ?.get("policies") as? JsonDict
+ )
+ }
+ }
+
override suspend fun agreeToTerms(serviceType: TermsService.ServiceType,
baseUrl: String,
agreedUrls: List,
@@ -91,7 +115,7 @@ internal class DefaultTermsService @Inject constructor(
private fun buildUrl(baseUrl: String, serviceType: TermsService.ServiceType): String {
val servicePath = when (serviceType) {
TermsService.ServiceType.IntegrationManager -> NetworkConstants.URI_INTEGRATION_MANAGER_PATH
- TermsService.ServiceType.IdentityService -> NetworkConstants.URI_IDENTITY_PATH_V2
+ TermsService.ServiceType.IdentityService -> NetworkConstants.URI_IDENTITY_PATH_V2
}
return "${baseUrl.ensureTrailingSlash()}$servicePath"
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/TermsAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/TermsAPI.kt
index 91d27030de..fb6aff5a9e 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/TermsAPI.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/TermsAPI.kt
@@ -16,6 +16,8 @@
package org.matrix.android.sdk.internal.session.terms
+import org.matrix.android.sdk.api.util.JsonDict
+import org.matrix.android.sdk.api.util.emptyJsonDict
import org.matrix.android.sdk.internal.network.HttpHeaders
import retrofit2.http.Body
import retrofit2.http.GET
@@ -37,4 +39,12 @@ internal interface TermsAPI {
suspend fun agreeToTerms(@Url url: String,
@Body params: AcceptTermsBody,
@Header(HttpHeaders.Authorization) token: String)
+
+ /**
+ * API to retrieve the terms for a homeserver. The API /terms does not exist yet, so retrieve the terms from the login flow.
+ * We do not care about the result (Credentials)
+ */
+ @POST
+ suspend fun register(@Url url: String,
+ @Body body: JsonDict = emptyJsonDict)
}
diff --git a/vector/build.gradle b/vector/build.gradle
index d29f36c877..26bfd3badf 100644
--- a/vector/build.gradle
+++ b/vector/build.gradle
@@ -141,7 +141,6 @@ android {
resValue "string", "build_number", "\"${buildNumber}\""
buildConfigField "im.vector.app.features.VectorFeatures.LoginVersion", "LOGIN_VERSION", "im.vector.app.features.VectorFeatures.LoginVersion.V1"
- buildConfigField "im.vector.app.features.VectorFeatures.NotificationSettingsVersion", "NOTIFICATION_SETTINGS_VERSION", "im.vector.app.features.VectorFeatures.NotificationSettingsVersion.V2"
buildConfigField "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy", "outboundSessionKeySharingStrategy", "im.vector.app.features.crypto.keysrequest.OutboundSessionKeySharingStrategy.WhenTyping"
@@ -365,7 +364,7 @@ dependencies {
implementation 'com.facebook.stetho:stetho:1.6.0'
// Phone number https://github.com/google/libphonenumber
- implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.38'
+ implementation 'com.googlecode.libphonenumber:libphonenumber:8.12.39'
// FlowBinding
implementation libs.github.flowBinding
diff --git a/vector/src/androidTest/java/im/vector/app/ui/robot/settings/SettingsNotificationsRobot.kt b/vector/src/androidTest/java/im/vector/app/ui/robot/settings/SettingsNotificationsRobot.kt
index 4dddc4c9cc..433a70b5e3 100644
--- a/vector/src/androidTest/java/im/vector/app/ui/robot/settings/SettingsNotificationsRobot.kt
+++ b/vector/src/androidTest/java/im/vector/app/ui/robot/settings/SettingsNotificationsRobot.kt
@@ -18,29 +18,19 @@ package im.vector.app.ui.robot.settings
import androidx.test.espresso.Espresso.pressBack
import com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn
-import im.vector.app.BuildConfig
import im.vector.app.R
import im.vector.app.espresso.tools.clickOnPreference
-import im.vector.app.features.VectorFeatures
class SettingsNotificationsRobot {
fun crawl() {
- when (BuildConfig.NOTIFICATION_SETTINGS_VERSION!!) {
- VectorFeatures.NotificationSettingsVersion.V1 -> {
- clickOn(R.string.settings_notification_advanced)
- pressBack()
- }
- VectorFeatures.NotificationSettingsVersion.V2 -> {
- clickOn(R.string.settings_notification_default)
- pressBack()
- clickOn(R.string.settings_notification_mentions_and_keywords)
- // TODO Test adding a keyword?
- pressBack()
- clickOn(R.string.settings_notification_other)
- pressBack()
- }
- }
+ clickOn(R.string.settings_notification_default)
+ pressBack()
+ clickOn(R.string.settings_notification_mentions_and_keywords)
+ // TODO Test adding a keyword?
+ pressBack()
+ clickOn(R.string.settings_notification_other)
+ pressBack()
/*
clickOn(R.string.settings_noisy_notifications_preferences)
diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt
index b8d00fac5a..43bb505a5e 100644
--- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt
+++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt
@@ -133,6 +133,7 @@ import im.vector.app.features.settings.devtools.KeyRequestsFragment
import im.vector.app.features.settings.devtools.OutgoingKeyRequestListFragment
import im.vector.app.features.settings.homeserver.HomeserverSettingsFragment
import im.vector.app.features.settings.ignored.VectorSettingsIgnoredUsersFragment
+import im.vector.app.features.settings.legals.LegalsFragment
import im.vector.app.features.settings.locale.LocalePickerFragment
import im.vector.app.features.settings.notifications.VectorSettingsAdvancedNotificationPreferenceFragment
import im.vector.app.features.settings.notifications.VectorSettingsNotificationPreferenceFragment
@@ -699,6 +700,11 @@ interface FragmentModule {
@FragmentKey(DiscoverySettingsFragment::class)
fun bindDiscoverySettingsFragment(fragment: DiscoverySettingsFragment): Fragment
+ @Binds
+ @IntoMap
+ @FragmentKey(LegalsFragment::class)
+ fun bindLegalsFragment(fragment: LegalsFragment): Fragment
+
@Binds
@IntoMap
@FragmentKey(ReviewTermsFragment::class)
diff --git a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
index cac694e84e..37721ca9f9 100644
--- a/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
+++ b/vector/src/main/java/im/vector/app/core/di/MavericksViewModelModule.kt
@@ -85,6 +85,7 @@ import im.vector.app.features.settings.devtools.KeyRequestListViewModel
import im.vector.app.features.settings.devtools.KeyRequestViewModel
import im.vector.app.features.settings.homeserver.HomeserverSettingsViewModel
import im.vector.app.features.settings.ignored.IgnoredUsersViewModel
+import im.vector.app.features.settings.legals.LegalsViewModel
import im.vector.app.features.settings.locale.LocalePickerViewModel
import im.vector.app.features.settings.push.PushGatewaysViewModel
import im.vector.app.features.settings.threepids.ThreePidsSettingsViewModel
@@ -504,6 +505,11 @@ interface MavericksViewModelModule {
@MavericksViewModelKey(DiscoverySettingsViewModel::class)
fun discoverySettingsViewModelFactory(factory: DiscoverySettingsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
+ @Binds
+ @IntoMap
+ @MavericksViewModelKey(LegalsViewModel::class)
+ fun legalsViewModelFactory(factory: LegalsViewModel.Factory): MavericksAssistedViewModelFactory<*, *>
+
@Binds
@IntoMap
@MavericksViewModelKey(RoomDetailViewModel::class)
diff --git a/vector/src/main/java/im/vector/app/core/ui/views/SendStateImageView.kt b/vector/src/main/java/im/vector/app/core/ui/views/SendStateImageView.kt
index cb1d08d2e5..3d710e2b24 100644
--- a/vector/src/main/java/im/vector/app/core/ui/views/SendStateImageView.kt
+++ b/vector/src/main/java/im/vector/app/core/ui/views/SendStateImageView.kt
@@ -20,7 +20,7 @@ import android.content.Context
import android.content.res.ColorStateList
import android.util.AttributeSet
import androidx.appcompat.widget.AppCompatImageView
-import androidx.core.view.isVisible
+import androidx.core.view.isInvisible
import im.vector.app.R
import im.vector.app.features.home.room.detail.timeline.item.SendStateDecoration
import im.vector.app.features.themes.ThemeUtils
@@ -38,28 +38,28 @@ class SendStateImageView @JvmOverloads constructor(
}
fun render(sendState: SendStateDecoration) {
- isVisible = when (sendState) {
+ isInvisible = when (sendState) {
SendStateDecoration.SENDING_NON_MEDIA -> {
setImageResource(R.drawable.ic_sending_message)
imageTintList = ColorStateList.valueOf(ThemeUtils.getColor(context, R.attr.vctr_content_tertiary))
contentDescription = context.getString(R.string.event_status_a11y_sending)
- true
+ false
}
SendStateDecoration.SENT -> {
setImageResource(R.drawable.ic_message_sent)
imageTintList = ColorStateList.valueOf(ThemeUtils.getColor(context, R.attr.vctr_content_tertiary))
contentDescription = context.getString(R.string.event_status_a11y_sent)
- true
+ false
}
SendStateDecoration.FAILED -> {
setImageResource(R.drawable.ic_sending_message_failed)
imageTintList = null
contentDescription = context.getString(R.string.event_status_a11y_failed)
- true
+ false
}
SendStateDecoration.SENDING_MEDIA,
SendStateDecoration.NONE -> {
- false
+ true
}
}
}
diff --git a/vector/src/main/java/im/vector/app/core/utils/Dialogs.kt b/vector/src/main/java/im/vector/app/core/utils/Dialogs.kt
index ad01546782..11b9a693da 100644
--- a/vector/src/main/java/im/vector/app/core/utils/Dialogs.kt
+++ b/vector/src/main/java/im/vector/app/core/utils/Dialogs.kt
@@ -23,7 +23,7 @@ import android.webkit.WebViewClient
import android.widget.TextView
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.R
-import im.vector.app.features.discovery.IdentityServerWithTerms
+import im.vector.app.features.discovery.ServerAndPolicies
import me.gujun.android.span.link
import me.gujun.android.span.span
@@ -45,7 +45,7 @@ fun Context.displayInWebView(url: String) {
.show()
}
-fun Context.showIdentityServerConsentDialog(identityServerWithTerms: IdentityServerWithTerms?,
+fun Context.showIdentityServerConsentDialog(identityServerWithTerms: ServerAndPolicies?,
consentCallBack: (() -> Unit)) {
// Build the message
val content = span {
diff --git a/vector/src/main/java/im/vector/app/features/VectorFeatures.kt b/vector/src/main/java/im/vector/app/features/VectorFeatures.kt
index b40d2d02f2..e106f7f75f 100644
--- a/vector/src/main/java/im/vector/app/features/VectorFeatures.kt
+++ b/vector/src/main/java/im/vector/app/features/VectorFeatures.kt
@@ -21,7 +21,6 @@ import im.vector.app.BuildConfig
interface VectorFeatures {
fun loginVersion(): LoginVersion
- fun notificationSettingsVersion(): NotificationSettingsVersion
enum class LoginVersion {
V1,
@@ -36,5 +35,4 @@ interface VectorFeatures {
class DefaultVectorFeatures : VectorFeatures {
override fun loginVersion(): VectorFeatures.LoginVersion = BuildConfig.LOGIN_VERSION
- override fun notificationSettingsVersion(): VectorFeatures.NotificationSettingsVersion = BuildConfig.NOTIFICATION_SETTINGS_VERSION
}
diff --git a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewEvents.kt b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewEvents.kt
index c7fd13a62c..cb8d137c05 100644
--- a/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewEvents.kt
+++ b/vector/src/main/java/im/vector/app/features/contactsbook/ContactsBookViewEvents.kt
@@ -17,9 +17,9 @@
package im.vector.app.features.contactsbook
import im.vector.app.core.platform.VectorViewEvents
-import im.vector.app.features.discovery.IdentityServerWithTerms
+import im.vector.app.features.discovery.ServerAndPolicies
sealed class ContactsBookViewEvents : VectorViewEvents {
data class Failure(val throwable: Throwable) : ContactsBookViewEvents()
- data class OnPoliciesRetrieved(val identityServerWithTerms: IdentityServerWithTerms?) : ContactsBookViewEvents()
+ data class OnPoliciesRetrieved(val identityServerWithTerms: ServerAndPolicies?) : ContactsBookViewEvents()
}
diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoveryPolicyItem.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoveryPolicyItem.kt
index c97a2286ae..4df4146d2f 100644
--- a/vector/src/main/java/im/vector/app/features/discovery/DiscoveryPolicyItem.kt
+++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoveryPolicyItem.kt
@@ -24,6 +24,7 @@ import im.vector.app.R
import im.vector.app.core.epoxy.ClickListener
import im.vector.app.core.epoxy.VectorEpoxyHolder
import im.vector.app.core.epoxy.onClick
+import im.vector.app.core.extensions.setTextOrHide
@EpoxyModelClass(layout = R.layout.item_discovery_policy)
abstract class DiscoveryPolicyItem : EpoxyModelWithHolder() {
@@ -40,7 +41,7 @@ abstract class DiscoveryPolicyItem : EpoxyModelWithHolder = Uninitialized,
+ val identityServer: Async = Uninitialized,
val emailList: Async> = Uninitialized,
val phoneNumbersList: Async> = Uninitialized,
// Can be true if terms are updated
diff --git a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt
index 4eb3fada28..19f233fe98 100644
--- a/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/discovery/DiscoverySettingsViewModel.kt
@@ -78,7 +78,7 @@ class DiscoverySettingsViewModel @AssistedInject constructor(
init {
setState {
copy(
- identityServer = Success(identityService.getCurrentIdentityServerUrl()?.let { IdentityServerWithTerms(it, emptyList()) }),
+ identityServer = Success(identityService.getCurrentIdentityServerUrl()?.let { ServerAndPolicies(it, emptyList()) }),
userConsent = identityService.getUserConsent()
)
}
@@ -151,7 +151,7 @@ class DiscoverySettingsViewModel @AssistedInject constructor(
val data = session.identityService().setNewIdentityServer(action.url)
setState {
copy(
- identityServer = Success(IdentityServerWithTerms(data, emptyList())),
+ identityServer = Success(ServerAndPolicies(data, emptyList())),
userConsent = false
)
}
@@ -401,7 +401,7 @@ class DiscoverySettingsViewModel @AssistedInject constructor(
}
}
- private suspend fun fetchIdentityServerWithTerms(): IdentityServerWithTerms? {
+ private suspend fun fetchIdentityServerWithTerms(): ServerAndPolicies? {
return session.fetchIdentityServerWithTerms(stringProvider.getString(R.string.resources_language))
}
}
diff --git a/vector/src/main/java/im/vector/app/features/discovery/Extensions.kt b/vector/src/main/java/im/vector/app/features/discovery/Extensions.kt
index bf6bd89938..24d675695b 100644
--- a/vector/src/main/java/im/vector/app/features/discovery/Extensions.kt
+++ b/vector/src/main/java/im/vector/app/features/discovery/Extensions.kt
@@ -19,22 +19,35 @@ package im.vector.app.features.discovery
import im.vector.app.core.utils.ensureProtocol
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.terms.TermsService
+import org.matrix.android.sdk.internal.session.terms.TermsResponse
-suspend fun Session.fetchIdentityServerWithTerms(userLanguage: String): IdentityServerWithTerms? {
- val identityServerUrl = identityService().getCurrentIdentityServerUrl()
- return identityServerUrl?.let {
- val terms = getTerms(TermsService.ServiceType.IdentityService, identityServerUrl.ensureProtocol())
- .serverResponse
- .getLocalizedTerms(userLanguage)
- val policyUrls = terms.mapNotNull {
- val name = it.localizedName ?: it.policyName
- val url = it.localizedUrl
- if (name == null || url == null) {
- null
- } else {
- IdentityServerPolicy(name = name, url = url)
+suspend fun Session.fetchIdentityServerWithTerms(userLanguage: String): ServerAndPolicies? {
+ return identityService().getCurrentIdentityServerUrl()
+ ?.let { identityServerUrl ->
+ val termsResponse = getTerms(TermsService.ServiceType.IdentityService, identityServerUrl.ensureProtocol())
+ .serverResponse
+ buildServerAndPolicies(identityServerUrl, termsResponse, userLanguage)
}
- }
- IdentityServerWithTerms(identityServerUrl, policyUrls)
- }
+}
+
+suspend fun Session.fetchHomeserverWithTerms(userLanguage: String): ServerAndPolicies {
+ val homeserverUrl = sessionParams.homeServerUrl
+ val terms = getHomeserverTerms(homeserverUrl.ensureProtocol())
+ return buildServerAndPolicies(homeserverUrl, terms, userLanguage)
+}
+
+private fun buildServerAndPolicies(serviceUrl: String,
+ termsResponse: TermsResponse,
+ userLanguage: String): ServerAndPolicies {
+ val terms = termsResponse.getLocalizedTerms(userLanguage)
+ val policyUrls = terms.mapNotNull {
+ val name = it.localizedName ?: it.policyName
+ val url = it.localizedUrl
+ if (name == null || url == null) {
+ null
+ } else {
+ ServerPolicy(name = name, url = url)
+ }
+ }
+ return ServerAndPolicies(serviceUrl, policyUrls)
}
diff --git a/vector/src/main/java/im/vector/app/features/discovery/IdentityServerWithTerms.kt b/vector/src/main/java/im/vector/app/features/discovery/ServerAndPolicies.kt
similarity index 86%
rename from vector/src/main/java/im/vector/app/features/discovery/IdentityServerWithTerms.kt
rename to vector/src/main/java/im/vector/app/features/discovery/ServerAndPolicies.kt
index 36bae0d0c5..17f1b0cff9 100644
--- a/vector/src/main/java/im/vector/app/features/discovery/IdentityServerWithTerms.kt
+++ b/vector/src/main/java/im/vector/app/features/discovery/ServerAndPolicies.kt
@@ -16,12 +16,12 @@
package im.vector.app.features.discovery
-data class IdentityServerWithTerms(
+data class ServerAndPolicies(
val serverUrl: String,
- val policies: List
+ val policies: List
)
-data class IdentityServerPolicy(
+data class ServerPolicy(
val name: String,
val url: String
)
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/BaseEventItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/BaseEventItem.kt
index 6aeb1519a9..5dfbf5d8f6 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/BaseEventItem.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/BaseEventItem.kt
@@ -43,22 +43,12 @@ abstract class BaseEventItem : VectorEpoxyModel
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
lateinit var dimensionConverter: DimensionConverter
- protected var ignoreSendStatusVisibility = false
-
@CallSuper
override fun bind(holder: H) {
super.bind(holder)
holder.leftGuideline.updateLayoutParams {
this.marginStart = leftGuideline
}
- // Ignore visibility of the send status icon?
- holder.contentContainer.updateLayoutParams {
- if (ignoreSendStatusVisibility) {
- addRule(RelativeLayout.ALIGN_PARENT_END)
- } else {
- removeRule(RelativeLayout.ALIGN_PARENT_END)
- }
- }
holder.checkableBackground.isChecked = highlighted
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt
index fb7d0cabd5..f006c2aa35 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt
@@ -33,10 +33,6 @@ import im.vector.app.features.home.room.detail.timeline.helper.VoiceMessagePlayb
@EpoxyModelClass(layout = R.layout.item_timeline_event_base)
abstract class MessageVoiceItem : AbsMessageItem() {
- init {
- ignoreSendStatusVisibility = true
- }
-
@EpoxyAttribute
var mxcUrl: String = ""
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt
index 3e08ce5589..631f00819c 100755
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/url/PreviewUrlView.kt
@@ -19,13 +19,14 @@ package im.vector.app.features.home.room.detail.timeline.url
import android.content.Context
import android.util.AttributeSet
import android.view.View
-import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
+import com.google.android.material.card.MaterialCardView
import im.vector.app.R
import im.vector.app.core.extensions.setTextOrHide
import im.vector.app.databinding.ViewUrlPreviewBinding
import im.vector.app.features.home.room.detail.timeline.TimelineEventController
import im.vector.app.features.media.ImageContentRenderer
+import im.vector.app.features.themes.ThemeUtils
import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.session.media.PreviewUrlData
@@ -36,7 +37,7 @@ class PreviewUrlView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
-) : ConstraintLayout(context, attrs, defStyleAttr), View.OnClickListener {
+) : MaterialCardView(context, attrs, defStyleAttr), View.OnClickListener {
private lateinit var views: ViewUrlPreviewBinding
@@ -44,6 +45,9 @@ class PreviewUrlView @JvmOverloads constructor(
init {
setupView()
+ radius = resources.getDimensionPixelSize(R.dimen.preview_url_view_corner_radius).toFloat()
+ cardElevation = 0f
+ setCardBackgroundColor(ThemeUtils.getColor(context, R.attr.vctr_system))
}
private var state: PreviewUrlUiState = PreviewUrlUiState.Unknown
@@ -121,9 +125,15 @@ class PreviewUrlView @JvmOverloads constructor(
private fun renderData(previewUrlData: PreviewUrlData, imageContentRenderer: ImageContentRenderer) {
isVisible = true
+
views.urlPreviewTitle.setTextOrHide(previewUrlData.title)
views.urlPreviewImage.isVisible = previewUrlData.mxcUrl?.let { imageContentRenderer.render(it, views.urlPreviewImage) }.orFalse()
views.urlPreviewDescription.setTextOrHide(previewUrlData.description)
+ views.urlPreviewDescription.maxLines = when {
+ previewUrlData.mxcUrl != null -> 2
+ previewUrlData.title != null -> 3
+ else -> 5
+ }
views.urlPreviewSite.setTextOrHide(previewUrlData.siteName.takeIf { it != previewUrlData.title })
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt
index 6543cc8795..f67abfbc88 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomListFragment.kt
@@ -44,7 +44,6 @@ import im.vector.app.core.resources.UserPreferencesProvider
import im.vector.app.databinding.FragmentRoomListBinding
import im.vector.app.features.home.RoomListDisplayMode
import im.vector.app.features.home.room.filtered.FilteredRoomFooterItem
-import im.vector.app.features.home.room.list.actions.RoomListActionsArgs
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomSheet
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedAction
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel
@@ -476,7 +475,7 @@ class RoomListFragment @Inject constructor(
footerController.setData(it)
}
RoomListQuickActionsBottomSheet
- .newInstance(room.roomId, RoomListActionsArgs.Mode.FULL)
+ .newInstance(room.roomId)
.show(childFragmentManager, "ROOM_LIST_QUICK_ACTIONS")
return true
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt
index 014ce14c95..5d8cda94ae 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsBottomSheet.kt
@@ -43,15 +43,8 @@ import javax.inject.Inject
@Parcelize
data class RoomListActionsArgs(
- val roomId: String,
- val mode: Mode
-) : Parcelable {
-
- enum class Mode {
- FULL,
- NOTIFICATIONS
- }
-}
+ val roomId: String
+) : Parcelable
/**
* Bottom sheet fragment that shows room information with list of contextual actions
@@ -124,9 +117,9 @@ class RoomListQuickActionsBottomSheet :
}
companion object {
- fun newInstance(roomId: String, mode: RoomListActionsArgs.Mode): RoomListQuickActionsBottomSheet {
+ fun newInstance(roomId: String): RoomListQuickActionsBottomSheet {
return RoomListQuickActionsBottomSheet().apply {
- setArguments(RoomListActionsArgs(roomId, mode))
+ setArguments(RoomListActionsArgs(roomId))
}
}
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt
index a2d10cf818..b343013408 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/list/actions/RoomListQuickActionsEpoxyController.kt
@@ -24,7 +24,6 @@ import im.vector.app.core.epoxy.bottomsheet.bottomSheetRoomPreviewItem
import im.vector.app.core.epoxy.profiles.notifications.radioButtonItem
import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.resources.StringProvider
-import im.vector.app.features.VectorFeatures
import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.roomprofile.notifications.notificationOptions
import im.vector.app.features.roomprofile.notifications.notificationStateMapped
@@ -39,7 +38,6 @@ class RoomListQuickActionsEpoxyController @Inject constructor(
private val avatarRenderer: AvatarRenderer,
private val colorProvider: ColorProvider,
private val stringProvider: StringProvider,
- private val features: VectorFeatures
) : TypedEpoxyController() {
var listener: Listener? = null
@@ -48,54 +46,38 @@ class RoomListQuickActionsEpoxyController @Inject constructor(
val notificationViewState = state.notificationSettingsViewState
val roomSummary = notificationViewState.roomSummary() ?: return
val host = this
- val isV2 = features.notificationSettingsVersion() == VectorFeatures.NotificationSettingsVersion.V2
- // V2 always shows full details as we no longer display the sheet from RoomProfile > Notifications
- val showFull = state.roomListActionsArgs.mode == RoomListActionsArgs.Mode.FULL || isV2
-
- if (showFull) {
- // Preview, favorite, settings
- bottomSheetRoomPreviewItem {
- id("room_preview")
- avatarRenderer(host.avatarRenderer)
- matrixItem(roomSummary.toMatrixItem())
- stringProvider(host.stringProvider)
- colorProvider(host.colorProvider)
- izLowPriority(roomSummary.isLowPriority)
- izFavorite(roomSummary.isFavorite)
- settingsClickListener { host.listener?.didSelectMenuAction(RoomListQuickActionsSharedAction.Settings(roomSummary.roomId)) }
- favoriteClickListener { host.listener?.didSelectMenuAction(RoomListQuickActionsSharedAction.Favorite(roomSummary.roomId)) }
- lowPriorityClickListener { host.listener?.didSelectMenuAction(RoomListQuickActionsSharedAction.LowPriority(roomSummary.roomId)) }
- }
-
- // Notifications
- bottomSheetDividerItem {
- id("notifications_separator")
- }
+ // Preview, favorite, settings
+ bottomSheetRoomPreviewItem {
+ id("room_preview")
+ avatarRenderer(host.avatarRenderer)
+ matrixItem(roomSummary.toMatrixItem())
+ stringProvider(host.stringProvider)
+ colorProvider(host.colorProvider)
+ izLowPriority(roomSummary.isLowPriority)
+ izFavorite(roomSummary.isFavorite)
+ settingsClickListener { host.listener?.didSelectMenuAction(RoomListQuickActionsSharedAction.Settings(roomSummary.roomId)) }
+ favoriteClickListener { host.listener?.didSelectMenuAction(RoomListQuickActionsSharedAction.Favorite(roomSummary.roomId)) }
+ lowPriorityClickListener { host.listener?.didSelectMenuAction(RoomListQuickActionsSharedAction.LowPriority(roomSummary.roomId)) }
}
- if (isV2) {
- notificationViewState.notificationOptions.forEach { notificationState ->
- val title = titleForNotificationState(notificationState)
- radioButtonItem {
- id(notificationState.name)
- titleRes(title)
- selected(notificationViewState.notificationStateMapped() == notificationState)
- listener {
- host.listener?.didSelectRoomNotificationState(notificationState)
- }
+ // Notifications
+ bottomSheetDividerItem {
+ id("notifications_separator")
+ }
+
+ notificationViewState.notificationOptions.forEach { notificationState ->
+ val title = titleForNotificationState(notificationState)
+ radioButtonItem {
+ id(notificationState.name)
+ titleRes(title)
+ selected(notificationViewState.notificationStateMapped() == notificationState)
+ listener {
+ host.listener?.didSelectRoomNotificationState(notificationState)
}
}
- } else {
- val selectedRoomState = notificationViewState.notificationState()
- RoomListQuickActionsSharedAction.NotificationsAllNoisy(roomSummary.roomId).toBottomSheetItem(0, selectedRoomState)
- RoomListQuickActionsSharedAction.NotificationsAll(roomSummary.roomId).toBottomSheetItem(1, selectedRoomState)
- RoomListQuickActionsSharedAction.NotificationsMentionsOnly(roomSummary.roomId).toBottomSheetItem(2, selectedRoomState)
- RoomListQuickActionsSharedAction.NotificationsMute(roomSummary.roomId).toBottomSheetItem(3, selectedRoomState)
}
- if (showFull) {
- RoomListQuickActionsSharedAction.Leave(roomSummary.roomId, showIcon = !isV2).toBottomSheetItem(5)
- }
+ RoomListQuickActionsSharedAction.Leave(roomSummary.roomId, showIcon = !true).toBottomSheetItem()
}
@StringRes
@@ -106,18 +88,11 @@ class RoomListQuickActionsEpoxyController @Inject constructor(
else -> null
}
- private fun RoomListQuickActionsSharedAction.toBottomSheetItem(index: Int, roomNotificationState: RoomNotificationState? = null) {
+ private fun RoomListQuickActionsSharedAction.Leave.toBottomSheetItem() {
val host = this@RoomListQuickActionsEpoxyController
- val selected = when (this) {
- is RoomListQuickActionsSharedAction.NotificationsAllNoisy -> roomNotificationState == RoomNotificationState.ALL_MESSAGES_NOISY
- is RoomListQuickActionsSharedAction.NotificationsAll -> roomNotificationState == RoomNotificationState.ALL_MESSAGES
- is RoomListQuickActionsSharedAction.NotificationsMentionsOnly -> roomNotificationState == RoomNotificationState.MENTIONS_ONLY
- is RoomListQuickActionsSharedAction.NotificationsMute -> roomNotificationState == RoomNotificationState.MUTE
- else -> false
- }
return bottomSheetActionItem {
- id("action_$index")
- selected(selected)
+ id("action_leave")
+ selected(false)
if (iconResId != null) {
iconRes(iconResId)
} else {
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt
index 2091fe04a1..5a8519ecb4 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt
@@ -44,13 +44,10 @@ import im.vector.app.core.utils.copyToClipboard
import im.vector.app.core.utils.startSharePlainTextIntent
import im.vector.app.databinding.FragmentMatrixProfileBinding
import im.vector.app.databinding.ViewStubRoomProfileHeaderBinding
-import im.vector.app.features.VectorFeatures
import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.RoomDetailPendingAction
import im.vector.app.features.home.room.detail.RoomDetailPendingActionStore
import im.vector.app.features.home.room.detail.upgrade.MigrateRoomBottomSheet
-import im.vector.app.features.home.room.list.actions.RoomListActionsArgs
-import im.vector.app.features.home.room.list.actions.RoomListQuickActionsBottomSheet
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedAction
import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedActionViewModel
import kotlinx.coroutines.flow.launchIn
@@ -69,8 +66,7 @@ data class RoomProfileArgs(
class RoomProfileFragment @Inject constructor(
private val roomProfileController: RoomProfileController,
private val avatarRenderer: AvatarRenderer,
- private val roomDetailPendingActionStore: RoomDetailPendingActionStore,
- private val features: VectorFeatures
+ private val roomDetailPendingActionStore: RoomDetailPendingActionStore
) :
VectorBaseFragment(),
RoomProfileController.Callback {
@@ -259,16 +255,7 @@ class RoomProfileFragment @Inject constructor(
}
override fun onNotificationsClicked() {
- when (features.notificationSettingsVersion()) {
- VectorFeatures.NotificationSettingsVersion.V1 -> {
- RoomListQuickActionsBottomSheet
- .newInstance(roomProfileArgs.roomId, RoomListActionsArgs.Mode.NOTIFICATIONS)
- .show(childFragmentManager, "ROOM_PROFILE_NOTIFICATIONS")
- }
- VectorFeatures.NotificationSettingsVersion.V2 -> {
- roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomNotificationSettings)
- }
- }
+ roomProfileSharedActionViewModel.post(RoomProfileSharedAction.OpenRoomNotificationSettings)
}
override fun onUploadsClicked() {
diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt
index 6eb8d7c195..c9464550ac 100755
--- a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt
@@ -35,6 +35,7 @@ import javax.inject.Inject
class VectorPreferences @Inject constructor(private val context: Context) {
companion object {
+ const val SETTINGS_HELP_PREFERENCE_KEY = "SETTINGS_HELP_PREFERENCE_KEY"
const val SETTINGS_CHANGE_PASSWORD_PREFERENCE_KEY = "SETTINGS_CHANGE_PASSWORD_PREFERENCE_KEY"
const val SETTINGS_VERSION_PREFERENCE_KEY = "SETTINGS_VERSION_PREFERENCE_KEY"
const val SETTINGS_SDK_VERSION_PREFERENCE_KEY = "SETTINGS_SDK_VERSION_PREFERENCE_KEY"
@@ -42,17 +43,8 @@ class VectorPreferences @Inject constructor(private val context: Context) {
const val SETTINGS_LOGGED_IN_PREFERENCE_KEY = "SETTINGS_LOGGED_IN_PREFERENCE_KEY"
const val SETTINGS_HOME_SERVER_PREFERENCE_KEY = "SETTINGS_HOME_SERVER_PREFERENCE_KEY"
const val SETTINGS_IDENTITY_SERVER_PREFERENCE_KEY = "SETTINGS_IDENTITY_SERVER_PREFERENCE_KEY"
- const val SETTINGS_APP_TERM_CONDITIONS_PREFERENCE_KEY = "SETTINGS_APP_TERM_CONDITIONS_PREFERENCE_KEY"
- const val SETTINGS_PRIVACY_POLICY_PREFERENCE_KEY = "SETTINGS_PRIVACY_POLICY_PREFERENCE_KEY"
const val SETTINGS_DISCOVERY_PREFERENCE_KEY = "SETTINGS_DISCOVERY_PREFERENCE_KEY"
- const val SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY = "SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY"
- const val SETTINGS_NOTIFICATION_DEFAULT_PREFERENCE_KEY = "SETTINGS_NOTIFICATION_DEFAULT_PREFERENCE_KEY"
- const val SETTINGS_NOTIFICATION_KEYWORD_AND_MENTIONS_PREFERENCE_KEY = "SETTINGS_NOTIFICATION_KEYWORD_AND_MENTIONS_PREFERENCE_KEY"
- const val SETTINGS_NOTIFICATION_OTHER_PREFERENCE_KEY = "SETTINGS_NOTIFICATION_OTHER_PREFERENCE_KEY"
- const val SETTINGS_THIRD_PARTY_NOTICES_PREFERENCE_KEY = "SETTINGS_THIRD_PARTY_NOTICES_PREFERENCE_KEY"
- const val SETTINGS_OTHER_THIRD_PARTY_NOTICES_PREFERENCE_KEY = "SETTINGS_OTHER_THIRD_PARTY_NOTICES_PREFERENCE_KEY"
- const val SETTINGS_COPYRIGHT_PREFERENCE_KEY = "SETTINGS_COPYRIGHT_PREFERENCE_KEY"
const val SETTINGS_CLEAR_CACHE_PREFERENCE_KEY = "SETTINGS_CLEAR_CACHE_PREFERENCE_KEY"
const val SETTINGS_CLEAR_MEDIA_CACHE_PREFERENCE_KEY = "SETTINGS_CLEAR_MEDIA_CACHE_PREFERENCE_KEY"
const val SETTINGS_USER_SETTINGS_PREFERENCE_KEY = "SETTINGS_USER_SETTINGS_PREFERENCE_KEY"
diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsHelpAboutFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsHelpAboutFragment.kt
index 03b7c16274..31d9cf0426 100644
--- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsHelpAboutFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsHelpAboutFragment.kt
@@ -22,11 +22,9 @@ import im.vector.app.R
import im.vector.app.core.preference.VectorPreference
import im.vector.app.core.utils.FirstThrottler
import im.vector.app.core.utils.copyToClipboard
-import im.vector.app.core.utils.displayInWebView
import im.vector.app.core.utils.openAppSettingsPage
import im.vector.app.core.utils.openUrlInChromeCustomTab
import im.vector.app.features.version.VersionProvider
-import im.vector.app.openOssLicensesMenuActivity
import org.matrix.android.sdk.api.Matrix
import javax.inject.Inject
@@ -40,6 +38,15 @@ class VectorSettingsHelpAboutFragment @Inject constructor(
private val firstThrottler = FirstThrottler(1000)
override fun bindPref() {
+ // Help
+ findPreference(VectorPreferences.SETTINGS_HELP_PREFERENCE_KEY)!!
+ .onPreferenceClickListener = Preference.OnPreferenceClickListener {
+ if (firstThrottler.canHandle() is FirstThrottler.CanHandlerResult.Yes) {
+ openUrlInChromeCustomTab(requireContext(), null, VectorSettingsUrls.HELP)
+ }
+ false
+ }
+
// preference to start the App info screen, to facilitate App permissions access
findPreference(APP_INFO_LINK_PREFERENCE_KEY)!!
.onPreferenceClickListener = Preference.OnPreferenceClickListener {
@@ -76,44 +83,6 @@ class VectorSettingsHelpAboutFragment @Inject constructor(
// olm version
findPreference(VectorPreferences.SETTINGS_OLM_VERSION_PREFERENCE_KEY)!!
.summary = session.cryptoService().getCryptoVersion(requireContext(), false)
-
- // copyright
- findPreference(VectorPreferences.SETTINGS_COPYRIGHT_PREFERENCE_KEY)!!
- .onPreferenceClickListener = Preference.OnPreferenceClickListener {
- openUrlInChromeCustomTab(requireContext(), null, VectorSettingsUrls.COPYRIGHT)
- false
- }
-
- // terms & conditions
- findPreference(VectorPreferences.SETTINGS_APP_TERM_CONDITIONS_PREFERENCE_KEY)!!
- .onPreferenceClickListener = Preference.OnPreferenceClickListener {
- openUrlInChromeCustomTab(requireContext(), null, VectorSettingsUrls.TAC)
- false
- }
-
- // privacy policy
- findPreference(VectorPreferences.SETTINGS_PRIVACY_POLICY_PREFERENCE_KEY)!!
- .onPreferenceClickListener = Preference.OnPreferenceClickListener {
- openUrlInChromeCustomTab(requireContext(), null, VectorSettingsUrls.PRIVACY_POLICY)
- false
- }
-
- // third party notice
- findPreference(VectorPreferences.SETTINGS_THIRD_PARTY_NOTICES_PREFERENCE_KEY)!!
- .onPreferenceClickListener = Preference.OnPreferenceClickListener {
- if (firstThrottler.canHandle() is FirstThrottler.CanHandlerResult.Yes) {
- activity?.displayInWebView(VectorSettingsUrls.THIRD_PARTY_LICENSES)
- }
- false
- }
-
- // Note: preference is not visible on F-Droid build
- findPreference(VectorPreferences.SETTINGS_OTHER_THIRD_PARTY_NOTICES_PREFERENCE_KEY)!!
- .onPreferenceClickListener = Preference.OnPreferenceClickListener {
- // See https://developers.google.com/android/guides/opensource
- openOssLicensesMenuActivity(requireActivity())
- false
- }
}
companion object {
diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsUrls.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsUrls.kt
index c5088aac6d..09249c4957 100644
--- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsUrls.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsUrls.kt
@@ -17,7 +17,7 @@
package im.vector.app.features.settings
object VectorSettingsUrls {
-
+ const val HELP = "https://element.io/help"
const val COPYRIGHT = "https://element.io/copyright"
const val TAC = "https://element.io/terms-of-service"
const val PRIVACY_POLICY = "https://element.io/privacy"
diff --git a/vector/src/main/java/im/vector/app/features/settings/legals/ElementLegals.kt b/vector/src/main/java/im/vector/app/features/settings/legals/ElementLegals.kt
new file mode 100644
index 0000000000..de59f36604
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/legals/ElementLegals.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.legals
+
+import im.vector.app.R
+import im.vector.app.core.resources.StringProvider
+import im.vector.app.features.discovery.ServerPolicy
+import im.vector.app.features.settings.VectorSettingsUrls
+import javax.inject.Inject
+
+class ElementLegals @Inject constructor(
+ private val stringProvider: StringProvider
+) {
+ /**
+ * Use ServerPolicy model
+ */
+ fun getData(): List {
+ return listOf(
+ ServerPolicy(stringProvider.getString(R.string.settings_copyright), VectorSettingsUrls.COPYRIGHT),
+ ServerPolicy(stringProvider.getString(R.string.settings_app_term_conditions), VectorSettingsUrls.TAC),
+ ServerPolicy(stringProvider.getString(R.string.settings_privacy_policy), VectorSettingsUrls.PRIVACY_POLICY)
+ )
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/legals/LegalsAction.kt b/vector/src/main/java/im/vector/app/features/settings/legals/LegalsAction.kt
new file mode 100644
index 0000000000..424c6bb78b
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/legals/LegalsAction.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.legals
+
+import im.vector.app.core.platform.VectorViewModelAction
+
+sealed interface LegalsAction : VectorViewModelAction {
+ object Refresh : LegalsAction
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/legals/LegalsController.kt b/vector/src/main/java/im/vector/app/features/settings/legals/LegalsController.kt
new file mode 100644
index 0000000000..98e77ae7d5
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/legals/LegalsController.kt
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package im.vector.app.features.settings.legals
+
+import android.content.res.Resources
+import com.airbnb.epoxy.TypedEpoxyController
+import com.airbnb.mvrx.Async
+import com.airbnb.mvrx.Fail
+import com.airbnb.mvrx.Loading
+import com.airbnb.mvrx.Success
+import com.airbnb.mvrx.Uninitialized
+import im.vector.app.R
+import im.vector.app.core.epoxy.errorWithRetryItem
+import im.vector.app.core.epoxy.loadingItem
+import im.vector.app.core.error.ErrorFormatter
+import im.vector.app.core.resources.StringProvider
+import im.vector.app.features.discovery.ServerAndPolicies
+import im.vector.app.features.discovery.ServerPolicy
+import im.vector.app.features.discovery.discoveryPolicyItem
+import im.vector.app.features.discovery.settingsInfoItem
+import im.vector.app.features.discovery.settingsSectionTitleItem
+import javax.inject.Inject
+
+class LegalsController @Inject constructor(
+ private val stringProvider: StringProvider,
+ private val resources: Resources,
+ private val elementLegals: ElementLegals,
+ private val errorFormatter: ErrorFormatter
+) : TypedEpoxyController() {
+
+ var listener: Listener? = null
+
+ override fun buildModels(data: LegalsState) {
+ buildAppSection()
+ buildHomeserverSection(data)
+ buildIdentityServerSection(data)
+ buildThirdPartyNotices()
+ }
+
+ private fun buildAppSection() {
+ settingsSectionTitleItem {
+ id("appTitle")
+ titleResId(R.string.legals_application_title)
+ }
+
+ buildPolicies("el", elementLegals.getData())
+ }
+
+ private fun buildHomeserverSection(data: LegalsState) {
+ settingsSectionTitleItem {
+ id("hsServerTitle")
+ titleResId(R.string.legals_home_server_title)
+ }
+
+ buildPolicyAsync("hs", data.homeServer)
+ }
+
+ private fun buildIdentityServerSection(data: LegalsState) {
+ if (data.hasIdentityServer) {
+ settingsSectionTitleItem {
+ id("idServerTitle")
+ titleResId(R.string.legals_identity_server_title)
+ }
+
+ buildPolicyAsync("is", data.identityServer)
+ }
+ }
+
+ private fun buildPolicyAsync(tag: String, serverAndPolicies: Async) {
+ val host = this
+
+ when (serverAndPolicies) {
+ Uninitialized,
+ is Loading -> loadingItem {
+ id("loading_$tag")
+ }
+ is Success -> {
+ val policies = serverAndPolicies()?.policies
+ if (policies.isNullOrEmpty()) {
+ settingsInfoItem {
+ id("emptyPolicy")
+ helperText(host.stringProvider.getString(R.string.legals_no_policy_provided))
+ }
+ } else {
+ buildPolicies(tag, policies)
+ }
+ }
+ is Fail -> {
+ errorWithRetryItem {
+ id("errorRetry_$tag")
+ text(host.errorFormatter.toHumanReadable(serverAndPolicies.error))
+ listener { host.listener?.onTapRetry() }
+ }
+ }
+ }
+ }
+
+ private fun buildPolicies(tag: String, policies: List) {
+ val host = this
+
+ policies.forEach { policy ->
+ discoveryPolicyItem {
+ id(tag + policy.url)
+ name(policy.name)
+ url(policy.url.takeIf { it.startsWith("http") })
+ clickListener { host.listener?.openPolicy(policy) }
+ }
+ }
+ }
+
+ private fun buildThirdPartyNotices() {
+ val host = this
+ settingsSectionTitleItem {
+ id("thirdTitle")
+ titleResId(R.string.legals_third_party_notices)
+ }
+
+ discoveryPolicyItem {
+ id("eltpn1")
+ name(host.stringProvider.getString(R.string.settings_third_party_notices))
+ clickListener { host.listener?.openThirdPartyNotice() }
+ }
+ // Only on Gplay
+ if (resources.getBoolean(R.bool.isGplay)) {
+ discoveryPolicyItem {
+ id("eltpn2")
+ name(host.stringProvider.getString(R.string.settings_other_third_party_notices))
+ clickListener { host.listener?.openThirdPartyNoticeGplay() }
+ }
+ }
+ }
+
+ interface Listener {
+ fun onTapRetry()
+ fun openPolicy(policy: ServerPolicy)
+ fun openThirdPartyNotice()
+ fun openThirdPartyNoticeGplay()
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/legals/LegalsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/legals/LegalsFragment.kt
new file mode 100644
index 0000000000..f9b50bdead
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/legals/LegalsFragment.kt
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package im.vector.app.features.settings.legals
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.appcompat.app.AppCompatActivity
+import com.airbnb.mvrx.fragmentViewModel
+import com.airbnb.mvrx.withState
+import im.vector.app.R
+import im.vector.app.core.extensions.cleanup
+import im.vector.app.core.extensions.configureWith
+import im.vector.app.core.platform.VectorBaseFragment
+import im.vector.app.core.utils.FirstThrottler
+import im.vector.app.core.utils.displayInWebView
+import im.vector.app.core.utils.openUrlInChromeCustomTab
+import im.vector.app.databinding.FragmentGenericRecyclerBinding
+import im.vector.app.features.discovery.ServerPolicy
+import im.vector.app.features.settings.VectorSettingsUrls
+import im.vector.app.openOssLicensesMenuActivity
+import javax.inject.Inject
+
+class LegalsFragment @Inject constructor(
+ private val controller: LegalsController
+) : VectorBaseFragment(),
+ LegalsController.Listener {
+
+ override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentGenericRecyclerBinding {
+ return FragmentGenericRecyclerBinding.inflate(inflater, container, false)
+ }
+
+ private val viewModel by fragmentViewModel(LegalsViewModel::class)
+ private val firstThrottler = FirstThrottler(1000)
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ controller.listener = this
+ views.genericRecyclerView.configureWith(controller)
+ }
+
+ override fun onDestroyView() {
+ views.genericRecyclerView.cleanup()
+ controller.listener = null
+ super.onDestroyView()
+ }
+
+ override fun invalidate() = withState(viewModel) { state ->
+ controller.setData(state)
+ }
+
+ override fun onResume() {
+ super.onResume()
+ (activity as? AppCompatActivity)?.supportActionBar?.setTitle(R.string.preference_root_legals)
+ viewModel.handle(LegalsAction.Refresh)
+ }
+
+ override fun onTapRetry() {
+ viewModel.handle(LegalsAction.Refresh)
+ }
+
+ override fun openPolicy(policy: ServerPolicy) {
+ openUrl(policy.url)
+ }
+
+ override fun openThirdPartyNotice() {
+ openUrl(VectorSettingsUrls.THIRD_PARTY_LICENSES)
+ }
+
+ private fun openUrl(url: String) {
+ if (firstThrottler.canHandle() is FirstThrottler.CanHandlerResult.Yes) {
+ if (url.startsWith("file://")) {
+ activity?.displayInWebView(url)
+ } else {
+ openUrlInChromeCustomTab(requireContext(), null, url)
+ }
+ }
+ }
+
+ override fun openThirdPartyNoticeGplay() {
+ if (firstThrottler.canHandle() is FirstThrottler.CanHandlerResult.Yes) {
+ // See https://developers.google.com/android/guides/opensource
+ openOssLicensesMenuActivity(requireActivity())
+ }
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/legals/LegalsState.kt b/vector/src/main/java/im/vector/app/features/settings/legals/LegalsState.kt
new file mode 100644
index 0000000000..ad01f85338
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/legals/LegalsState.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.settings.legals
+
+import com.airbnb.mvrx.Async
+import com.airbnb.mvrx.MavericksState
+import com.airbnb.mvrx.Uninitialized
+import im.vector.app.features.discovery.ServerAndPolicies
+
+data class LegalsState(
+ val homeServer: Async = Uninitialized,
+ val hasIdentityServer: Boolean = false,
+ val identityServer: Async = Uninitialized
+) : MavericksState
diff --git a/vector/src/main/java/im/vector/app/features/settings/legals/LegalsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/legals/LegalsViewModel.kt
new file mode 100644
index 0000000000..9d58535490
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/settings/legals/LegalsViewModel.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2021 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package im.vector.app.features.settings.legals
+
+import com.airbnb.mvrx.Fail
+import com.airbnb.mvrx.Loading
+import com.airbnb.mvrx.MavericksViewModelFactory
+import com.airbnb.mvrx.Success
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import im.vector.app.R
+import im.vector.app.core.di.MavericksAssistedViewModelFactory
+import im.vector.app.core.di.hiltMavericksViewModelFactory
+import im.vector.app.core.extensions.exhaustive
+import im.vector.app.core.platform.EmptyViewEvents
+import im.vector.app.core.platform.VectorViewModel
+import im.vector.app.core.resources.StringProvider
+import im.vector.app.features.discovery.fetchHomeserverWithTerms
+import im.vector.app.features.discovery.fetchIdentityServerWithTerms
+import kotlinx.coroutines.launch
+import org.matrix.android.sdk.api.session.Session
+
+class LegalsViewModel @AssistedInject constructor(
+ @Assisted initialState: LegalsState,
+ private val session: Session,
+ private val stringProvider: StringProvider
+) : VectorViewModel(initialState) {
+
+ @AssistedFactory
+ interface Factory : MavericksAssistedViewModelFactory {
+ override fun create(initialState: LegalsState): LegalsViewModel
+ }
+
+ companion object : MavericksViewModelFactory by hiltMavericksViewModelFactory()
+
+ override fun handle(action: LegalsAction) {
+ when (action) {
+ LegalsAction.Refresh -> loadData()
+ }.exhaustive
+ }
+
+ private fun loadData() = withState { state ->
+ loadHomeserver(state)
+ val url = session.identityService().getCurrentIdentityServerUrl()
+ if (url.isNullOrEmpty()) {
+ setState { copy(hasIdentityServer = false) }
+ } else {
+ setState { copy(hasIdentityServer = true) }
+ loadIdentityServer(state)
+ }
+ }
+
+ private fun loadHomeserver(state: LegalsState) {
+ if (state.homeServer !is Success) {
+ setState { copy(homeServer = Loading()) }
+ viewModelScope.launch {
+ runCatching { session.fetchHomeserverWithTerms(stringProvider.getString(R.string.resources_language)) }
+ .fold(
+ onSuccess = { setState { copy(homeServer = Success(it)) } },
+ onFailure = { setState { copy(homeServer = Fail(it)) } }
+ )
+ }
+ }
+ }
+
+ private fun loadIdentityServer(state: LegalsState) {
+ if (state.identityServer !is Success) {
+ setState { copy(identityServer = Loading()) }
+ viewModelScope.launch {
+ runCatching { session.fetchIdentityServerWithTerms(stringProvider.getString(R.string.resources_language)) }
+ .fold(
+ onSuccess = { setState { copy(identityServer = Success(it)) } },
+ onFailure = { setState { copy(identityServer = Fail(it)) } }
+ )
+ }
+ }
+ }
+}
diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt
index 3004d30913..4199bd1753 100644
--- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt
@@ -40,7 +40,6 @@ import im.vector.app.core.pushers.PushersManager
import im.vector.app.core.services.GuardServiceStarter
import im.vector.app.core.utils.isIgnoringBatteryOptimizations
import im.vector.app.core.utils.requestDisablingBatteryOptimization
-import im.vector.app.features.VectorFeatures
import im.vector.app.features.notifications.NotificationUtils
import im.vector.app.features.settings.BackgroundSyncMode
import im.vector.app.features.settings.BackgroundSyncModeChooserDialog
@@ -64,8 +63,7 @@ class VectorSettingsNotificationPreferenceFragment @Inject constructor(
private val pushManager: PushersManager,
private val activeSessionHolder: ActiveSessionHolder,
private val vectorPreferences: VectorPreferences,
- private val guardServiceStarter: GuardServiceStarter,
- private val features: VectorFeatures
+ private val guardServiceStarter: GuardServiceStarter
) : VectorSettingsBaseFragment(),
BackgroundSyncModeChooserDialog.InteractionListener {
@@ -147,7 +145,6 @@ class VectorSettingsNotificationPreferenceFragment @Inject constructor(
refreshBackgroundSyncPrefs()
handleSystemPreference()
- handleVersionedSettings()
}
private fun bindEmailNotifications() {
@@ -312,15 +309,6 @@ class VectorSettingsNotificationPreferenceFragment @Inject constructor(
}
}
- private fun handleVersionedSettings() {
- val isNotificationSettingsV2Enabled = features.notificationSettingsVersion() == VectorFeatures.NotificationSettingsVersion.V2
-
- findPreference(VectorPreferences.SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY)?.isVisible = !isNotificationSettingsV2Enabled
- findPreference(VectorPreferences.SETTINGS_NOTIFICATION_DEFAULT_PREFERENCE_KEY)?.isVisible = isNotificationSettingsV2Enabled
- findPreference(VectorPreferences.SETTINGS_NOTIFICATION_KEYWORD_AND_MENTIONS_PREFERENCE_KEY)?.isVisible = isNotificationSettingsV2Enabled
- findPreference(VectorPreferences.SETTINGS_NOTIFICATION_OTHER_PREFERENCE_KEY)?.isVisible = isNotificationSettingsV2Enabled
- }
-
override fun onResume() {
super.onResume()
activeSessionHolder.getSafeActiveSession()?.refreshPushers()
diff --git a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewEvents.kt b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewEvents.kt
index ffda0dd505..ef29e8015a 100644
--- a/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewEvents.kt
+++ b/vector/src/main/java/im/vector/app/features/userdirectory/UserListViewEvents.kt
@@ -17,13 +17,13 @@
package im.vector.app.features.userdirectory
import im.vector.app.core.platform.VectorViewEvents
-import im.vector.app.features.discovery.IdentityServerWithTerms
+import im.vector.app.features.discovery.ServerAndPolicies
/**
* Transient events for invite users to room screen
*/
sealed class UserListViewEvents : VectorViewEvents {
data class Failure(val throwable: Throwable) : UserListViewEvents()
- data class OnPoliciesRetrieved(val identityServerWithTerms: IdentityServerWithTerms?) : UserListViewEvents()
+ data class OnPoliciesRetrieved(val identityServerWithTerms: ServerAndPolicies?) : UserListViewEvents()
data class OpenShareMatrixToLink(val link: String) : UserListViewEvents()
}
diff --git a/vector/src/main/res/drawable/ic_close_with_circular_bg.xml b/vector/src/main/res/drawable/ic_close_with_circular_bg.xml
new file mode 100644
index 0000000000..5e54b638a0
--- /dev/null
+++ b/vector/src/main/res/drawable/ic_close_with_circular_bg.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
diff --git a/vector/src/main/res/drawable/ic_settings_root_legals.xml b/vector/src/main/res/drawable/ic_settings_root_legals.xml
new file mode 100644
index 0000000000..8c5049b36e
--- /dev/null
+++ b/vector/src/main/res/drawable/ic_settings_root_legals.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/vector/src/main/res/layout/item_discovery_policy.xml b/vector/src/main/res/layout/item_discovery_policy.xml
index 453d236bab..2d90c3c0ed 100644
--- a/vector/src/main/res/layout/item_discovery_policy.xml
+++ b/vector/src/main/res/layout/item_discovery_policy.xml
@@ -5,9 +5,21 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
+ android:minHeight="80dp"
android:padding="16dp"
tools:viewBindingIgnore="true">
+
+
+ tools:text="Copyright" />
+ android:textColor="?android:textColorLink"
+ tools:text="https://element.io/copyright" />
@@ -116,27 +117,23 @@
android:id="@+id/messageContentRedactedStub"
style="@style/TimelineContentStubBaseParams"
android:layout_height="wrap_content"
- android:layout_marginEnd="56dp"
android:layout="@layout/item_timeline_event_redacted_stub" />
@@ -153,7 +150,7 @@
android:layout_marginBottom="4dp"
android:contentDescription="@string/event_status_a11y_sending"
android:src="@drawable/ic_sending_message"
- android:visibility="gone"
+ android:visibility="invisible"
tools:tint="?vctr_content_tertiary"
tools:visibility="visible" />
diff --git a/vector/src/main/res/layout/item_timeline_event_text_message_stub.xml b/vector/src/main/res/layout/item_timeline_event_text_message_stub.xml
index 0280efd848..3f9feb93af 100644
--- a/vector/src/main/res/layout/item_timeline_event_text_message_stub.xml
+++ b/vector/src/main/res/layout/item_timeline_event_text_message_stub.xml
@@ -17,7 +17,7 @@
+ tools:parentTag="com.google.android.material.card.MaterialCardView">
-
-
-
+ android:orientation="vertical">
-
+
-
+
-
+
+
+
+
+
\ No newline at end of file
diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml
index ddb731a5e0..97bf7a7d6a 100644
--- a/vector/src/main/res/values/strings.xml
+++ b/vector/src/main/res/values/strings.xml
@@ -1397,6 +1397,12 @@
Allow integrations
Integration manager
+ ${app_name} policy
+ Your homeserver policy
+ Your identity server policy
+ Third party libraries
+ This server does not provide any policy.
+
Integrations are disabled
"Enable 'Allow integrations' in Settings to do this."
@@ -2270,7 +2276,13 @@
Voice & Video
Help & About
+ Legals
+ Help
+ Help and support
+ Get help with using Element
+ Versions
+ System settings
Register token
@@ -3566,7 +3578,6 @@
Manage rooms and spaces
-
Show all rooms in Home
All rooms you’re in will be shown in Home.
diff --git a/vector/src/main/res/xml/vector_settings_help_about.xml b/vector/src/main/res/xml/vector_settings_help_about.xml
index b36fba05c2..0388b545b7 100644
--- a/vector/src/main/res/xml/vector_settings_help_about.xml
+++ b/vector/src/main/res/xml/vector_settings_help_about.xml
@@ -1,47 +1,42 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+
+
+
+
\ No newline at end of file
diff --git a/vector/src/main/res/xml/vector_settings_notifications.xml b/vector/src/main/res/xml/vector_settings_notifications.xml
index 154e7cca0d..66ac93a4f9 100644
--- a/vector/src/main/res/xml/vector_settings_notifications.xml
+++ b/vector/src/main/res/xml/vector_settings_notifications.xml
@@ -20,14 +20,6 @@
-
-
+
+
\ No newline at end of file