mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-15 01:35:07 +08:00
Merge branch 'develop' into feature/bma/posthog
This commit is contained in:
commit
a40e60ba8f
92
.github/workflows/triage-move-labelled.yml
vendored
92
.github/workflows/triage-move-labelled.yml
vendored
@ -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 }}
|
||||
|
64
build.gradle
64
build.gradle
@ -1,12 +1,11 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
|
||||
apply from: 'dependencies.gradle'
|
||||
apply from: 'dependencies_groups.gradle'
|
||||
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
maven {
|
||||
url "https://plugins.gradle.org/m2/"
|
||||
}
|
||||
@ -37,45 +36,50 @@ allprojects {
|
||||
apply plugin: "org.jlleitschuh.gradle.ktlint"
|
||||
|
||||
repositories {
|
||||
// For olm library. This has to be declared first, to ensure that Olm library is not downloaded from another repo
|
||||
// For olm library.
|
||||
maven {
|
||||
url 'https://gitlab.matrix.org/api/v4/projects/27/packages/maven'
|
||||
content {
|
||||
groups.olm.regex.each { includeGroupByRegex it }
|
||||
groups.olm.group.each { includeGroup it }
|
||||
}
|
||||
}
|
||||
maven {
|
||||
url 'https://jitpack.io'
|
||||
content {
|
||||
// Use this repo only for olm library
|
||||
includeGroupByRegex "org\\.matrix\\.gitlab\\.matrix-org"
|
||||
// And also for FilePicker
|
||||
includeGroupByRegex "com\\.github\\.jaiselrahman"
|
||||
// And monarchy
|
||||
includeGroupByRegex "com\\.github\\.Zhuinden"
|
||||
// And ucrop
|
||||
includeGroupByRegex "com\\.github\\.yalantis"
|
||||
// JsonViewer
|
||||
includeGroupByRegex 'com\\.github\\.BillCarsonFr'
|
||||
// PhotoView
|
||||
includeGroupByRegex 'com\\.github\\.chrisbanes'
|
||||
// PFLockScreen-Android
|
||||
includeGroupByRegex 'com\\.github\\.vector-im'
|
||||
// DraggableView
|
||||
includeGroupByRegex 'com\\.github\\.hyuwah'
|
||||
|
||||
// Chat effects
|
||||
includeGroupByRegex 'com\\.github\\.jetradarmobile'
|
||||
includeGroupByRegex 'nl\\.dionsegijn'
|
||||
|
||||
// Voice RecordView
|
||||
includeGroupByRegex 'com\\.github\\.Armen101'
|
||||
groups.jitpack.regex.each { includeGroupByRegex it }
|
||||
groups.jitpack.group.each { includeGroup it }
|
||||
}
|
||||
}
|
||||
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
|
||||
// Jitsi repo
|
||||
maven {
|
||||
url "https://github.com/vector-im/jitsi_libre_maven/raw/main/android-sdk-3.10.0"
|
||||
// Note: to test Jitsi release you can use a local file like this:
|
||||
// url "file:///Users/bmarty/workspaces/jitsi_libre_maven/android-sdk-3.10.0"
|
||||
content {
|
||||
groups.jitsi.regex.each { includeGroupByRegex it }
|
||||
groups.jitsi.group.each { includeGroup it }
|
||||
}
|
||||
}
|
||||
google {
|
||||
content {
|
||||
groups.google.regex.each { includeGroupByRegex it }
|
||||
groups.google.group.each { includeGroup it }
|
||||
}
|
||||
}
|
||||
mavenCentral {
|
||||
content {
|
||||
groups.mavenCentral.regex.each { includeGroupByRegex it }
|
||||
groups.mavenCentral.group.each { includeGroup it }
|
||||
}
|
||||
}
|
||||
//noinspection JcenterRepositoryObsolete
|
||||
jcenter {
|
||||
content {
|
||||
groups.jcenter.regex.each { includeGroupByRegex it }
|
||||
groups.jcenter.group.each { includeGroup it }
|
||||
}
|
||||
}
|
||||
google()
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
|
||||
|
1
changelog.d/4278.feature
Normal file
1
changelog.d/4278.feature
Normal file
@ -0,0 +1 @@
|
||||
Updates URL previews to match latest designs
|
1
changelog.d/4592.bugfix
Normal file
1
changelog.d/4592.bugfix
Normal file
@ -0,0 +1 @@
|
||||
Fix empty Dev Tools screen issue.
|
1
changelog.d/4638.feature
Normal file
1
changelog.d/4638.feature
Normal file
@ -0,0 +1 @@
|
||||
Add a help section in the settings.
|
1
changelog.d/4647.misc
Normal file
1
changelog.d/4647.misc
Normal file
@ -0,0 +1 @@
|
||||
Upgrade OLM to v3.2.7 and get it from our maven repository.
|
1
changelog.d/4650.misc
Normal file
1
changelog.d/4650.misc
Normal file
@ -0,0 +1 @@
|
||||
Cleanup id ref. Use type views instead
|
1
changelog.d/4660.feature
Normal file
1
changelog.d/4660.feature
Normal file
@ -0,0 +1 @@
|
||||
Create a legal screen in the setting to group all the different policies.
|
1
changelog.d/4666.misc
Normal file
1
changelog.d/4666.misc
Normal file
@ -0,0 +1 @@
|
||||
Add automation to move message bubbles issues to message bubbles board.
|
1
changelog.d/4670.misc
Normal file
1
changelog.d/4670.misc
Normal file
@ -0,0 +1 @@
|
||||
Add explicit dependency location, regarding the several maven repository. Also update some libraries (flexbox and alerter), and do some cleanup.
|
1
changelog.d/4671.misc
Normal file
1
changelog.d/4671.misc
Normal file
@ -0,0 +1 @@
|
||||
Fix graphql warning in issue workflow automation
|
@ -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"
|
||||
|
200
dependencies_groups.gradle
Normal file
200
dependencies_groups.gradle
Normal file
@ -0,0 +1,200 @@
|
||||
ext.groups = [
|
||||
jitpack : [
|
||||
regex: [
|
||||
],
|
||||
group: [
|
||||
'com.github.Armen101',
|
||||
'com.github.BillCarsonFr',
|
||||
'com.github.chrisbanes',
|
||||
'com.github.hyuwah',
|
||||
'com.github.jetradarmobile',
|
||||
'com.github.tapadoo',
|
||||
'com.github.vector-im',
|
||||
'com.github.yalantis',
|
||||
'com.github.Zhuinden',
|
||||
]
|
||||
],
|
||||
olm : [
|
||||
regex: [
|
||||
],
|
||||
group: [
|
||||
'org.matrix.android',
|
||||
]
|
||||
],
|
||||
jitsi : [
|
||||
regex: [
|
||||
],
|
||||
group: [
|
||||
'com.facebook.react',
|
||||
'org.jitsi.react',
|
||||
'org.webkit',
|
||||
]
|
||||
],
|
||||
google : [
|
||||
regex: [
|
||||
'androidx\\..*',
|
||||
'com\\.android\\.tools\\..*',
|
||||
'com\\.google\\.android\\..*',
|
||||
],
|
||||
group: [
|
||||
'com.google.firebase',
|
||||
'com.android',
|
||||
'com.android.tools',
|
||||
]
|
||||
],
|
||||
mavenCentral: [
|
||||
regex: [
|
||||
],
|
||||
group: [
|
||||
'com.adevinta.android',
|
||||
'com.airbnb.android',
|
||||
'com.almworks.sqlite4java',
|
||||
'com.arthenica',
|
||||
'com.atlassian.commonmark',
|
||||
'com.atlassian.pom',
|
||||
'com.beust',
|
||||
'com.davemorrissey.labs',
|
||||
'com.dropbox.core',
|
||||
'com.facebook.fresco',
|
||||
'com.facebook.infer.annotation',
|
||||
'com.facebook.soloader',
|
||||
'com.facebook.stetho',
|
||||
'com.fasterxml',
|
||||
'com.fasterxml.jackson',
|
||||
'com.fasterxml.jackson.core',
|
||||
'com.gabrielittner.threetenbp',
|
||||
'com.getkeepsafe.relinker',
|
||||
'com.github.bumptech.glide',
|
||||
'com.github.filippudak',
|
||||
'com.github.filippudak.progresspieview',
|
||||
'com.github.javaparser',
|
||||
'com.github.piasy',
|
||||
'com.github.shyiko.klob',
|
||||
'com.google',
|
||||
'com.google.auto.service',
|
||||
'com.google.auto.value',
|
||||
'com.google.code.findbugs',
|
||||
'com.google.code.gson',
|
||||
'com.google.dagger',
|
||||
'com.google.devtools.ksp',
|
||||
'com.google.errorprone',
|
||||
'com.google.googlejavaformat',
|
||||
'com.google.guava',
|
||||
'com.google.j2objc',
|
||||
'com.google.jimfs',
|
||||
'com.google.protobuf',
|
||||
'com.google.zxing',
|
||||
'com.googlecode.htmlcompressor',
|
||||
'com.googlecode.json-simple',
|
||||
'com.googlecode.libphonenumber',
|
||||
'com.ibm.icu',
|
||||
'com.jakewharton.android.repackaged',
|
||||
'com.jakewharton.timber',
|
||||
'com.linkedin.dexmaker',
|
||||
'com.nulab-inc',
|
||||
'com.otaliastudios.opengl',
|
||||
'com.parse.bolts',
|
||||
'com.pinterest',
|
||||
'com.pinterest.ktlint',
|
||||
'com.squareup',
|
||||
'com.squareup.duktape',
|
||||
'com.squareup.moshi',
|
||||
'com.squareup.okhttp3',
|
||||
'com.squareup.okio',
|
||||
'com.squareup.retrofit2',
|
||||
'com.sun.activation',
|
||||
'com.sun.istack',
|
||||
'com.sun.xml.bind',
|
||||
'com.sun.xml.bind.mvn',
|
||||
'com.sun.xml.fastinfoset',
|
||||
'com.thoughtworks.qdox',
|
||||
'com.vanniktech',
|
||||
'commons-cli',
|
||||
'commons-codec',
|
||||
'commons-io',
|
||||
'commons-logging',
|
||||
'info.picocli',
|
||||
'io.arrow-kt',
|
||||
'io.github.detekt.sarif4k',
|
||||
'io.github.reactivecircus.flowbinding',
|
||||
'io.jsonwebtoken',
|
||||
'io.kindedj',
|
||||
'io.mockk',
|
||||
'io.noties.markwon',
|
||||
'io.reactivex.rxjava2',
|
||||
'io.realm',
|
||||
'it.unimi.dsi',
|
||||
'jakarta.activation',
|
||||
'jakarta.xml.bind',
|
||||
'javax.annotation',
|
||||
'javax.inject',
|
||||
'jline',
|
||||
'jp.wasabeef',
|
||||
'junit',
|
||||
'me.leolin',
|
||||
'me.saket',
|
||||
'net.bytebuddy',
|
||||
'net.java',
|
||||
'net.java.dev.jna',
|
||||
'net.lachlanmckee',
|
||||
'net.ltgt.gradle.incap',
|
||||
'net.sf.jopt-simple',
|
||||
'net.sf.kxml',
|
||||
'nl.dionsegijn',
|
||||
'org.amshove.kluent',
|
||||
'org.apache',
|
||||
'org.apache.ant',
|
||||
'org.apache.commons',
|
||||
'org.apache.httpcomponents',
|
||||
'org.apache.sanselan',
|
||||
'org.bouncycastle',
|
||||
'org.checkerframework',
|
||||
'org.codehaus',
|
||||
'org.codehaus.groovy',
|
||||
'org.codehaus.mojo',
|
||||
'org.eclipse.ee4j',
|
||||
'org.ec4j.core',
|
||||
'org.glassfish.jaxb',
|
||||
'org.hamcrest',
|
||||
'org.jetbrains',
|
||||
'org.jetbrains.intellij.deps',
|
||||
'org.jetbrains.kotlin',
|
||||
'org.jetbrains.kotlinx',
|
||||
'org.jsoup',
|
||||
'org.junit',
|
||||
'org.junit.jupiter',
|
||||
'org.junit.platform',
|
||||
'org.jvnet.staxex',
|
||||
'org.mockito',
|
||||
'org.mongodb',
|
||||
'org.objenesis',
|
||||
'org.opentest4j',
|
||||
'org.ow2',
|
||||
'org.ow2.asm',
|
||||
'org.ow2.asm',
|
||||
'org.reactivestreams',
|
||||
'org.robolectric',
|
||||
'org.slf4j',
|
||||
'org.sonatype.oss',
|
||||
'org.testng',
|
||||
'org.threeten',
|
||||
'xerces',
|
||||
'xml-apis',
|
||||
]
|
||||
],
|
||||
jcenter : [
|
||||
regex: [
|
||||
],
|
||||
group: [
|
||||
'com.amulyakhare',
|
||||
'com.otaliastudios',
|
||||
'com.yqritc',
|
||||
// https://github.com/cmelchior/realmfieldnameshelper/issues/42
|
||||
'dk.ilios',
|
||||
'im.dlg',
|
||||
'me.dm7.barcodescanner',
|
||||
'me.gujun.android',
|
||||
]
|
||||
]
|
||||
]
|
||||
|
@ -39,4 +39,7 @@
|
||||
|
||||
<!-- Navigation Drawer -->
|
||||
<dimen name="navigation_drawer_max_width">320dp</dimen>
|
||||
|
||||
<!-- Preview Url -->
|
||||
<dimen name="preview_url_view_corner_radius">8dp</dimen>
|
||||
</resources>
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,8 +140,8 @@ dependencies {
|
||||
implementation libs.arrow.core
|
||||
implementation libs.arrow.instances
|
||||
|
||||
// olm lib is now hosted by jitpack: https://jitpack.io/#org.matrix.gitlab.matrix-org/olm
|
||||
implementation 'org.matrix.gitlab.matrix-org:olm:3.2.4'
|
||||
// olm lib is now hosted by maven at https://gitlab.matrix.org/api/v4/projects/27/packages/maven
|
||||
implementation 'org.matrix.android:olm:3.2.7'
|
||||
|
||||
// DI
|
||||
implementation libs.dagger.dagger
|
||||
@ -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'
|
||||
|
@ -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<String>,
|
||||
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
|
||||
}
|
||||
|
@ -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<String>,
|
||||
@ -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"
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -35,9 +35,9 @@ class ${activityClass} : VectorBaseActivity(), ToolbarConfigurable {
|
||||
<#if createFragmentArgs>
|
||||
val fragmentArgs: ${fragmentArgsClass} = intent?.extras?.getParcelable(EXTRA_FRAGMENT_ARGS)
|
||||
?: return
|
||||
addFragment(R.id.simpleFragmentContainer, ${fragmentClass}::class.java, fragmentArgs)
|
||||
addFragment(views.simpleFragmentContainer.id, ${fragmentClass}::class.java, fragmentArgs)
|
||||
<#else>
|
||||
addFragment(R.id.simpleFragmentContainer, ${fragmentClass}::class.java)
|
||||
addFragment(views.simpleFragmentContainer.id, ${fragmentClass}::class.java)
|
||||
</#if>
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
||||
@ -317,11 +316,6 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
// videocache includes a sl4j logger which causes mockk to attempt to call the static android Log
|
||||
testImplementation.exclude group: 'org.slf4j', module: 'slf4j-android'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation project(":matrix-sdk-android")
|
||||
@ -365,7 +359,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
|
||||
@ -398,7 +392,7 @@ dependencies {
|
||||
implementation libs.markwon.html
|
||||
implementation 'com.googlecode.htmlcompressor:htmlcompressor:1.5.2'
|
||||
implementation 'me.saket:better-link-movement-method:2.2.0'
|
||||
implementation 'com.google.android:flexbox:2.0.1'
|
||||
implementation 'com.google.android.flexbox:flexbox:3.0.0'
|
||||
implementation libs.androidx.autoFill
|
||||
implementation 'jp.wasabeef:glide-transformations:4.3.0'
|
||||
implementation 'com.github.vector-im:PFLockScreen-Android:1.0.0-beta12'
|
||||
@ -415,7 +409,7 @@ dependencies {
|
||||
implementation 'com.arthenica:ffmpeg-kit-audio:4.5.LTS'
|
||||
|
||||
// Alerter
|
||||
implementation 'com.tapadoo.android:alerter:7.0.1'
|
||||
implementation 'com.github.tapadoo:alerter:7.2.4'
|
||||
|
||||
implementation 'com.otaliastudios:autocomplete:1.1.0'
|
||||
|
||||
@ -433,7 +427,6 @@ dependencies {
|
||||
|
||||
implementation libs.github.glide
|
||||
kapt libs.github.glideCompiler
|
||||
implementation 'com.danikula:videocache:2.7.1'
|
||||
implementation 'com.github.yalantis:ucrop:2.2.7'
|
||||
|
||||
// Badge for compatibility
|
||||
|
@ -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)
|
||||
|
@ -8,6 +8,7 @@
|
||||
<activity android:name=".features.debug.analytics.DebugAnalyticsActivity" />
|
||||
<activity android:name=".features.debug.settings.DebugPrivateSettingsActivity" />
|
||||
<activity android:name=".features.debug.sas.DebugSasEmojiActivity" />
|
||||
<activity android:name=".features.debug.features.DebugFeaturesSettingsActivity" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
@ -35,6 +35,7 @@ import im.vector.app.core.utils.registerForPermissionsResult
|
||||
import im.vector.app.core.utils.toast
|
||||
import im.vector.app.databinding.ActivityDebugMenuBinding
|
||||
import im.vector.app.features.debug.analytics.DebugAnalyticsActivity
|
||||
import im.vector.app.features.debug.features.DebugFeaturesSettingsActivity
|
||||
import im.vector.app.features.debug.sas.DebugSasEmojiActivity
|
||||
import im.vector.app.features.debug.settings.DebugPrivateSettingsActivity
|
||||
import im.vector.app.features.qrcode.QrCodeScannerActivity
|
||||
@ -77,6 +78,7 @@ class DebugMenuActivity : VectorBaseActivity<ActivityDebugMenuBinding>() {
|
||||
}
|
||||
|
||||
private fun setupViews() {
|
||||
views.debugFeatures.setOnClickListener { startActivity(Intent(this, DebugFeaturesSettingsActivity::class.java)) }
|
||||
views.debugPrivateSetting.setOnClickListener { openPrivateSettings() }
|
||||
views.debugAnalytics.setOnClickListener {
|
||||
startActivity(Intent(this, DebugAnalyticsActivity::class.java))
|
||||
|
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.debug.di
|
||||
|
||||
import android.content.Context
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import im.vector.app.features.DefaultVectorFeatures
|
||||
import im.vector.app.features.VectorFeatures
|
||||
import im.vector.app.features.debug.features.DebugVectorFeatures
|
||||
|
||||
@InstallIn(SingletonComponent::class)
|
||||
@Module
|
||||
interface FeaturesModule {
|
||||
|
||||
@Binds
|
||||
fun bindFeatures(debugFeatures: DebugVectorFeatures): VectorFeatures
|
||||
|
||||
companion object {
|
||||
|
||||
@Provides
|
||||
fun providesDefaultVectorFeatures(): DefaultVectorFeatures {
|
||||
return DefaultVectorFeatures()
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun providesDebugVectorFeatures(context: Context, defaultVectorFeatures: DefaultVectorFeatures): DebugVectorFeatures {
|
||||
return DebugVectorFeatures(context, defaultVectorFeatures)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.debug.features
|
||||
|
||||
import android.os.Bundle
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.configureWith
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.databinding.FragmentGenericRecyclerBinding
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
class DebugFeaturesSettingsActivity : VectorBaseActivity<FragmentGenericRecyclerBinding>() {
|
||||
|
||||
@Inject lateinit var debugFeatures: DebugVectorFeatures
|
||||
@Inject lateinit var debugFeaturesStateFactory: DebugFeaturesStateFactory
|
||||
@Inject lateinit var controller: FeaturesController
|
||||
|
||||
override fun getBinding() = FragmentGenericRecyclerBinding.inflate(layoutInflater)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
controller.listener = object : EnumFeatureItem.Listener {
|
||||
override fun <T : Enum<T>> onOptionSelected(option: T?, feature: Feature.EnumFeature<T>) {
|
||||
debugFeatures.overrideEnum(option, feature.type)
|
||||
}
|
||||
}
|
||||
views.genericRecyclerView.configureWith(controller)
|
||||
controller.setData(debugFeaturesStateFactory.create())
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
controller.listener = null
|
||||
views.genericRecyclerView.cleanup()
|
||||
super.onDestroy()
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.debug.features
|
||||
|
||||
import im.vector.app.features.DefaultVectorFeatures
|
||||
import javax.inject.Inject
|
||||
|
||||
class DebugFeaturesStateFactory @Inject constructor(
|
||||
private val debugFeatures: DebugVectorFeatures,
|
||||
private val defaultFeatures: DefaultVectorFeatures
|
||||
) {
|
||||
|
||||
fun create(): FeaturesState {
|
||||
return FeaturesState(listOf(
|
||||
createEnumFeature(
|
||||
label = "Login version",
|
||||
selection = debugFeatures.loginVersion(),
|
||||
default = defaultFeatures.loginVersion()
|
||||
)
|
||||
))
|
||||
}
|
||||
|
||||
private inline fun <reified T : Enum<T>> createEnumFeature(label: String, selection: T, default: T): Feature {
|
||||
return Feature.EnumFeature(
|
||||
label = label,
|
||||
selection = selection.takeIf { debugFeatures.hasEnumOverride(T::class) },
|
||||
default = default,
|
||||
options = enumValues<T>().toList(),
|
||||
type = T::class
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.debug.features
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.preferences.core.MutablePreferences
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import androidx.datastore.preferences.preferencesDataStore
|
||||
import im.vector.app.features.DefaultVectorFeatures
|
||||
import im.vector.app.features.VectorFeatures
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "debug_features")
|
||||
|
||||
class DebugVectorFeatures(
|
||||
context: Context,
|
||||
private val vectorFeatures: DefaultVectorFeatures
|
||||
) : VectorFeatures {
|
||||
|
||||
private val dataStore = context.dataStore
|
||||
|
||||
override fun loginVersion(): VectorFeatures.LoginVersion {
|
||||
return readPreferences().getEnum<VectorFeatures.LoginVersion>() ?: vectorFeatures.loginVersion()
|
||||
}
|
||||
|
||||
fun <T : Enum<T>> hasEnumOverride(type: KClass<T>) = readPreferences().containsEnum(type)
|
||||
|
||||
fun <T : Enum<T>> overrideEnum(value: T?, type: KClass<T>) {
|
||||
if (value == null) {
|
||||
updatePreferences { it.removeEnum(type) }
|
||||
} else {
|
||||
updatePreferences { it.putEnum(value, type) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun readPreferences() = runBlocking { dataStore.data.first() }
|
||||
|
||||
private fun updatePreferences(block: (MutablePreferences) -> Unit) = runBlocking {
|
||||
dataStore.edit { block(it) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T : Enum<T>> MutablePreferences.removeEnum(type: KClass<T>) {
|
||||
remove(enumPreferencesKey(type))
|
||||
}
|
||||
|
||||
private fun <T : Enum<T>> Preferences.containsEnum(type: KClass<T>) = contains(enumPreferencesKey(type))
|
||||
|
||||
private fun <T : Enum<T>> MutablePreferences.putEnum(value: T, type: KClass<T>) {
|
||||
this[enumPreferencesKey(type)] = value.name
|
||||
}
|
||||
|
||||
private inline fun <reified T : Enum<T>> Preferences.getEnum(): T? {
|
||||
return get(enumPreferencesKey<T>())?.let { enumValueOf<T>(it) }
|
||||
}
|
||||
|
||||
private inline fun <reified T : Enum<T>> enumPreferencesKey() = enumPreferencesKey(T::class)
|
||||
|
||||
private fun <T : Enum<T>> enumPreferencesKey(type: KClass<T>) = stringPreferencesKey("enum-${type.simpleName}")
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2019 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.debug.features
|
||||
|
||||
import android.view.View
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.Spinner
|
||||
import android.widget.TextView
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
|
||||
@EpoxyModelClass(layout = im.vector.app.R.layout.item_feature)
|
||||
abstract class EnumFeatureItem : VectorEpoxyModel<EnumFeatureItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
lateinit var feature: Feature.EnumFeature<*>
|
||||
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
|
||||
var listener: Listener? = null
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
holder.label.text = feature.label
|
||||
|
||||
holder.optionsSpinner.apply {
|
||||
val arrayAdapter = ArrayAdapter<String>(context, android.R.layout.simple_spinner_dropdown_item)
|
||||
arrayAdapter.add("DEFAULT - ${feature.default.name}")
|
||||
arrayAdapter.addAll(feature.options.map { it.name })
|
||||
adapter = arrayAdapter
|
||||
|
||||
feature.selection?.let {
|
||||
setSelection(feature.options.indexOf(it) + 1, false)
|
||||
}
|
||||
|
||||
onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||
when (position) {
|
||||
0 -> listener?.onOptionSelected(option = null, feature)
|
||||
else -> feature.onOptionSelected(position - 1)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T : Enum<T>> Feature.EnumFeature<T>.onOptionSelected(selection: Int) {
|
||||
listener?.onOptionSelected(options[selection], this)
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
val label by bind<TextView>(im.vector.app.R.id.feature_label)
|
||||
val optionsSpinner by bind<Spinner>(im.vector.app.R.id.feature_options)
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
fun <T : Enum<T>> onOptionSelected(option: T?, feature: Feature.EnumFeature<T>)
|
||||
}
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2019 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.debug.features
|
||||
|
||||
import com.airbnb.epoxy.TypedEpoxyController
|
||||
import javax.inject.Inject
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
data class FeaturesState(
|
||||
val features: List<Feature>
|
||||
)
|
||||
|
||||
sealed interface Feature {
|
||||
|
||||
data class EnumFeature<T : Enum<T>>(
|
||||
val label: String,
|
||||
val selection: T?,
|
||||
val default: T,
|
||||
val options: List<T>,
|
||||
val type: KClass<T>
|
||||
) : Feature
|
||||
}
|
||||
|
||||
class FeaturesController @Inject constructor() : TypedEpoxyController<FeaturesState>() {
|
||||
|
||||
var listener: EnumFeatureItem.Listener? = null
|
||||
|
||||
override fun buildModels(data: FeaturesState?) {
|
||||
if (data == null) return
|
||||
|
||||
data.features.forEachIndexed { index, feature ->
|
||||
when (feature) {
|
||||
is Feature.EnumFeature<*> -> enumFeatureItem {
|
||||
id(index)
|
||||
feature(feature)
|
||||
listener(this@FeaturesController.listener)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -17,7 +17,6 @@
|
||||
package im.vector.app.features.debug.settings
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.addFragment
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.databinding.ActivitySimpleBinding
|
||||
@ -30,7 +29,7 @@ class DebugPrivateSettingsActivity : VectorBaseActivity<ActivitySimpleBinding>()
|
||||
override fun initUiAndData() {
|
||||
if (isFirstCreation()) {
|
||||
addFragment(
|
||||
R.id.simpleFragmentContainer,
|
||||
views.simpleFragmentContainer,
|
||||
DebugPrivateSettingsFragment::class.java
|
||||
)
|
||||
}
|
||||
|
@ -20,6 +20,12 @@
|
||||
android:padding="@dimen/layout_horizontal_margin"
|
||||
android:showDividers="middle">
|
||||
|
||||
<Button
|
||||
android:id="@+id/debug_features"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Features" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/debug_private_setting"
|
||||
android:layout_width="wrap_content"
|
||||
|
30
vector/src/debug/res/layout/item_feature.xml
Normal file
30
vector/src/debug/res/layout/item_feature.xml
Normal file
@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/feature_label"
|
||||
style="@style/Widget.Vector.TextView.Subtitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:textColor="?vctr_content_primary"
|
||||
tools:text="Login version" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatSpinner
|
||||
android:id="@+id/feature_options"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
</LinearLayout>
|
@ -8,7 +8,8 @@
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
android:orientation="horizontal"
|
||||
tools:viewBindingIgnore="true">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sas_emoji_index"
|
||||
|
@ -342,11 +342,6 @@ SOFTWARE.
|
||||
<br/>
|
||||
Copyright 2012 Square, Inc.
|
||||
</li>
|
||||
<li>
|
||||
<b>videocache</b>
|
||||
<br/>
|
||||
Copyright 2014-2017 Alexey Danilov
|
||||
</li>
|
||||
<li>
|
||||
<b>ShortcutBadger</b>
|
||||
<br/>
|
||||
|
@ -134,6 +134,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
|
||||
@ -705,6 +706,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)
|
||||
|
@ -87,6 +87,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
|
||||
@ -516,6 +517,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)
|
||||
|
@ -31,8 +31,6 @@ import im.vector.app.core.error.DefaultErrorFormatter
|
||||
import im.vector.app.core.error.ErrorFormatter
|
||||
import im.vector.app.core.time.Clock
|
||||
import im.vector.app.core.time.DefaultClock
|
||||
import im.vector.app.features.DefaultVectorFeatures
|
||||
import im.vector.app.features.VectorFeatures
|
||||
import im.vector.app.features.analytics.VectorAnalytics
|
||||
import im.vector.app.features.analytics.impl.DefaultVectorAnalytics
|
||||
import im.vector.app.features.invite.AutoAcceptInvites
|
||||
@ -140,9 +138,4 @@ object VectorStaticModule {
|
||||
fun providesCoroutineDispatchers(): CoroutineDispatchers {
|
||||
return CoroutineDispatchers(io = Dispatchers.IO, computation = Dispatchers.Default)
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun providesFeatures(): VectorFeatures {
|
||||
return DefaultVectorFeatures()
|
||||
}
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ package im.vector.app.core.extensions
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.os.Parcelable
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.result.ActivityResult
|
||||
@ -33,57 +34,56 @@ fun ComponentActivity.registerStartForActivityResult(onResult: (ActivityResult)
|
||||
}
|
||||
|
||||
fun AppCompatActivity.addFragment(
|
||||
frameId: Int,
|
||||
container: ViewGroup,
|
||||
fragment: Fragment,
|
||||
allowStateLoss: Boolean = false
|
||||
) {
|
||||
supportFragmentManager.commitTransaction(allowStateLoss) { add(frameId, fragment) }
|
||||
allowStateLoss: Boolean = false) {
|
||||
supportFragmentManager.commitTransaction(allowStateLoss) { add(container.id, fragment) }
|
||||
}
|
||||
|
||||
fun <T : Fragment> AppCompatActivity.addFragment(
|
||||
frameId: Int,
|
||||
container: ViewGroup,
|
||||
fragmentClass: Class<T>,
|
||||
params: Parcelable? = null,
|
||||
tag: String? = null,
|
||||
allowStateLoss: Boolean = false
|
||||
) {
|
||||
allowStateLoss: Boolean = false) {
|
||||
supportFragmentManager.commitTransaction(allowStateLoss) {
|
||||
add(frameId, fragmentClass, params.toMvRxBundle(), tag)
|
||||
add(container.id, fragmentClass, params.toMvRxBundle(), tag)
|
||||
}
|
||||
}
|
||||
|
||||
fun AppCompatActivity.replaceFragment(
|
||||
frameId: Int,
|
||||
container: ViewGroup,
|
||||
fragment: Fragment,
|
||||
tag: String? = null,
|
||||
allowStateLoss: Boolean = false
|
||||
) {
|
||||
supportFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment, tag) }
|
||||
allowStateLoss: Boolean = false) {
|
||||
supportFragmentManager.commitTransaction(allowStateLoss) {
|
||||
replace(container.id, fragment, tag)
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : Fragment> AppCompatActivity.replaceFragment(
|
||||
frameId: Int,
|
||||
container: ViewGroup,
|
||||
fragmentClass: Class<T>,
|
||||
params: Parcelable? = null,
|
||||
tag: String? = null,
|
||||
allowStateLoss: Boolean = false
|
||||
) {
|
||||
allowStateLoss: Boolean = false) {
|
||||
supportFragmentManager.commitTransaction(allowStateLoss) {
|
||||
replace(frameId, fragmentClass, params.toMvRxBundle(), tag)
|
||||
replace(container.id, fragmentClass, params.toMvRxBundle(), tag)
|
||||
}
|
||||
}
|
||||
|
||||
fun AppCompatActivity.addFragmentToBackstack(
|
||||
frameId: Int,
|
||||
container: ViewGroup,
|
||||
fragment: Fragment,
|
||||
tag: String? = null,
|
||||
allowStateLoss: Boolean = false
|
||||
) {
|
||||
supportFragmentManager.commitTransaction(allowStateLoss) { replace(frameId, fragment).addToBackStack(tag) }
|
||||
allowStateLoss: Boolean = false) {
|
||||
supportFragmentManager.commitTransaction(allowStateLoss) {
|
||||
replace(container.id, fragment).addToBackStack(tag)
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : Fragment> AppCompatActivity.addFragmentToBackstack(
|
||||
frameId: Int,
|
||||
container: ViewGroup,
|
||||
fragmentClass: Class<T>,
|
||||
params: Parcelable? = null,
|
||||
tag: String? = null,
|
||||
@ -91,7 +91,7 @@ fun <T : Fragment> AppCompatActivity.addFragmentToBackstack(
|
||||
option: ((FragmentTransaction) -> Unit)? = null) {
|
||||
supportFragmentManager.commitTransaction(allowStateLoss) {
|
||||
option?.invoke(this)
|
||||
replace(frameId, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag)
|
||||
replace(container.id, fragmentClass, params.toMvRxBundle(), tag).addToBackStack(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.addFragment
|
||||
import im.vector.app.core.platform.ToolbarConfigurable
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
@ -61,7 +60,7 @@ class AttachmentsPreviewActivity : VectorBaseActivity<ActivitySimpleBinding>(),
|
||||
override fun initUiAndData() {
|
||||
if (isFirstCreation()) {
|
||||
val fragmentArgs: AttachmentsPreviewArgs = intent?.extras?.getParcelable(EXTRA_FRAGMENT_ARGS) ?: return
|
||||
addFragment(R.id.simpleFragmentContainer, AttachmentsPreviewFragment::class.java, fragmentArgs)
|
||||
addFragment(views.simpleFragmentContainer, AttachmentsPreviewFragment::class.java, fragmentArgs)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ class ReAuthActivity : SimpleFragmentActivity() {
|
||||
// so we assume that after the user close the tab we return success and let caller retry the UIA flow :/
|
||||
if (isFirstCreation()) {
|
||||
addFragment(
|
||||
R.id.container,
|
||||
views.container,
|
||||
PromptFragment::class.java
|
||||
)
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
|
||||
.launchIn(lifecycleScope)
|
||||
if (isFirstCreation()) {
|
||||
addFragment(
|
||||
R.id.container,
|
||||
views.container,
|
||||
UserListFragment::class.java,
|
||||
UserListFragmentArgs(
|
||||
title = getString(R.string.fab_menu_create_chat),
|
||||
@ -95,20 +95,20 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
|
||||
|
||||
private fun openAddByQrCode() {
|
||||
if (checkPermissions(PERMISSIONS_FOR_TAKING_PHOTO, this, permissionCameraLauncher)) {
|
||||
addFragment(R.id.container, CreateDirectRoomByQrCodeFragment::class.java)
|
||||
addFragment(views.container, CreateDirectRoomByQrCodeFragment::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
private fun openPhoneBook() {
|
||||
// Check permission first
|
||||
if (checkPermissions(PERMISSIONS_FOR_MEMBERS_SEARCH, this, permissionReadContactLauncher)) {
|
||||
addFragmentToBackstack(R.id.container, ContactsBookFragment::class.java)
|
||||
addFragmentToBackstack(views.container, ContactsBookFragment::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
private val permissionReadContactLauncher = registerForPermissionsResult { allGranted, deniedPermanently ->
|
||||
if (allGranted) {
|
||||
doOnPostResume { addFragmentToBackstack(R.id.container, ContactsBookFragment::class.java) }
|
||||
doOnPostResume { addFragmentToBackstack(views.container, ContactsBookFragment::class.java) }
|
||||
} else if (deniedPermanently) {
|
||||
onPermissionDeniedSnackbar(R.string.permissions_denied_add_contact)
|
||||
}
|
||||
@ -116,7 +116,7 @@ class CreateDirectRoomActivity : SimpleFragmentActivity() {
|
||||
|
||||
private val permissionCameraLauncher = registerForPermissionsResult { allGranted, deniedPermanently ->
|
||||
if (allGranted) {
|
||||
addFragment(R.id.container, CreateDirectRoomByQrCodeFragment::class.java)
|
||||
addFragment(views.container, CreateDirectRoomByQrCodeFragment::class.java)
|
||||
} else if (deniedPermanently) {
|
||||
onPermissionDeniedSnackbar(R.string.permissions_denied_qr_code)
|
||||
}
|
||||
|
@ -64,9 +64,9 @@ class KeysBackupRestoreActivity : SimpleFragmentActivity() {
|
||||
val isBackupCreatedFromPassphrase =
|
||||
viewModel.keyVersionResult.value?.getAuthDataAsMegolmBackupAuthData()?.privateKeySalt != null
|
||||
if (isBackupCreatedFromPassphrase) {
|
||||
replaceFragment(R.id.container, KeysBackupRestoreFromPassphraseFragment::class.java)
|
||||
replaceFragment(views.container, KeysBackupRestoreFromPassphraseFragment::class.java)
|
||||
} else {
|
||||
replaceFragment(R.id.container, KeysBackupRestoreFromKeyFragment::class.java)
|
||||
replaceFragment(views.container, KeysBackupRestoreFromKeyFragment::class.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -91,13 +91,13 @@ class KeysBackupRestoreActivity : SimpleFragmentActivity() {
|
||||
viewModel.navigateEvent.observeEvent(this) { uxStateEvent ->
|
||||
when (uxStateEvent) {
|
||||
KeysBackupRestoreSharedViewModel.NAVIGATE_TO_RECOVER_WITH_KEY -> {
|
||||
addFragmentToBackstack(R.id.container, KeysBackupRestoreFromKeyFragment::class.java, allowStateLoss = true)
|
||||
addFragmentToBackstack(views.container, KeysBackupRestoreFromKeyFragment::class.java, allowStateLoss = true)
|
||||
}
|
||||
KeysBackupRestoreSharedViewModel.NAVIGATE_TO_SUCCESS -> {
|
||||
viewModel.keyVersionResult.value?.version?.let {
|
||||
KeysBackupBanner.onRecoverDoneForVersion(this, it)
|
||||
}
|
||||
replaceFragment(R.id.container, KeysBackupRestoreSuccessFragment::class.java, allowStateLoss = true)
|
||||
replaceFragment(views.container, KeysBackupRestoreSuccessFragment::class.java, allowStateLoss = true)
|
||||
}
|
||||
KeysBackupRestoreSharedViewModel.NAVIGATE_TO_4S -> {
|
||||
launch4SActivity()
|
||||
|
@ -44,7 +44,7 @@ class KeysBackupManageActivity : SimpleFragmentActivity() {
|
||||
override fun initUiAndData() {
|
||||
super.initUiAndData()
|
||||
if (supportFragmentManager.fragments.isEmpty()) {
|
||||
replaceFragment(R.id.container, KeysBackupSettingsFragment::class.java)
|
||||
replaceFragment(views.container, KeysBackupSettingsFragment::class.java)
|
||||
viewModel.handle(KeyBackupSettingsAction.Init)
|
||||
}
|
||||
|
||||
|
@ -54,7 +54,7 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() {
|
||||
override fun initUiAndData() {
|
||||
super.initUiAndData()
|
||||
if (isFirstCreation()) {
|
||||
replaceFragment(R.id.container, KeysBackupSetupStep1Fragment::class.java)
|
||||
replaceFragment(views.container, KeysBackupSetupStep1Fragment::class.java)
|
||||
}
|
||||
|
||||
viewModel = viewModelProvider.get(KeysBackupSetupSharedViewModel::class.java)
|
||||
@ -80,11 +80,11 @@ class KeysBackupSetupActivity : SimpleFragmentActivity() {
|
||||
when (uxStateEvent) {
|
||||
KeysBackupSetupSharedViewModel.NAVIGATE_TO_STEP_2 -> {
|
||||
supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
|
||||
replaceFragment(R.id.container, KeysBackupSetupStep2Fragment::class.java)
|
||||
replaceFragment(views.container, KeysBackupSetupStep2Fragment::class.java)
|
||||
}
|
||||
KeysBackupSetupSharedViewModel.NAVIGATE_TO_STEP_3 -> {
|
||||
supportFragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE)
|
||||
replaceFragment(R.id.container, KeysBackupSetupStep3Fragment::class.java)
|
||||
replaceFragment(views.container, KeysBackupSetupStep3Fragment::class.java)
|
||||
}
|
||||
KeysBackupSetupSharedViewModel.NAVIGATE_FINISH -> {
|
||||
val resultIntent = Intent()
|
||||
|
@ -31,7 +31,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.error.ErrorFormatter
|
||||
import im.vector.app.core.extensions.commitTransaction
|
||||
import im.vector.app.core.extensions.replaceFragment
|
||||
import im.vector.app.core.platform.SimpleFragmentActivity
|
||||
import im.vector.app.core.platform.VectorBaseBottomSheetDialogFragment
|
||||
import im.vector.app.features.crypto.recover.SetupMode
|
||||
@ -84,7 +84,7 @@ class SharedSecureStorageActivity :
|
||||
SharedSecureStorageViewState.Step.ResetAll -> SharedSecuredStorageResetAllFragment::class
|
||||
}
|
||||
|
||||
showFragment(fragment, Bundle())
|
||||
showFragment(fragment)
|
||||
}
|
||||
|
||||
private fun observeViewEvents(it: SharedSecureStorageViewEvent?) {
|
||||
@ -131,15 +131,14 @@ class SharedSecureStorageActivity :
|
||||
}
|
||||
}
|
||||
|
||||
private fun showFragment(fragmentClass: KClass<out Fragment>, bundle: Bundle) {
|
||||
private fun showFragment(fragmentClass: KClass<out Fragment>) {
|
||||
if (supportFragmentManager.findFragmentByTag(fragmentClass.simpleName) == null) {
|
||||
supportFragmentManager.commitTransaction {
|
||||
replace(R.id.container,
|
||||
fragmentClass.java,
|
||||
bundle,
|
||||
fragmentClass.simpleName
|
||||
)
|
||||
}
|
||||
replaceFragment(
|
||||
views.container,
|
||||
fragmentClass.java,
|
||||
null,
|
||||
fragmentClass.simpleName
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,7 +91,7 @@ class RoomDevToolActivity : SimpleFragmentActivity(), FragmentManager.OnBackStac
|
||||
val classJava = RoomDevToolFragment::class.java
|
||||
val tag = classJava.name
|
||||
if (supportFragmentManager.findFragmentByTag(tag) == null) {
|
||||
replaceFragment(R.id.container, RoomDevToolFragment::class.java)
|
||||
replaceFragment(views.container, RoomDevToolFragment::class.java)
|
||||
} else {
|
||||
supportFragmentManager.popBackStack()
|
||||
}
|
||||
@ -155,14 +155,14 @@ class RoomDevToolActivity : SimpleFragmentActivity(), FragmentManager.OnBackStac
|
||||
if (supportFragmentManager.findFragmentByTag(tag) == null) {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.setCustomAnimations(R.anim.fade_in, R.anim.fade_out, R.anim.fade_in, R.anim.fade_out)
|
||||
.replace(R.id.container, fragment, tag)
|
||||
.replace(views.container.id, fragment, tag)
|
||||
.addToBackStack(tag)
|
||||
.commit()
|
||||
} else {
|
||||
if (!supportFragmentManager.popBackStackImmediate(tag, 0)) {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.setCustomAnimations(R.anim.fade_in, R.anim.fade_out, R.anim.fade_in, R.anim.fade_out)
|
||||
.replace(R.id.container, fragment, tag)
|
||||
.replace(views.container.id, fragment, tag)
|
||||
.addToBackStack(tag)
|
||||
.commit()
|
||||
}
|
||||
|
@ -28,6 +28,10 @@ class RoomDevToolRootController @Inject constructor(
|
||||
|
||||
var interactionListener: DevToolsInteractionListener? = null
|
||||
|
||||
init {
|
||||
requestModelBuild()
|
||||
}
|
||||
|
||||
override fun buildModels() {
|
||||
val host = this
|
||||
genericButtonItem {
|
||||
|
@ -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<DiscoveryPolicyItem.Holder>() {
|
||||
@ -40,7 +41,7 @@ abstract class DiscoveryPolicyItem : EpoxyModelWithHolder<DiscoveryPolicyItem.Ho
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
holder.title.text = name
|
||||
holder.url.text = url
|
||||
holder.url.setTextOrHide(url)
|
||||
holder.view.onClick(clickListener)
|
||||
}
|
||||
|
||||
|
@ -433,6 +433,6 @@ class DiscoverySettingsController @Inject constructor(
|
||||
fun onTapUpdateUserConsent(newValue: Boolean)
|
||||
fun onTapRetryToRetrieveBindings()
|
||||
fun onPolicyUrlsExpandedStateToggled(newExpandedState: Boolean)
|
||||
fun onPolicyTapped(policy: IdentityServerPolicy)
|
||||
fun onPolicyTapped(policy: ServerPolicy)
|
||||
}
|
||||
}
|
||||
|
@ -167,10 +167,11 @@ class DiscoverySettingsFragment @Inject constructor(
|
||||
val pidList = state.emailList().orEmpty() + state.phoneNumbersList().orEmpty()
|
||||
val hasBoundIds = pidList.any { it.isShared() == SharedState.SHARED }
|
||||
|
||||
val serverUrl = state.identityServer()?.serverUrl.orEmpty()
|
||||
val message = if (hasBoundIds) {
|
||||
getString(R.string.settings_discovery_disconnect_with_bound_pid, state.identityServer(), state.identityServer())
|
||||
getString(R.string.settings_discovery_disconnect_with_bound_pid, serverUrl, serverUrl)
|
||||
} else {
|
||||
getString(R.string.disconnect_identity_server_dialog_content, state.identityServer())
|
||||
getString(R.string.disconnect_identity_server_dialog_content, serverUrl)
|
||||
}
|
||||
|
||||
MaterialAlertDialogBuilder(requireActivity())
|
||||
@ -203,7 +204,7 @@ class DiscoverySettingsFragment @Inject constructor(
|
||||
viewModel.handle(DiscoverySettingsAction.SetPoliciesExpandState(expanded = newExpandedState))
|
||||
}
|
||||
|
||||
override fun onPolicyTapped(policy: IdentityServerPolicy) {
|
||||
override fun onPolicyTapped(policy: ServerPolicy) {
|
||||
openUrlInChromeCustomTab(requireContext(), null, policy.url)
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ import com.airbnb.mvrx.MavericksState
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
|
||||
data class DiscoverySettingsState(
|
||||
val identityServer: Async<IdentityServerWithTerms?> = Uninitialized,
|
||||
val identityServer: Async<ServerAndPolicies?> = Uninitialized,
|
||||
val emailList: Async<List<PidInfo>> = Uninitialized,
|
||||
val phoneNumbersList: Async<List<PidInfo>> = Uninitialized,
|
||||
// Can be true if terms are updated
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -16,12 +16,12 @@
|
||||
|
||||
package im.vector.app.features.discovery
|
||||
|
||||
data class IdentityServerWithTerms(
|
||||
data class ServerAndPolicies(
|
||||
val serverUrl: String,
|
||||
val policies: List<IdentityServerPolicy>
|
||||
val policies: List<ServerPolicy>
|
||||
)
|
||||
|
||||
data class IdentityServerPolicy(
|
||||
data class ServerPolicy(
|
||||
val name: String,
|
||||
val url: String
|
||||
)
|
@ -178,8 +178,8 @@ class HomeActivity :
|
||||
sharedActionViewModel = viewModelProvider.get(HomeSharedActionViewModel::class.java)
|
||||
views.drawerLayout.addDrawerListener(drawerListener)
|
||||
if (isFirstCreation()) {
|
||||
replaceFragment(R.id.homeDetailFragmentContainer, HomeDetailFragment::class.java)
|
||||
replaceFragment(R.id.homeDrawerFragmentContainer, HomeDrawerFragment::class.java)
|
||||
replaceFragment(views.homeDetailFragmentContainer, HomeDetailFragment::class.java)
|
||||
replaceFragment(views.homeDrawerFragmentContainer, HomeDrawerFragment::class.java)
|
||||
}
|
||||
|
||||
sharedActionViewModel
|
||||
@ -195,7 +195,7 @@ class HomeActivity :
|
||||
// When switching from space to group or group to space, we need to reload the fragment
|
||||
// To be removed when dropping legacy groups
|
||||
if (sharedAction.clearFragment) {
|
||||
replaceFragment(R.id.homeDetailFragmentContainer, HomeDetailFragment::class.java, allowStateLoss = true)
|
||||
replaceFragment(views.homeDetailFragmentContainer, HomeDetailFragment::class.java, allowStateLoss = true)
|
||||
} else {
|
||||
// nop
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ import com.airbnb.mvrx.Mavericks
|
||||
import com.airbnb.mvrx.viewModel
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.endKeepScreenOn
|
||||
import im.vector.app.core.extensions.hideKeyboard
|
||||
import im.vector.app.core.extensions.keepScreenOn
|
||||
@ -108,8 +107,8 @@ class RoomDetailActivity :
|
||||
currentRoomId = roomDetailArgs.roomId
|
||||
|
||||
if (isFirstCreation()) {
|
||||
replaceFragment(R.id.roomDetailContainer, RoomDetailFragment::class.java, roomDetailArgs)
|
||||
replaceFragment(R.id.roomDetailDrawerContainer, BreadcrumbsFragment::class.java)
|
||||
replaceFragment(views.roomDetailContainer, RoomDetailFragment::class.java, roomDetailArgs)
|
||||
replaceFragment(views.roomDetailDrawerContainer, BreadcrumbsFragment::class.java)
|
||||
}
|
||||
|
||||
sharedActionViewModel = viewModelProvider.get(RoomDetailSharedActionViewModel::class.java)
|
||||
@ -146,7 +145,7 @@ class RoomDetailActivity :
|
||||
if (currentRoomId != switchToRoom.roomId) {
|
||||
currentRoomId = switchToRoom.roomId
|
||||
requireActiveMembershipViewModel.handle(RequireActiveMembershipAction.ChangeRoom(switchToRoom.roomId))
|
||||
replaceFragment(R.id.roomDetailContainer, RoomDetailFragment::class.java, RoomDetailArgs(switchToRoom.roomId))
|
||||
replaceFragment(views.roomDetailContainer, RoomDetailFragment::class.java, RoomDetailArgs(switchToRoom.roomId))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,6 @@ import android.os.Bundle
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import com.airbnb.mvrx.Mavericks
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.addFragment
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.databinding.ActivitySearchBinding
|
||||
@ -47,7 +46,7 @@ class SearchActivity : VectorBaseActivity<ActivitySearchBinding>() {
|
||||
override fun initUiAndData() {
|
||||
if (isFirstCreation()) {
|
||||
val fragmentArgs: SearchArgs = intent?.extras?.getParcelable(Mavericks.KEY_ARG) ?: return
|
||||
addFragment(R.id.searchFragmentContainer, SearchFragment::class.java, fragmentArgs, FRAGMENT_TAG)
|
||||
addFragment(views.searchFragmentContainer, SearchFragment::class.java, fragmentArgs, FRAGMENT_TAG)
|
||||
}
|
||||
views.searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String): Boolean {
|
||||
|
@ -43,22 +43,12 @@ abstract class BaseEventItem<H : BaseEventItem.BaseHolder> : VectorEpoxyModel<H>
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
|
||||
lateinit var dimensionConverter: DimensionConverter
|
||||
|
||||
protected var ignoreSendStatusVisibility = false
|
||||
|
||||
@CallSuper
|
||||
override fun bind(holder: H) {
|
||||
super.bind(holder)
|
||||
holder.leftGuideline.updateLayoutParams<RelativeLayout.LayoutParams> {
|
||||
this.marginStart = leftGuideline
|
||||
}
|
||||
// Ignore visibility of the send status icon?
|
||||
holder.contentContainer.updateLayoutParams<RelativeLayout.LayoutParams> {
|
||||
if (ignoreSendStatusVisibility) {
|
||||
addRule(RelativeLayout.ALIGN_PARENT_END)
|
||||
} else {
|
||||
removeRule(RelativeLayout.ALIGN_PARENT_END)
|
||||
}
|
||||
}
|
||||
holder.checkableBackground.isChecked = highlighted
|
||||
}
|
||||
|
||||
|
@ -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<MessageVoiceItem.Holder>() {
|
||||
|
||||
init {
|
||||
ignoreSendStatusVisibility = true
|
||||
}
|
||||
|
||||
@EpoxyAttribute
|
||||
var mxcUrl: String = ""
|
||||
|
||||
|
@ -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 })
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,6 @@ import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.replaceFragment
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.databinding.ActivityFilteredRoomsBinding
|
||||
@ -46,7 +45,7 @@ class FilteredRoomsActivity : VectorBaseActivity<ActivityFilteredRoomsBinding>()
|
||||
configureToolbar(views.filteredRoomsToolbar)
|
||||
if (isFirstCreation()) {
|
||||
val params = RoomListParams(RoomListDisplayMode.FILTERED)
|
||||
replaceFragment(R.id.filteredRoomsFragmentContainer, RoomListFragment::class.java, params, FRAGMENT_TAG)
|
||||
replaceFragment(views.filteredRoomsFragmentContainer, RoomListFragment::class.java, params, FRAGMENT_TAG)
|
||||
}
|
||||
views.filteredRoomsSearchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
|
||||
override fun onQueryTextSubmit(query: String): Boolean {
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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<RoomListQuickActionViewState>() {
|
||||
|
||||
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 {
|
||||
|
@ -81,7 +81,7 @@ class InviteUsersToRoomActivity : SimpleFragmentActivity() {
|
||||
.launchIn(lifecycleScope)
|
||||
if (isFirstCreation()) {
|
||||
addFragment(
|
||||
R.id.container,
|
||||
views.container,
|
||||
UserListFragment::class.java,
|
||||
UserListFragmentArgs(
|
||||
title = getString(R.string.invite_users_to_room_title),
|
||||
@ -104,13 +104,13 @@ class InviteUsersToRoomActivity : SimpleFragmentActivity() {
|
||||
private fun openPhoneBook() {
|
||||
// Check permission first
|
||||
if (checkPermissions(PERMISSIONS_FOR_MEMBERS_SEARCH, this, permissionContactLauncher)) {
|
||||
addFragmentToBackstack(R.id.container, ContactsBookFragment::class.java)
|
||||
addFragmentToBackstack(views.container, ContactsBookFragment::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
private val permissionContactLauncher = registerForPermissionsResult { allGranted, deniedPermanently ->
|
||||
if (allGranted) {
|
||||
doOnPostResume { addFragmentToBackstack(R.id.container, ContactsBookFragment::class.java) }
|
||||
doOnPostResume { addFragmentToBackstack(views.container, ContactsBookFragment::class.java) }
|
||||
} else if (deniedPermanently) {
|
||||
onPermissionDeniedSnackbar(R.string.permissions_denied_add_contact)
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ open class LoginActivity : VectorBaseActivity<ActivityLoginBinding>(), ToolbarCo
|
||||
private val popExitAnim = R.anim.exit_fade_out
|
||||
|
||||
private val topFragment: Fragment?
|
||||
get() = supportFragmentManager.findFragmentById(R.id.loginFragmentContainer)
|
||||
get() = supportFragmentManager.findFragmentById(views.loginFragmentContainer.id)
|
||||
|
||||
private val commonOption: (FragmentTransaction) -> Unit = { ft ->
|
||||
// Find the loginLogo on the current Fragment, this should not return null
|
||||
@ -100,7 +100,7 @@ open class LoginActivity : VectorBaseActivity<ActivityLoginBinding>(), ToolbarCo
|
||||
}
|
||||
|
||||
protected open fun addFirstFragment() {
|
||||
addFragment(R.id.loginFragmentContainer, LoginSplashFragment::class.java)
|
||||
addFragment(views.loginFragmentContainer, LoginSplashFragment::class.java)
|
||||
}
|
||||
|
||||
private fun handleLoginViewEvents(loginViewEvents: LoginViewEvents) {
|
||||
@ -118,7 +118,7 @@ open class LoginActivity : VectorBaseActivity<ActivityLoginBinding>(), ToolbarCo
|
||||
// First ask for login and password
|
||||
// I add a tag to indicate that this fragment is a registration stage.
|
||||
// This way it will be automatically popped in when starting the next registration stage
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginFragment::class.java,
|
||||
tag = FRAGMENT_REGISTRATION_STAGE_TAG,
|
||||
option = commonOption
|
||||
@ -135,7 +135,7 @@ open class LoginActivity : VectorBaseActivity<ActivityLoginBinding>(), ToolbarCo
|
||||
Unit
|
||||
}
|
||||
is LoginViewEvents.OpenServerSelection ->
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginServerSelectionFragment::class.java,
|
||||
option = { ft ->
|
||||
findViewById<View?>(R.id.loginSplashLogo)?.let { ft.addSharedElement(it, ViewCompat.getTransitionName(it) ?: "") }
|
||||
@ -149,23 +149,23 @@ open class LoginActivity : VectorBaseActivity<ActivityLoginBinding>(), ToolbarCo
|
||||
is LoginViewEvents.OnServerSelectionDone -> onServerSelectionDone(loginViewEvents)
|
||||
is LoginViewEvents.OnSignModeSelected -> onSignModeSelected(loginViewEvents)
|
||||
is LoginViewEvents.OnLoginFlowRetrieved ->
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginSignUpSignInSelectionFragment::class.java,
|
||||
option = commonOption)
|
||||
is LoginViewEvents.OnWebLoginError -> onWebLoginError(loginViewEvents)
|
||||
is LoginViewEvents.OnForgetPasswordClicked ->
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginResetPasswordFragment::class.java,
|
||||
option = commonOption)
|
||||
is LoginViewEvents.OnResetPasswordSendThreePidDone -> {
|
||||
supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, POP_BACK_STACK_EXCLUSIVE)
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginResetPasswordMailConfirmationFragment::class.java,
|
||||
option = commonOption)
|
||||
}
|
||||
is LoginViewEvents.OnResetPasswordMailConfirmationSuccess -> {
|
||||
supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, POP_BACK_STACK_EXCLUSIVE)
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginResetPasswordSuccessFragment::class.java,
|
||||
option = commonOption)
|
||||
}
|
||||
@ -176,7 +176,7 @@ open class LoginActivity : VectorBaseActivity<ActivityLoginBinding>(), ToolbarCo
|
||||
is LoginViewEvents.OnSendEmailSuccess -> {
|
||||
// Pop the enter email Fragment
|
||||
supportFragmentManager.popBackStack(FRAGMENT_REGISTRATION_STAGE_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE)
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginWaitForEmailFragment::class.java,
|
||||
LoginWaitForEmailFragmentArgument(loginViewEvents.email),
|
||||
tag = FRAGMENT_REGISTRATION_STAGE_TAG,
|
||||
@ -185,7 +185,7 @@ open class LoginActivity : VectorBaseActivity<ActivityLoginBinding>(), ToolbarCo
|
||||
is LoginViewEvents.OnSendMsisdnSuccess -> {
|
||||
// Pop the enter Msisdn Fragment
|
||||
supportFragmentManager.popBackStack(FRAGMENT_REGISTRATION_STAGE_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE)
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginGenericTextInputFormFragment::class.java,
|
||||
LoginGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.ConfirmMsisdn, true, loginViewEvents.msisdn),
|
||||
tag = FRAGMENT_REGISTRATION_STAGE_TAG,
|
||||
@ -229,7 +229,7 @@ open class LoginActivity : VectorBaseActivity<ActivityLoginBinding>(), ToolbarCo
|
||||
when (loginViewEvents.serverType) {
|
||||
ServerType.MatrixOrg -> Unit // In this case, we wait for the login flow
|
||||
ServerType.EMS,
|
||||
ServerType.Other -> addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
ServerType.Other -> addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginServerUrlFormFragment::class.java,
|
||||
option = commonOption)
|
||||
ServerType.Unknown -> Unit /* Should not happen */
|
||||
@ -249,14 +249,14 @@ open class LoginActivity : VectorBaseActivity<ActivityLoginBinding>(), ToolbarCo
|
||||
LoginMode.Unknown,
|
||||
is LoginMode.Sso -> error("Developer error")
|
||||
is LoginMode.SsoAndPassword,
|
||||
LoginMode.Password -> addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
LoginMode.Password -> addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginFragment::class.java,
|
||||
tag = FRAGMENT_LOGIN_TAG,
|
||||
option = commonOption)
|
||||
LoginMode.Unsupported -> onLoginModeNotSupported(state.loginModeSupportedTypes)
|
||||
}.exhaustive
|
||||
}
|
||||
SignMode.SignInWithMatrixId -> addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
SignMode.SignInWithMatrixId -> addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginFragment::class.java,
|
||||
tag = FRAGMENT_LOGIN_TAG,
|
||||
option = commonOption)
|
||||
@ -279,7 +279,7 @@ open class LoginActivity : VectorBaseActivity<ActivityLoginBinding>(), ToolbarCo
|
||||
.setTitle(R.string.app_name)
|
||||
.setMessage(getString(R.string.login_registration_not_supported))
|
||||
.setPositiveButton(R.string.yes) { _, _ ->
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginWebFragment::class.java,
|
||||
option = commonOption)
|
||||
}
|
||||
@ -292,7 +292,7 @@ open class LoginActivity : VectorBaseActivity<ActivityLoginBinding>(), ToolbarCo
|
||||
.setTitle(R.string.app_name)
|
||||
.setMessage(getString(R.string.login_mode_not_supported, supportedTypes.joinToString { "'$it'" }))
|
||||
.setPositiveButton(R.string.yes) { _, _ ->
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginWebFragment::class.java,
|
||||
option = commonOption)
|
||||
}
|
||||
@ -322,22 +322,22 @@ open class LoginActivity : VectorBaseActivity<ActivityLoginBinding>(), ToolbarCo
|
||||
supportFragmentManager.popBackStack(FRAGMENT_REGISTRATION_STAGE_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE)
|
||||
|
||||
when (stage) {
|
||||
is Stage.ReCaptcha -> addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
is Stage.ReCaptcha -> addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginCaptchaFragment::class.java,
|
||||
LoginCaptchaFragmentArgument(stage.publicKey),
|
||||
tag = FRAGMENT_REGISTRATION_STAGE_TAG,
|
||||
option = commonOption)
|
||||
is Stage.Email -> addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
is Stage.Email -> addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginGenericTextInputFormFragment::class.java,
|
||||
LoginGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.SetEmail, stage.mandatory),
|
||||
tag = FRAGMENT_REGISTRATION_STAGE_TAG,
|
||||
option = commonOption)
|
||||
is Stage.Msisdn -> addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
is Stage.Msisdn -> addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginGenericTextInputFormFragment::class.java,
|
||||
LoginGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.SetMsisdn, stage.mandatory),
|
||||
tag = FRAGMENT_REGISTRATION_STAGE_TAG,
|
||||
option = commonOption)
|
||||
is Stage.Terms -> addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
is Stage.Terms -> addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginTermsFragment::class.java,
|
||||
LoginTermsFragmentArgument(stage.policies.toLocalizedLoginTerms(getString(R.string.resources_language))),
|
||||
tag = FRAGMENT_REGISTRATION_STAGE_TAG,
|
||||
|
@ -71,7 +71,7 @@ open class LoginActivity2 : VectorBaseActivity<ActivityLoginBinding>(), ToolbarC
|
||||
private val popExitAnim = R.anim.exit_fade_out
|
||||
|
||||
private val topFragment: Fragment?
|
||||
get() = supportFragmentManager.findFragmentById(R.id.loginFragmentContainer)
|
||||
get() = supportFragmentManager.findFragmentById(views.loginFragmentContainer.id)
|
||||
|
||||
private val commonOption: (FragmentTransaction) -> Unit = { ft ->
|
||||
// Find the loginLogo on the current Fragment, this should not return null
|
||||
@ -108,7 +108,7 @@ open class LoginActivity2 : VectorBaseActivity<ActivityLoginBinding>(), ToolbarC
|
||||
}
|
||||
|
||||
protected open fun addFirstFragment() {
|
||||
addFragment(R.id.loginFragmentContainer, LoginSplashSignUpSignInSelectionFragment2::class.java)
|
||||
addFragment(views.loginFragmentContainer, LoginSplashSignUpSignInSelectionFragment2::class.java)
|
||||
}
|
||||
|
||||
private fun handleLoginViewEvents(event: LoginViewEvents2) {
|
||||
@ -127,7 +127,7 @@ open class LoginActivity2 : VectorBaseActivity<ActivityLoginBinding>(), ToolbarC
|
||||
// First ask for login and password
|
||||
// I add a tag to indicate that this fragment is a registration stage.
|
||||
// This way it will be automatically popped in when starting the next registration stage
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginFragment2::class.java,
|
||||
tag = FRAGMENT_REGISTRATION_STAGE_TAG,
|
||||
option = commonOption
|
||||
@ -146,7 +146,7 @@ open class LoginActivity2 : VectorBaseActivity<ActivityLoginBinding>(), ToolbarC
|
||||
Unit
|
||||
}
|
||||
is LoginViewEvents2.OpenServerSelection ->
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginServerSelectionFragment2::class.java,
|
||||
option = { ft ->
|
||||
findViewById<View?>(R.id.loginSplashLogo)?.let { ft.addSharedElement(it, ViewCompat.getTransitionName(it) ?: "") }
|
||||
@ -158,12 +158,12 @@ open class LoginActivity2 : VectorBaseActivity<ActivityLoginBinding>(), ToolbarC
|
||||
// ft.setCustomAnimations(enterAnim, exitAnim, popEnterAnim, popExitAnim)
|
||||
})
|
||||
is LoginViewEvents2.OpenHomeServerUrlFormScreen -> {
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginServerUrlFormFragment2::class.java,
|
||||
option = commonOption)
|
||||
}
|
||||
is LoginViewEvents2.OpenSignInEnterIdentifierScreen -> {
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginFragmentSigninUsername2::class.java,
|
||||
option = { ft ->
|
||||
findViewById<View?>(R.id.loginSplashLogo)?.let { ft.addSharedElement(it, ViewCompat.getTransitionName(it) ?: "") }
|
||||
@ -176,24 +176,24 @@ open class LoginActivity2 : VectorBaseActivity<ActivityLoginBinding>(), ToolbarC
|
||||
})
|
||||
}
|
||||
is LoginViewEvents2.OpenSsoOnlyScreen -> {
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginSsoOnlyFragment2::class.java,
|
||||
option = commonOption)
|
||||
}
|
||||
is LoginViewEvents2.OnWebLoginError -> onWebLoginError(event)
|
||||
is LoginViewEvents2.OpenResetPasswordScreen ->
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginResetPasswordFragment2::class.java,
|
||||
option = commonOption)
|
||||
is LoginViewEvents2.OnResetPasswordSendThreePidDone -> {
|
||||
supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, POP_BACK_STACK_EXCLUSIVE)
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginResetPasswordMailConfirmationFragment2::class.java,
|
||||
option = commonOption)
|
||||
}
|
||||
is LoginViewEvents2.OnResetPasswordMailConfirmationSuccess -> {
|
||||
supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, POP_BACK_STACK_EXCLUSIVE)
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginResetPasswordSuccessFragment2::class.java,
|
||||
option = commonOption)
|
||||
}
|
||||
@ -202,37 +202,37 @@ open class LoginActivity2 : VectorBaseActivity<ActivityLoginBinding>(), ToolbarC
|
||||
supportFragmentManager.popBackStack(FRAGMENT_LOGIN_TAG, POP_BACK_STACK_EXCLUSIVE)
|
||||
}
|
||||
is LoginViewEvents2.OnSendEmailSuccess ->
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginWaitForEmailFragment2::class.java,
|
||||
LoginWaitForEmailFragmentArgument(event.email),
|
||||
tag = FRAGMENT_REGISTRATION_STAGE_TAG,
|
||||
option = commonOption)
|
||||
is LoginViewEvents2.OpenSigninPasswordScreen -> {
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginFragmentSigninPassword2::class.java,
|
||||
tag = FRAGMENT_LOGIN_TAG,
|
||||
option = commonOption)
|
||||
}
|
||||
is LoginViewEvents2.OpenSignupPasswordScreen -> {
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginFragmentSignupPassword2::class.java,
|
||||
tag = FRAGMENT_REGISTRATION_STAGE_TAG,
|
||||
option = commonOption)
|
||||
}
|
||||
is LoginViewEvents2.OpenSignUpChooseUsernameScreen -> {
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginFragmentSignupUsername2::class.java,
|
||||
tag = FRAGMENT_REGISTRATION_STAGE_TAG,
|
||||
option = commonOption)
|
||||
}
|
||||
is LoginViewEvents2.OpenSignInWithAnythingScreen -> {
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginFragmentToAny2::class.java,
|
||||
tag = FRAGMENT_LOGIN_TAG,
|
||||
option = commonOption)
|
||||
}
|
||||
is LoginViewEvents2.OnSendMsisdnSuccess ->
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginGenericTextInputFormFragment2::class.java,
|
||||
LoginGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.ConfirmMsisdn, true, event.msisdn),
|
||||
tag = FRAGMENT_REGISTRATION_STAGE_TAG,
|
||||
@ -257,7 +257,7 @@ open class LoginActivity2 : VectorBaseActivity<ActivityLoginBinding>(), ToolbarC
|
||||
if (event.newAccount) {
|
||||
// Propose to set avatar and display name
|
||||
// Back on this Fragment will finish the Activity
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
AccountCreatedFragment::class.java,
|
||||
option = commonOption)
|
||||
} else {
|
||||
@ -312,7 +312,7 @@ open class LoginActivity2 : VectorBaseActivity<ActivityLoginBinding>(), ToolbarC
|
||||
.setTitle(R.string.app_name)
|
||||
.setMessage(getString(R.string.login_registration_not_supported))
|
||||
.setPositiveButton(R.string.yes) { _, _ ->
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginWebFragment2::class.java,
|
||||
option = commonOption)
|
||||
}
|
||||
@ -325,7 +325,7 @@ open class LoginActivity2 : VectorBaseActivity<ActivityLoginBinding>(), ToolbarC
|
||||
.setTitle(R.string.app_name)
|
||||
.setMessage(getString(R.string.login_mode_not_supported, supportedTypes.joinToString { "'$it'" }))
|
||||
.setPositiveButton(R.string.yes) { _, _ ->
|
||||
addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginWebFragment2::class.java,
|
||||
option = commonOption)
|
||||
}
|
||||
@ -355,22 +355,22 @@ open class LoginActivity2 : VectorBaseActivity<ActivityLoginBinding>(), ToolbarC
|
||||
supportFragmentManager.popBackStack(FRAGMENT_REGISTRATION_STAGE_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE)
|
||||
|
||||
when (stage) {
|
||||
is Stage.ReCaptcha -> addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
is Stage.ReCaptcha -> addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginCaptchaFragment2::class.java,
|
||||
LoginCaptchaFragmentArgument(stage.publicKey),
|
||||
tag = FRAGMENT_REGISTRATION_STAGE_TAG,
|
||||
option = commonOption)
|
||||
is Stage.Email -> addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
is Stage.Email -> addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginGenericTextInputFormFragment2::class.java,
|
||||
LoginGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.SetEmail, stage.mandatory),
|
||||
tag = FRAGMENT_REGISTRATION_STAGE_TAG,
|
||||
option = commonOption)
|
||||
is Stage.Msisdn -> addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
is Stage.Msisdn -> addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginGenericTextInputFormFragment2::class.java,
|
||||
LoginGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.SetMsisdn, stage.mandatory),
|
||||
tag = FRAGMENT_REGISTRATION_STAGE_TAG,
|
||||
option = commonOption)
|
||||
is Stage.Terms -> addFragmentToBackstack(R.id.loginFragmentContainer,
|
||||
is Stage.Terms -> addFragmentToBackstack(views.loginFragmentContainer,
|
||||
LoginTermsFragment2::class.java,
|
||||
LoginTermsFragmentArgument(stage.policies.toLocalizedLoginTerms(getString(R.string.resources_language))),
|
||||
tag = FRAGMENT_REGISTRATION_STAGE_TAG,
|
||||
|
@ -21,7 +21,6 @@ import android.content.Intent
|
||||
import com.airbnb.mvrx.Mavericks
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.addFragment
|
||||
import im.vector.app.core.platform.ToolbarConfigurable
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
@ -45,7 +44,7 @@ class PinActivity : VectorBaseActivity<ActivitySimpleBinding>(), ToolbarConfigur
|
||||
override fun initUiAndData() {
|
||||
if (isFirstCreation()) {
|
||||
val fragmentArgs: PinArgs = intent?.extras?.getParcelable(Mavericks.KEY_ARG) ?: return
|
||||
addFragment(R.id.simpleFragmentContainer, PinFragment::class.java, fragmentArgs)
|
||||
addFragment(views.simpleFragmentContainer, PinFragment::class.java, fragmentArgs)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,6 @@ import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.addFragment
|
||||
import im.vector.app.core.platform.SimpleFragmentActivity
|
||||
|
||||
@ -36,7 +35,7 @@ class CreatePollActivity : SimpleFragmentActivity() {
|
||||
|
||||
if (isFirstCreation()) {
|
||||
addFragment(
|
||||
R.id.container,
|
||||
views.container,
|
||||
CreatePollFragment::class.java,
|
||||
createPollArgs
|
||||
)
|
||||
|
@ -104,7 +104,7 @@ class PopupAlertManager @Inject constructor() {
|
||||
// we want to remove existing popup on previous activity and display it on new one
|
||||
if (currentAlerter != null) {
|
||||
weakCurrentActivity?.get()?.let {
|
||||
Alerter.clearCurrent(it, null)
|
||||
Alerter.clearCurrent(it, null, null)
|
||||
if (currentAlerter?.isLight == false) {
|
||||
setLightStatusBar()
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ import com.google.zxing.BarcodeFormat
|
||||
import com.google.zxing.Result
|
||||
import com.google.zxing.ResultMetadataType
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.replaceFragment
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.databinding.ActivitySimpleBinding
|
||||
@ -39,7 +38,7 @@ class QrCodeScannerActivity : VectorBaseActivity<ActivitySimpleBinding>() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
if (isFirstCreation()) {
|
||||
replaceFragment(R.id.simpleFragmentContainer, QrCodeScannerFragment::class.java)
|
||||
replaceFragment(views.simpleFragmentContainer, QrCodeScannerFragment::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,6 @@ import androidx.lifecycle.lifecycleScope
|
||||
import com.airbnb.mvrx.viewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.addFragment
|
||||
import im.vector.app.core.extensions.addFragmentToBackstack
|
||||
import im.vector.app.core.extensions.popBackstack
|
||||
@ -66,14 +65,14 @@ class RoomDirectoryActivity : VectorBaseActivity<ActivitySimpleBinding>(), Matri
|
||||
// Transmit the filter to the CreateRoomFragment
|
||||
withState(roomDirectoryViewModel) {
|
||||
addFragmentToBackstack(
|
||||
R.id.simpleFragmentContainer,
|
||||
views.simpleFragmentContainer,
|
||||
CreateRoomFragment::class.java,
|
||||
CreateRoomArgs(it.currentFilter)
|
||||
)
|
||||
}
|
||||
}
|
||||
is RoomDirectorySharedAction.ChangeProtocol ->
|
||||
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomDirectoryPickerFragment::class.java)
|
||||
addFragmentToBackstack(views.simpleFragmentContainer, RoomDirectoryPickerFragment::class.java)
|
||||
is RoomDirectorySharedAction.Close -> finish()
|
||||
}
|
||||
}
|
||||
@ -82,7 +81,7 @@ class RoomDirectoryActivity : VectorBaseActivity<ActivitySimpleBinding>(), Matri
|
||||
|
||||
override fun initUiAndData() {
|
||||
if (isFirstCreation()) {
|
||||
addFragment(R.id.simpleFragmentContainer, PublicRoomsFragment::class.java)
|
||||
addFragment(views.simpleFragmentContainer, PublicRoomsFragment::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,6 @@ import android.os.Bundle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.addFragment
|
||||
import im.vector.app.core.platform.ToolbarConfigurable
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
@ -51,7 +50,7 @@ class CreateRoomActivity : VectorBaseActivity<ActivitySimpleBinding>(), ToolbarC
|
||||
override fun initUiAndData() {
|
||||
if (isFirstCreation()) {
|
||||
addFragment(
|
||||
R.id.simpleFragmentContainer,
|
||||
views.simpleFragmentContainer,
|
||||
CreateRoomFragment::class.java,
|
||||
CreateRoomArgs(
|
||||
intent?.getStringExtra(INITIAL_NAME) ?: "",
|
||||
|
@ -21,7 +21,6 @@ import android.content.Intent
|
||||
import android.os.Parcelable
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.addFragment
|
||||
import im.vector.app.core.platform.ToolbarConfigurable
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
@ -94,9 +93,9 @@ class RoomPreviewActivity : VectorBaseActivity<ActivitySimpleBinding>(), Toolbar
|
||||
// TODO Room preview: Note: M does not recommend to use /events anymore, so for now we just display the room preview
|
||||
// TODO the same way if it was not world readable
|
||||
Timber.d("just display the room preview the same way if it was not world readable")
|
||||
addFragment(R.id.simpleFragmentContainer, RoomPreviewNoPreviewFragment::class.java, args)
|
||||
addFragment(views.simpleFragmentContainer, RoomPreviewNoPreviewFragment::class.java, args)
|
||||
} else {
|
||||
addFragment(R.id.simpleFragmentContainer, RoomPreviewNoPreviewFragment::class.java, args)
|
||||
addFragment(views.simpleFragmentContainer, RoomPreviewNoPreviewFragment::class.java, args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,6 @@ import com.airbnb.mvrx.Mavericks
|
||||
import com.airbnb.mvrx.viewModel
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.addFragment
|
||||
import im.vector.app.core.platform.ToolbarConfigurable
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
@ -54,7 +53,7 @@ class RoomMemberProfileActivity :
|
||||
override fun initUiAndData() {
|
||||
if (isFirstCreation()) {
|
||||
val fragmentArgs: RoomMemberProfileArgs = intent?.extras?.getParcelable(Mavericks.KEY_ARG) ?: return
|
||||
addFragment(R.id.simpleFragmentContainer, RoomMemberProfileFragment::class.java, fragmentArgs)
|
||||
addFragment(views.simpleFragmentContainer, RoomMemberProfileFragment::class.java, fragmentArgs)
|
||||
}
|
||||
|
||||
requireActiveMembershipViewModel.observeViewEvents {
|
||||
|
@ -25,7 +25,6 @@ import com.airbnb.mvrx.Mavericks
|
||||
import com.airbnb.mvrx.viewModel
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.addFragment
|
||||
import im.vector.app.core.extensions.addFragmentToBackstack
|
||||
import im.vector.app.core.extensions.exhaustive
|
||||
@ -86,13 +85,13 @@ class RoomProfileActivity :
|
||||
if (isFirstCreation()) {
|
||||
when (intent?.extras?.getInt(EXTRA_DIRECT_ACCESS, EXTRA_DIRECT_ACCESS_ROOM_ROOT)) {
|
||||
EXTRA_DIRECT_ACCESS_ROOM_SETTINGS -> {
|
||||
addFragment(R.id.simpleFragmentContainer, RoomProfileFragment::class.java, roomProfileArgs)
|
||||
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomSettingsFragment::class.java, roomProfileArgs)
|
||||
addFragment(views.simpleFragmentContainer, RoomProfileFragment::class.java, roomProfileArgs)
|
||||
addFragmentToBackstack(views.simpleFragmentContainer, RoomSettingsFragment::class.java, roomProfileArgs)
|
||||
}
|
||||
EXTRA_DIRECT_ACCESS_ROOM_MEMBERS -> {
|
||||
addFragment(R.id.simpleFragmentContainer, RoomMemberListFragment::class.java, roomProfileArgs)
|
||||
addFragment(views.simpleFragmentContainer, RoomMemberListFragment::class.java, roomProfileArgs)
|
||||
}
|
||||
else -> addFragment(R.id.simpleFragmentContainer, RoomProfileFragment::class.java, roomProfileArgs)
|
||||
else -> addFragment(views.simpleFragmentContainer, RoomProfileFragment::class.java, roomProfileArgs)
|
||||
}
|
||||
}
|
||||
sharedActionViewModel
|
||||
@ -132,31 +131,31 @@ class RoomProfileActivity :
|
||||
}
|
||||
|
||||
private fun openRoomUploads() {
|
||||
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomUploadsFragment::class.java, roomProfileArgs)
|
||||
addFragmentToBackstack(views.simpleFragmentContainer, RoomUploadsFragment::class.java, roomProfileArgs)
|
||||
}
|
||||
|
||||
private fun openRoomSettings() {
|
||||
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomSettingsFragment::class.java, roomProfileArgs)
|
||||
addFragmentToBackstack(views.simpleFragmentContainer, RoomSettingsFragment::class.java, roomProfileArgs)
|
||||
}
|
||||
|
||||
private fun openRoomAlias() {
|
||||
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomAliasFragment::class.java, roomProfileArgs)
|
||||
addFragmentToBackstack(views.simpleFragmentContainer, RoomAliasFragment::class.java, roomProfileArgs)
|
||||
}
|
||||
|
||||
private fun openRoomPermissions() {
|
||||
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomPermissionsFragment::class.java, roomProfileArgs)
|
||||
addFragmentToBackstack(views.simpleFragmentContainer, RoomPermissionsFragment::class.java, roomProfileArgs)
|
||||
}
|
||||
|
||||
private fun openRoomMembers() {
|
||||
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomMemberListFragment::class.java, roomProfileArgs)
|
||||
addFragmentToBackstack(views.simpleFragmentContainer, RoomMemberListFragment::class.java, roomProfileArgs)
|
||||
}
|
||||
|
||||
private fun openBannedRoomMembers() {
|
||||
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomBannedMemberListFragment::class.java, roomProfileArgs)
|
||||
addFragmentToBackstack(views.simpleFragmentContainer, RoomBannedMemberListFragment::class.java, roomProfileArgs)
|
||||
}
|
||||
|
||||
private fun openRoomNotificationSettings() {
|
||||
addFragmentToBackstack(R.id.simpleFragmentContainer, RoomNotificationSettingsFragment::class.java, roomProfileArgs)
|
||||
addFragmentToBackstack(views.simpleFragmentContainer, RoomNotificationSettingsFragment::class.java, roomProfileArgs)
|
||||
}
|
||||
|
||||
override fun configure(toolbar: MaterialToolbar) {
|
||||
|
@ -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<FragmentMatrixProfileBinding>(),
|
||||
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() {
|
||||
|
@ -61,7 +61,7 @@ class RoomJoinRuleActivity : VectorBaseActivity<ActivitySimpleBinding>() {
|
||||
roomProfileArgs = intent?.extras?.getParcelable(Mavericks.KEY_ARG) ?: return
|
||||
if (isFirstCreation()) {
|
||||
addFragment(
|
||||
R.id.simpleFragmentContainer,
|
||||
views.simpleFragmentContainer,
|
||||
RoomJoinRuleFragment::class.java,
|
||||
roomProfileArgs
|
||||
)
|
||||
@ -121,7 +121,7 @@ class RoomJoinRuleActivity : VectorBaseActivity<ActivitySimpleBinding>() {
|
||||
supportFragmentManager.commitTransaction {
|
||||
setCustomAnimations(R.anim.fade_in, R.anim.fade_out, R.anim.fade_in, R.anim.fade_out)
|
||||
val tag = RoomJoinRuleChooseRestrictedFragment::class.simpleName
|
||||
replace(R.id.simpleFragmentContainer,
|
||||
replace(views.simpleFragmentContainer.id,
|
||||
RoomJoinRuleChooseRestrictedFragment::class.java,
|
||||
this@RoomJoinRuleActivity.roomProfileArgs.toMvRxBundle(),
|
||||
tag
|
||||
|
@ -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"
|
||||
|
@ -70,25 +70,25 @@ class VectorSettingsActivity : VectorBaseActivity<ActivityVectorSettingsBinding>
|
||||
|
||||
when (val payload = readPayload<SettingsActivityPayload>(SettingsActivityPayload.Root)) {
|
||||
SettingsActivityPayload.General ->
|
||||
replaceFragment(R.id.vector_settings_page, VectorSettingsGeneralFragment::class.java, null, FRAGMENT_TAG)
|
||||
replaceFragment(views.vectorSettingsPage, VectorSettingsGeneralFragment::class.java, null, FRAGMENT_TAG)
|
||||
SettingsActivityPayload.AdvancedSettings ->
|
||||
replaceFragment(R.id.vector_settings_page, VectorSettingsAdvancedSettingsFragment::class.java, null, FRAGMENT_TAG)
|
||||
replaceFragment(views.vectorSettingsPage, VectorSettingsAdvancedSettingsFragment::class.java, null, FRAGMENT_TAG)
|
||||
SettingsActivityPayload.SecurityPrivacy ->
|
||||
replaceFragment(R.id.vector_settings_page, VectorSettingsSecurityPrivacyFragment::class.java, null, FRAGMENT_TAG)
|
||||
replaceFragment(views.vectorSettingsPage, VectorSettingsSecurityPrivacyFragment::class.java, null, FRAGMENT_TAG)
|
||||
SettingsActivityPayload.SecurityPrivacyManageSessions ->
|
||||
replaceFragment(R.id.vector_settings_page,
|
||||
replaceFragment(views.vectorSettingsPage,
|
||||
VectorSettingsDevicesFragment::class.java,
|
||||
null,
|
||||
FRAGMENT_TAG)
|
||||
SettingsActivityPayload.Notifications -> {
|
||||
requestHighlightPreferenceKeyOnResume(VectorPreferences.SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY)
|
||||
replaceFragment(R.id.vector_settings_page, VectorSettingsNotificationPreferenceFragment::class.java, null, FRAGMENT_TAG)
|
||||
replaceFragment(views.vectorSettingsPage, VectorSettingsNotificationPreferenceFragment::class.java, null, FRAGMENT_TAG)
|
||||
}
|
||||
is SettingsActivityPayload.DiscoverySettings -> {
|
||||
replaceFragment(R.id.vector_settings_page, DiscoverySettingsFragment::class.java, payload, FRAGMENT_TAG)
|
||||
replaceFragment(views.vectorSettingsPage, DiscoverySettingsFragment::class.java, payload, FRAGMENT_TAG)
|
||||
}
|
||||
else ->
|
||||
replaceFragment(R.id.vector_settings_page, VectorSettingsRootFragment::class.java, null, FRAGMENT_TAG)
|
||||
replaceFragment(views.vectorSettingsPage, VectorSettingsRootFragment::class.java, null, FRAGMENT_TAG)
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ class VectorSettingsActivity : VectorBaseActivity<ActivityVectorSettingsBinding>
|
||||
// Replace the existing Fragment with the new Fragment
|
||||
supportFragmentManager.beginTransaction()
|
||||
.setCustomAnimations(R.anim.right_in, R.anim.fade_out, R.anim.fade_in, R.anim.right_out)
|
||||
.replace(R.id.vector_settings_page, oFragment, pref.title.toString())
|
||||
.replace(views.vectorSettingsPage.id, oFragment, pref.title.toString())
|
||||
.addToBackStack(null)
|
||||
.commit()
|
||||
return true
|
||||
@ -154,7 +154,7 @@ class VectorSettingsActivity : VectorBaseActivity<ActivityVectorSettingsBinding>
|
||||
fun <T : Fragment> navigateTo(fragmentClass: Class<T>, arguments: Bundle? = null) {
|
||||
supportFragmentManager.beginTransaction()
|
||||
.setCustomAnimations(R.anim.right_in, R.anim.fade_out, R.anim.fade_in, R.anim.right_out)
|
||||
.replace(R.id.vector_settings_page, fragmentClass, arguments)
|
||||
.replace(views.vectorSettingsPage.id, fragmentClass, arguments)
|
||||
.addToBackStack(null)
|
||||
.commit()
|
||||
}
|
||||
|
@ -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<VectorPreference>(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<VectorPreference>(APP_INFO_LINK_PREFERENCE_KEY)!!
|
||||
.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
@ -76,44 +83,6 @@ class VectorSettingsHelpAboutFragment @Inject constructor(
|
||||
// olm version
|
||||
findPreference<VectorPreference>(VectorPreferences.SETTINGS_OLM_VERSION_PREFERENCE_KEY)!!
|
||||
.summary = session.cryptoService().getCryptoVersion(requireContext(), false)
|
||||
|
||||
// copyright
|
||||
findPreference<VectorPreference>(VectorPreferences.SETTINGS_COPYRIGHT_PREFERENCE_KEY)!!
|
||||
.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
openUrlInChromeCustomTab(requireContext(), null, VectorSettingsUrls.COPYRIGHT)
|
||||
false
|
||||
}
|
||||
|
||||
// terms & conditions
|
||||
findPreference<VectorPreference>(VectorPreferences.SETTINGS_APP_TERM_CONDITIONS_PREFERENCE_KEY)!!
|
||||
.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
openUrlInChromeCustomTab(requireContext(), null, VectorSettingsUrls.TAC)
|
||||
false
|
||||
}
|
||||
|
||||
// privacy policy
|
||||
findPreference<VectorPreference>(VectorPreferences.SETTINGS_PRIVACY_POLICY_PREFERENCE_KEY)!!
|
||||
.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
openUrlInChromeCustomTab(requireContext(), null, VectorSettingsUrls.PRIVACY_POLICY)
|
||||
false
|
||||
}
|
||||
|
||||
// third party notice
|
||||
findPreference<VectorPreference>(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<VectorPreference>(VectorPreferences.SETTINGS_OTHER_THIRD_PARTY_NOTICES_PREFERENCE_KEY)!!
|
||||
.onPreferenceClickListener = Preference.OnPreferenceClickListener {
|
||||
// See https://developers.google.com/android/guides/opensource
|
||||
openOssLicensesMenuActivity(requireActivity())
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -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"
|
||||
|
@ -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<ServerPolicy> {
|
||||
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)
|
||||
)
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
@ -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<LegalsState>() {
|
||||
|
||||
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<ServerAndPolicies?>) {
|
||||
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<ServerPolicy>) {
|
||||
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()
|
||||
}
|
||||
}
|
@ -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<FragmentGenericRecyclerBinding>(),
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
@ -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<ServerAndPolicies?> = Uninitialized,
|
||||
val hasIdentityServer: Boolean = false,
|
||||
val identityServer: Async<ServerAndPolicies?> = Uninitialized
|
||||
) : MavericksState
|
@ -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<LegalsState, LegalsAction, EmptyViewEvents>(initialState) {
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : MavericksAssistedViewModelFactory<LegalsViewModel, LegalsState> {
|
||||
override fun create(initialState: LegalsState): LegalsViewModel
|
||||
}
|
||||
|
||||
companion object : MavericksViewModelFactory<LegalsViewModel, LegalsState> 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)) } }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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<Preference>(VectorPreferences.SETTINGS_NOTIFICATION_ADVANCED_PREFERENCE_KEY)?.isVisible = !isNotificationSettingsV2Enabled
|
||||
findPreference<Preference>(VectorPreferences.SETTINGS_NOTIFICATION_DEFAULT_PREFERENCE_KEY)?.isVisible = isNotificationSettingsV2Enabled
|
||||
findPreference<Preference>(VectorPreferences.SETTINGS_NOTIFICATION_KEYWORD_AND_MENTIONS_PREFERENCE_KEY)?.isVisible = isNotificationSettingsV2Enabled
|
||||
findPreference<Preference>(VectorPreferences.SETTINGS_NOTIFICATION_OTHER_PREFERENCE_KEY)?.isVisible = isNotificationSettingsV2Enabled
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
activeSessionHolder.getSafeActiveSession()?.refreshPushers()
|
||||
|
@ -18,7 +18,6 @@ package im.vector.app.features.share
|
||||
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.addFragment
|
||||
import im.vector.app.core.platform.ToolbarConfigurable
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
@ -33,7 +32,7 @@ class IncomingShareActivity : VectorBaseActivity<ActivitySimpleBinding>(), Toolb
|
||||
|
||||
override fun initUiAndData() {
|
||||
if (isFirstCreation()) {
|
||||
addFragment(R.id.simpleFragmentContainer, IncomingShareFragment::class.java)
|
||||
addFragment(views.simpleFragmentContainer, IncomingShareFragment::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ class SoftLogoutActivity : LoginActivity() {
|
||||
}
|
||||
|
||||
override fun addFirstFragment() {
|
||||
replaceFragment(R.id.loginFragmentContainer, SoftLogoutFragment::class.java)
|
||||
replaceFragment(views.loginFragmentContainer, SoftLogoutFragment::class.java)
|
||||
}
|
||||
|
||||
private fun updateWithState(softLogoutViewState: SoftLogoutViewState) {
|
||||
|
@ -89,7 +89,7 @@ class SoftLogoutActivity2 : LoginActivity2() {
|
||||
}
|
||||
|
||||
override fun addFirstFragment() {
|
||||
replaceFragment(R.id.loginFragmentContainer, SoftLogoutFragment::class.java)
|
||||
replaceFragment(views.loginFragmentContainer, SoftLogoutFragment::class.java)
|
||||
}
|
||||
|
||||
private fun updateWithState(softLogoutViewState: SoftLogoutViewState) {
|
||||
|
@ -123,7 +123,7 @@ class SpaceCreationActivity : SimpleFragmentActivity() {
|
||||
val frag = supportFragmentManager.findFragmentByTag(fragmentClass.name) ?: createFragment(fragmentClass)
|
||||
supportFragmentManager.beginTransaction()
|
||||
.setCustomAnimations(R.anim.fade_in, R.anim.fade_out, R.anim.fade_in, R.anim.fade_out)
|
||||
.replace(R.id.container,
|
||||
.replace(views.container.id,
|
||||
frag,
|
||||
fragmentClass.name
|
||||
)
|
||||
|
@ -25,7 +25,7 @@ import com.airbnb.mvrx.Mavericks
|
||||
import com.airbnb.mvrx.viewModel
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.commitTransaction
|
||||
import im.vector.app.core.extensions.replaceFragment
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.databinding.ActivitySimpleBinding
|
||||
import im.vector.app.features.matrixto.MatrixToBottomSheet
|
||||
@ -65,17 +65,12 @@ class SpaceExploreActivity : VectorBaseActivity<ActivitySimpleBinding>(), Matrix
|
||||
supportFragmentManager.registerFragmentLifecycleCallbacks(fragmentLifecycleCallbacks, false)
|
||||
|
||||
if (isFirstCreation()) {
|
||||
val simpleName = SpaceDirectoryFragment::class.java.simpleName
|
||||
val args = intent?.getParcelableExtra<SpaceDirectoryArgs>(Mavericks.KEY_ARG)
|
||||
if (supportFragmentManager.findFragmentByTag(simpleName) == null) {
|
||||
supportFragmentManager.commitTransaction {
|
||||
replace(R.id.simpleFragmentContainer,
|
||||
SpaceDirectoryFragment::class.java,
|
||||
Bundle().apply { this.putParcelable(Mavericks.KEY_ARG, args) },
|
||||
simpleName
|
||||
)
|
||||
}
|
||||
}
|
||||
replaceFragment(
|
||||
views.simpleFragmentContainer,
|
||||
SpaceDirectoryFragment::class.java,
|
||||
args
|
||||
)
|
||||
}
|
||||
|
||||
sharedViewModel.observeViewEvents {
|
||||
|
@ -22,8 +22,7 @@ import android.os.Bundle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.airbnb.mvrx.Mavericks
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.extensions.commitTransaction
|
||||
import im.vector.app.core.extensions.replaceFragment
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
import im.vector.app.databinding.ActivitySimpleBinding
|
||||
import im.vector.app.features.spaces.preview.SpacePreviewArgs
|
||||
@ -45,26 +44,21 @@ class SpacePreviewActivity : VectorBaseActivity<ActivitySimpleBinding>() {
|
||||
.stream()
|
||||
.onEach { action ->
|
||||
when (action) {
|
||||
SpacePreviewSharedAction.DismissAction -> finish()
|
||||
SpacePreviewSharedAction.ShowModalLoading -> showWaitingView()
|
||||
SpacePreviewSharedAction.HideModalLoading -> hideWaitingView()
|
||||
SpacePreviewSharedAction.DismissAction -> finish()
|
||||
SpacePreviewSharedAction.ShowModalLoading -> showWaitingView()
|
||||
SpacePreviewSharedAction.HideModalLoading -> hideWaitingView()
|
||||
is SpacePreviewSharedAction.ShowErrorMessage -> action.error?.let { showSnackbar(it) }
|
||||
}
|
||||
}
|
||||
.launchIn(lifecycleScope)
|
||||
|
||||
if (isFirstCreation()) {
|
||||
val simpleName = SpacePreviewFragment::class.java.simpleName
|
||||
val args = intent?.getParcelableExtra<SpacePreviewArgs>(Mavericks.KEY_ARG)
|
||||
if (supportFragmentManager.findFragmentByTag(simpleName) == null) {
|
||||
supportFragmentManager.commitTransaction {
|
||||
replace(R.id.simpleFragmentContainer,
|
||||
SpacePreviewFragment::class.java,
|
||||
Bundle().apply { this.putParcelable(Mavericks.KEY_ARG, args) },
|
||||
simpleName
|
||||
)
|
||||
}
|
||||
}
|
||||
replaceFragment(
|
||||
views.simpleFragmentContainer,
|
||||
SpacePreviewFragment::class.java,
|
||||
args
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,8 +31,8 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.error.ErrorFormatter
|
||||
import im.vector.app.core.extensions.commitTransaction
|
||||
import im.vector.app.core.extensions.hideKeyboard
|
||||
import im.vector.app.core.extensions.replaceFragment
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.core.platform.ToolbarConfigurable
|
||||
import im.vector.app.core.platform.VectorBaseActivity
|
||||
@ -69,17 +69,11 @@ class SpaceLeaveAdvancedActivity : VectorBaseActivity<ActivitySimpleLoadingBindi
|
||||
val args = intent?.getParcelableExtra<SpaceBottomSheetSettingsArgs>(Mavericks.KEY_ARG)
|
||||
|
||||
if (isFirstCreation()) {
|
||||
val simpleName = SpaceLeaveAdvancedFragment::class.java.simpleName
|
||||
if (supportFragmentManager.findFragmentByTag(simpleName) == null) {
|
||||
supportFragmentManager.commitTransaction {
|
||||
replace(
|
||||
R.id.simpleFragmentContainer,
|
||||
SpaceLeaveAdvancedFragment::class.java,
|
||||
Bundle().apply { this.putParcelable(Mavericks.KEY_ARG, args) },
|
||||
simpleName
|
||||
)
|
||||
}
|
||||
}
|
||||
replaceFragment(
|
||||
views.simpleFragmentContainer,
|
||||
SpaceLeaveAdvancedFragment::class.java,
|
||||
args
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user