Bug fixes, improvements, and significant changes to the conversation menu & info

Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
Mario Danic 2019-10-20 01:54:28 +02:00
parent 59030fe9a5
commit bf3d5c2c65
28 changed files with 932 additions and 463 deletions

View File

@ -23,10 +23,10 @@ apply plugin: 'findbugs'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply plugin: 'realm-android'
def taskRequest = getGradle().getStartParameter().getTaskRequests().toString() def taskRequest = getGradle().getStartParameter().getTaskRequests().toString()
if (taskRequest.contains("Gplay") || taskRequest.contains("findbugs") || taskRequest.contains("lint")) { if (taskRequest.contains("Gplay") || taskRequest.contains("findbugs") ||
taskRequest.contains("lint")) {
apply from: 'gplay.gradle' apply from: 'gplay.gradle'
} }
@ -40,8 +40,8 @@ android {
targetSdkVersion 29 targetSdkVersion 29
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
versionCode 119 versionCode 120
versionName "7.0.5" versionName "8.0.0alpha1"
flavorDimensions "default" flavorDimensions "default"
renderscriptTargetApi 19 renderscriptTargetApi 19
@ -54,7 +54,6 @@ android {
// used for f-droid // used for f-droid
generic generic
gplay gplay
} }
// Enabling multidex support. // Enabling multidex support.
@ -140,20 +139,19 @@ android {
} }
ext { ext {
work_version = "1.0.1" work_version = "2.3.0-alpha02"
koin_version = "2.1.0-alpha-1" koin_version = "2.1.0-alpha-1"
lifecycle_version = "2.1.0" lifecycle_version = "2.2.0-beta01"
coil_version = "0.7.0" coil_version = "0.7.0"
room_version = "2.2.0"
} }
configurations.all { configurations.all {
exclude group: 'com.google.firebase', module: 'firebase-core' exclude group: 'com.google.firebase', module: 'firebase-core'
exclude group: 'com.google.firebase', module: 'firebase-analytics' exclude group: 'com.google.firebase', module: 'firebase-analytics'
exclude group: 'com.google.firebase', module: 'firebase-measurement-connector' exclude group: 'com.google.firebase', module: 'firebase-measurement-connector'
} }
dependencies { dependencies {
implementation fileTree(include: ['*'], dir: 'libs') implementation fileTree(include: ['*'], dir: 'libs')
@ -173,19 +171,44 @@ dependencies {
implementation "com.github.stateless4j:stateless4j:2.6.0" implementation "com.github.stateless4j:stateless4j:2.6.0"
// ViewModel and LiveData // ViewModel and LiveData
implementation "androidx.core:core-ktx:1.1.0"
implementation "androidx.sqlite:sqlite-ktx:2.0.1"
implementation "androidx.collection:collection-ktx:1.1.0"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0-beta01" implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0-beta01" implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0-beta01" implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// optional - ReactiveStreams support for LiveData // optional - ReactiveStreams support for LiveData
implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version" // For Kotlin use lifecycle-reactivestreams-ktx implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version"
// optional - Test helpers for LiveData // optional - Test helpers for LiveData
testImplementation "androidx.arch.core:core-testing:$lifecycle_version" testImplementation "androidx.arch.core:core-testing:2.1.0"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version" // For Kotlin use kapt instead of
// annotationProcessor
// optional - Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"
// optional - RxJava support for Room
implementation "androidx.room:room-rxjava2:$room_version"
// optional - Guava support for Room, including Optional and ListenableFuture
//implementation "androidx.room:room-guava:$room_version"
// Test helpers
testImplementation "androidx.room:room-testing:$room_version"
implementation "androidx.work:work-runtime-ktx:$work_version"
implementation "androidx.work:work-rxjava2:$work_version"
androidTestImplementation "androidx.work:work-testing:$work_version"
implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'com.google.android.material:material:1.1.0-beta01' implementation 'com.google.android.material:material:1.1.0-beta01'
@ -193,10 +216,7 @@ dependencies {
implementation 'com.github.vanniktech:Emoji:0.6.0' implementation 'com.github.vanniktech:Emoji:0.6.0'
implementation group: 'androidx.emoji', name: 'emoji-bundled', version: '1.0.0' implementation group: 'androidx.emoji', name: 'emoji-bundled', version: '1.0.0'
implementation 'org.michaelevans.colorart:library:0.0.3' implementation 'org.michaelevans.colorart:library:0.0.3'
implementation "android.arch.work:work-runtime:${work_version}"
implementation "android.arch.work:work-rxjava2:${work_version}"
implementation 'com.google.android:flexbox:1.1.0' implementation 'com.google.android:flexbox:1.1.0'
androidTestImplementation "android.arch.work:work-testing:${work_version}"
implementation 'com.gitlab.bitfireAT:dav4jvm:ee66e8e5' implementation 'com.gitlab.bitfireAT:dav4jvm:ee66e8e5'
implementation 'org.conscrypt:conscrypt-android:2.2.1' implementation 'org.conscrypt:conscrypt-android:2.2.1'
@ -231,6 +251,7 @@ dependencies {
implementation 'com.google.dagger:dagger:2.24' implementation 'com.google.dagger:dagger:2.24'
kapt 'com.google.dagger:dagger-compiler:2.24' kapt 'com.google.dagger:dagger-compiler:2.24'
kapt 'com.google.dagger:dagger-android-processor:2.24'
implementation 'com.github.lukaspili.autodagger2:autodagger2:1.1' implementation 'com.github.lukaspili.autodagger2:autodagger2:1.1'
kapt 'com.github.lukaspili.autodagger2:autodagger2-compiler:1.1' kapt 'com.github.lukaspili.autodagger2:autodagger2-compiler:1.1'
compileOnly 'javax.annotation:jsr250-api:1.0' compileOnly 'javax.annotation:jsr250-api:1.0'
@ -258,7 +279,7 @@ dependencies {
implementation 'me.zhanghai.android.effortlesspermissions:library:1.1.0' implementation 'me.zhanghai.android.effortlesspermissions:library:1.1.0'
implementation 'org.apache.commons:commons-lang3:3.9' implementation 'org.apache.commons:commons-lang3:3.9'
implementation 'com.github.wooplr:Spotlight:1.3' implementation 'com.github.wooplr:Spotlight:1.3'
implementation('com.github.mario:chatkit:a183142049', { implementation('com.github.mario:chatkit:c6a6176729', {
exclude group: 'com.facebook.fresco' exclude group: 'com.facebook.fresco'
}) })
@ -278,7 +299,6 @@ dependencies {
implementation 'com.novoda:merlin:1.2.1' implementation 'com.novoda:merlin:1.2.1'
implementation 'com.github.Kennyc1012:BottomSheet:2.4.1'
implementation 'com.github.mario:PopupBubble:a365177d96' implementation 'com.github.mario:PopupBubble:a365177d96'
implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1' implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
implementation 'eu.medsea.mimeutil:mime-util:2.1.3' implementation 'eu.medsea.mimeutil:mime-util:2.1.3'
@ -297,11 +317,11 @@ dependencies {
testImplementation 'org.powermock:powermock-module-junit4:2.0.2' testImplementation 'org.powermock:powermock-module-junit4:2.0.2'
testImplementation 'org.powermock:powermock-api-mockito2:2.0.2' testImplementation 'org.powermock:powermock-api-mockito2:2.0.2'
androidTestImplementation('androidx.test.espresso:espresso-core:3.3.0-alpha02', { androidTestImplementation('androidx.test.espresso:espresso-core:3.3.0-alpha02', {
exclude group: 'com.android.support', module: 'support-annotations' exclude group: 'com.android.support', module: 'support-annotations'
}) })
findbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.9.0' findbugsPlugins 'com.h3xstream.findsecbugs:findsecbugs-plugin:1.9.0'
findbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.4.6' findbugsPlugins 'com.mebigfatguy.fb-contrib:fb-contrib:7.4.6'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'
implementation 'com.github.Kennyc1012:BottomSheet:2.4.1'
} }

View File

@ -19,5 +19,6 @@
*/ */
dependencies { dependencies {
implementation "androidx.work:work-gcm:$work_version"
implementation "com.google.firebase:firebase-messaging:20.0.0" implementation "com.google.firebase:firebase-messaging:20.0.0"
} }

View File

@ -0,0 +1,29 @@
<!--
~ Nextcloud Talk application
~
~ @author Mario Danic
~ Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<!-- drawable/link_variant.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#000000"
android:pathData="M10.59,13.41C11,13.8 11,14.44 10.59,14.83C10.2,15.22 9.56,15.22 9.17,14.83C7.22,12.88 7.22,9.71 9.17,7.76V7.76L12.71,4.22C14.66,2.27 17.83,2.27 19.78,4.22C21.73,6.17 21.73,9.34 19.78,11.29L18.29,12.78C18.3,11.96 18.17,11.14 17.89,10.36L18.36,9.88C19.54,8.71 19.54,6.81 18.36,5.64C17.19,4.46 15.29,4.46 14.12,5.64L10.59,9.17C9.41,10.34 9.41,12.24 10.59,13.41M13.41,9.17C13.8,8.78 14.44,8.78 14.83,9.17C16.78,11.12 16.78,14.29 14.83,16.24V16.24L11.29,19.78C9.34,21.73 6.17,21.73 4.22,19.78C2.27,17.83 2.27,14.66 4.22,12.71L5.71,11.22C5.7,12.04 5.83,12.86 6.11,13.65L5.64,14.12C4.46,15.29 4.46,17.19 5.64,18.36C6.81,19.54 8.71,19.54 9.88,18.36L13.41,14.83C14.59,13.66 14.59,11.76 13.41,10.59C13,10.2 13,9.56 13.41,9.17Z" />
</vector>

View File

@ -20,6 +20,7 @@
package com.nextcloud.talk.controllers package com.nextcloud.talk.controllers
import android.content.Intent
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.graphics.drawable.LayerDrawable import android.graphics.drawable.LayerDrawable
import android.os.Bundle import android.os.Bundle
@ -48,6 +49,7 @@ import com.bluelinelabs.conductor.changehandler.HorizontalChangeHandler
import com.facebook.drawee.backends.pipeline.Fresco import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.drawee.view.SimpleDraweeView import com.facebook.drawee.view.SimpleDraweeView
import com.nextcloud.talk.R import com.nextcloud.talk.R
import com.nextcloud.talk.R.string
import com.nextcloud.talk.adapters.items.UserItem import com.nextcloud.talk.adapters.items.UserItem
import com.nextcloud.talk.api.NcApi import com.nextcloud.talk.api.NcApi
import com.nextcloud.talk.application.NextcloudTalkApplication import com.nextcloud.talk.application.NextcloudTalkApplication
@ -55,24 +57,30 @@ import com.nextcloud.talk.controllers.base.BaseController
import com.nextcloud.talk.controllers.bottomsheet.items.BasicListItemWithImage import com.nextcloud.talk.controllers.bottomsheet.items.BasicListItemWithImage
import com.nextcloud.talk.controllers.bottomsheet.items.listItemsWithImage import com.nextcloud.talk.controllers.bottomsheet.items.listItemsWithImage
import com.nextcloud.talk.events.EventStatus import com.nextcloud.talk.events.EventStatus
import com.nextcloud.talk.interfaces.ConversationInfoInterface
import com.nextcloud.talk.jobs.DeleteConversationWorker import com.nextcloud.talk.jobs.DeleteConversationWorker
import com.nextcloud.talk.jobs.LeaveConversationWorker import com.nextcloud.talk.jobs.LeaveConversationWorker
import com.nextcloud.talk.models.database.UserEntity import com.nextcloud.talk.models.database.UserEntity
import com.nextcloud.talk.models.json.conversations.Conversation import com.nextcloud.talk.models.json.conversations.Conversation
import com.nextcloud.talk.models.json.conversations.Conversation.ConversationType.ROOM_PUBLIC_CALL
import com.nextcloud.talk.models.json.conversations.RoomOverall import com.nextcloud.talk.models.json.conversations.RoomOverall
import com.nextcloud.talk.models.json.converters.EnumNotificationLevelConverter import com.nextcloud.talk.models.json.converters.EnumNotificationLevelConverter
import com.nextcloud.talk.models.json.generic.GenericOverall import com.nextcloud.talk.models.json.generic.GenericOverall
import com.nextcloud.talk.models.json.participants.Participant import com.nextcloud.talk.models.json.participants.Participant
import com.nextcloud.talk.models.json.participants.ParticipantsOverall import com.nextcloud.talk.models.json.participants.ParticipantsOverall
import com.nextcloud.talk.newarch.utils.getCredentials
import com.nextcloud.talk.utils.ApiUtils import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.DateUtils import com.nextcloud.talk.utils.DateUtils
import com.nextcloud.talk.utils.DisplayUtils import com.nextcloud.talk.utils.DisplayUtils
import com.nextcloud.talk.utils.ShareUtils
import com.nextcloud.talk.utils.bundle.BundleKeys import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.database.user.UserUtils
import com.nextcloud.talk.utils.preferences.preferencestorage.DatabaseStorageModule import com.nextcloud.talk.utils.preferences.preferencestorage.DatabaseStorageModule
import com.nextcloud.talk.utils.ui.MaterialPreferenceCategoryWithRightLink import com.nextcloud.talk.utils.ui.MaterialPreferenceCategoryWithRightLink
import com.yarolegovich.lovelydialog.LovelySaveStateHandler import com.yarolegovich.lovelydialog.LovelySaveStateHandler
import com.yarolegovich.lovelydialog.LovelyStandardDialog import com.yarolegovich.lovelydialog.LovelyStandardDialog
import com.yarolegovich.mp.MaterialChoicePreference import com.yarolegovich.mp.MaterialChoicePreference
import com.yarolegovich.mp.MaterialEditTextPreference
import com.yarolegovich.mp.MaterialPreferenceCategory import com.yarolegovich.mp.MaterialPreferenceCategory
import com.yarolegovich.mp.MaterialPreferenceScreen import com.yarolegovich.mp.MaterialPreferenceScreen
import com.yarolegovich.mp.MaterialStandardPreference import com.yarolegovich.mp.MaterialStandardPreference
@ -92,7 +100,24 @@ import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class) @AutoInjector(NextcloudTalkApplication::class)
class ConversationInfoController(args: Bundle) : BaseController(), class ConversationInfoController(args: Bundle) : BaseController(),
FlexibleAdapter.OnItemClickListener { FlexibleAdapter.OnItemClickListener, ConversationInfoInterface {
override fun conversationNameSet(name: String?) {
conversationDisplayName.post {
conversationDisplayName.text = name
}
}
override fun passwordSet(isCleared: Boolean) {
passwordAction.post {
if (!isCleared) {
passwordAction.setSummary(context.getString(string.nc_password_redacted))
} else {
passwordAction.setSummary(context.getString(string.nc_manual))
}
}
}
@BindView(R.id.notification_settings) @BindView(R.id.notification_settings)
lateinit var notificationsPreferenceScreen: MaterialPreferenceScreen lateinit var notificationsPreferenceScreen: MaterialPreferenceScreen
@BindView(R.id.progressBar) @BindView(R.id.progressBar)
@ -125,9 +150,23 @@ class ConversationInfoController(args: Bundle) : BaseController(),
lateinit var muteCalls: MaterialSwitchPreference lateinit var muteCalls: MaterialSwitchPreference
@BindView(R.id.mpc_action) @BindView(R.id.mpc_action)
lateinit var actionTextView: TextView lateinit var actionTextView: TextView
@BindView(R.id.generalConversationOptions)
lateinit var generalConversationOptions: MaterialPreferenceScreen
@BindView(R.id.changeConversationName)
lateinit var changeConversationName: MaterialEditTextPreference
@BindView(R.id.favoriteConversationAction)
lateinit var favoriteConversationAction: MaterialSwitchPreference
@BindView(R.id.allowGuestsAction)
lateinit var allowGuestsAction: MaterialSwitchPreference
@BindView(R.id.passwordAction)
lateinit var passwordAction: MaterialEditTextPreference
@BindView(R.id.shareAction)
lateinit var shareAction: MaterialStandardPreference
@set:Inject @set:Inject
lateinit var ncApi: NcApi lateinit var ncApi: NcApi
@set:Inject
lateinit var userUtils: UserUtils
private val conversationToken: String? private val conversationToken: String?
private val conversationUser: UserEntity? private val conversationUser: UserEntity?
@ -189,13 +228,6 @@ class ConversationInfoController(args: Bundle) : BaseController(),
super.onAttach(view) super.onAttach(view)
eventBus.register(this) eventBus.register(this)
if (databaseStorageModule == null) {
databaseStorageModule = DatabaseStorageModule(conversationUser!!, conversationToken)
}
notificationsPreferenceScreen.setStorageModule(databaseStorageModule)
conversationInfoWebinar.setStorageModule(databaseStorageModule)
fetchRoomInfo() fetchRoomInfo()
} }
@ -206,6 +238,15 @@ class ConversationInfoController(args: Bundle) : BaseController(),
saveStateHandler = LovelySaveStateHandler() saveStateHandler = LovelySaveStateHandler()
} }
if (databaseStorageModule == null) {
databaseStorageModule = DatabaseStorageModule(
conversationUser, conversationToken, this)
}
notificationsPreferenceScreen.setStorageModule(databaseStorageModule)
conversationInfoWebinar.setStorageModule(databaseStorageModule)
generalConversationOptions.setStorageModule(databaseStorageModule)
actionTextView.visibility = View.GONE actionTextView.visibility = View.GONE
} }
@ -280,6 +321,91 @@ class ConversationInfoController(args: Bundle) : BaseController(),
} }
} }
fun submitGuestChange() {
if (databaseStorageModule != null && conversationUser != null && conversation != null) {
if ((allowGuestsAction.findViewById<View>(R.id.mp_checkable) as SwitchCompat).isChecked) {
ncApi.makeRoomPublic(conversationUser.getCredentials(), ApiUtils.getUrlForRoomVisibility
(conversationUser.baseUrl, conversation!!.token))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<GenericOverall> {
override fun onComplete() {
}
override fun onSubscribe(d: Disposable) {
}
override fun onNext(t: GenericOverall) {
}
override fun onError(e: Throwable) {
}
})
} else {
ncApi.makeRoomPrivate(conversationUser.getCredentials(), ApiUtils.getUrlForRoomVisibility
(conversationUser.baseUrl, conversation!!.token))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<GenericOverall> {
override fun onComplete() {
}
override fun onSubscribe(d: Disposable) {
}
override fun onNext(t: GenericOverall) {
}
override fun onError(e: Throwable) {
}
})
}
}
}
fun submitFavoriteChange() {
if (databaseStorageModule != null && conversationUser != null && conversation != null) {
if ((favoriteConversationAction.findViewById<View>(R.id.mp_checkable) as SwitchCompat).isChecked) {
ncApi.addConversationToFavorites(conversationUser.getCredentials(), ApiUtils
.getUrlForConversationFavorites(conversationUser.baseUrl, conversation!!.token))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<GenericOverall> {
override fun onComplete() {
}
override fun onSubscribe(d: Disposable) {
}
override fun onNext(t: GenericOverall) {
}
override fun onError(e: Throwable) {
}
})
} else {
ncApi.removeConversationFromFavorites(conversationUser.getCredentials(), ApiUtils
.getUrlForConversationFavorites(conversationUser.baseUrl, conversation!!.token))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<GenericOverall> {
override fun onComplete() {
}
override fun onSubscribe(d: Disposable) {
}
override fun onNext(t: GenericOverall) {
}
override fun onError(e: Throwable) {
}
})
}
}
}
fun submitLobbyChanges() { fun submitLobbyChanges() {
val state = if ((conversationInfoLobby.findViewById<View>( val state = if ((conversationInfoLobby.findViewById<View>(
R.id R.id
@ -518,15 +644,17 @@ class ConversationInfoController(args: Bundle) : BaseController(),
val conversationCopy = conversation val conversationCopy = conversation
if (isAttached && (!isBeingDestroyed || !isDestroyed)) {
if (conversationCopy!!.canModerate(conversationUser)) { if (conversationCopy!!.canModerate(conversationUser)) {
actionTextView.visibility = View.VISIBLE actionTextView.visibility = View.VISIBLE
} else { } else {
actionTextView.visibility = View.GONE actionTextView.visibility = View.GONE
} }
if (isAttached && (!isBeingDestroyed || !isDestroyed)) {
ownOptionsCategory.visibility = View.VISIBLE ownOptionsCategory.visibility = View.VISIBLE
setupGeneralSettings()
setupWebinaryView() setupWebinaryView()
if (!conversation!!.canLeave(conversationUser)) { if (!conversation!!.canLeave(conversationUser)) {
@ -571,6 +699,83 @@ class ConversationInfoController(args: Bundle) : BaseController(),
}) })
} }
private fun setupGeneralSettings() {
if (conversation != null) {
changeConversationName.value = conversation!!.displayName
if (conversation!!.isNameEditable(conversationUser)) {
changeConversationName.visibility = View.VISIBLE
} else {
changeConversationName.visibility = View.GONE
}
favoriteConversationAction.value = conversation!!.isFavorite
allowGuestsAction.value = conversation!!.type == ROOM_PUBLIC_CALL
(allowGuestsAction.findViewById<View>(R.id.mp_checkable) as SwitchCompat)
.isChecked = allowGuestsAction.value
(favoriteConversationAction.findViewById<View>(R.id.mp_checkable) as SwitchCompat)
.isChecked = favoriteConversationAction.value
(favoriteConversationAction.findViewById<View>(R.id.mp_checkable) as SwitchCompat).setOnCheckedChangeListener { buttonView, isChecked ->
submitFavoriteChange()
}
(allowGuestsAction.findViewById<View>(R.id.mp_checkable) as SwitchCompat).setOnCheckedChangeListener { buttonView, isChecked ->
if (isChecked) {
passwordAction.visibility = View.VISIBLE
shareAction.visibility = View.VISIBLE
} else {
passwordAction.visibility = View.GONE
shareAction.visibility = View.GONE
}
submitGuestChange()
}
shareAction.setOnClickListener {
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(
Intent.EXTRA_SUBJECT,
String.format(
context.getString(R.string.nc_share_subject),
context.getString(R.string.nc_app_name)
)
)
putExtra(
Intent.EXTRA_TEXT, ShareUtils.getStringForIntent(
context, conversation!!.password,
userUtils, conversation
)
)
type = "text/plain"
}
val intent = Intent.createChooser(sendIntent, context.getString(string.nc_share_link))
startActivity(intent)
}
if (allowGuestsAction.value) {
passwordAction.visibility = View.VISIBLE
shareAction.visibility = View.VISIBLE
passwordAction.value = conversation!!.hasPassword.toString()
if (conversation!!.hasPassword) {
passwordAction.setSummary(context.getString(string.nc_password_redacted))
} else {
passwordAction.setSummary(context.getString(string.nc_manual))
}
} else {
passwordAction.visibility = View.GONE
shareAction.visibility = View.GONE
}
}
}
private fun adjustNotificationLevelUI() { private fun adjustNotificationLevelUI() {
if (conversation != null) { if (conversation != null) {
if (conversationUser != null && conversationUser.hasSpreedFeatureCapability( if (conversationUser != null && conversationUser.hasSpreedFeatureCapability(

View File

@ -0,0 +1,26 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.nextcloud.talk.interfaces;
public interface ConversationInfoInterface {
void conversationNameSet(String name);
void passwordSet(boolean isCleared);
}

View File

@ -27,6 +27,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.media.AudioAttributes; import android.media.AudioAttributes;
import android.media.MediaPlayer; import android.media.MediaPlayer;
import android.net.Uri; import android.net.Uri;

View File

@ -345,7 +345,7 @@ class ConversationsListView : BaseView(), OnQueryTextListener,
drawable.ic_star_black_24dp -> { drawable.ic_star_black_24dp -> {
viewModel.changeFavoriteValueForConversation(conversation, true) viewModel.changeFavoriteValueForConversation(conversation, true)
} }
drawable.ic_link_grey600_24px -> { drawable.ic_share_black_24dp -> {
startActivity(viewModel.getShareIntentForConversation(conversation)) startActivity(viewModel.getShareIntentForConversation(conversation))
} }
drawable.ic_exit_to_app_black_24dp -> { drawable.ic_exit_to_app_black_24dp -> {

View File

@ -276,7 +276,7 @@ class ConversationsListViewModel constructor(
items.add( items.add(
(BasicListItemWithImage( (BasicListItemWithImage(
drawable drawable
.ic_link_grey600_24px, context.getString(string.nc_share_link) .ic_share_black_24dp, context.getString(string.nc_share_link)
)) ))
) )
} }

View File

@ -60,7 +60,6 @@ class PackageReplacedReceiver : BroadcastReceiver() {
.NOTIFICATION_SERVICE .NOTIFICATION_SERVICE
) as NotificationManager ) as NotificationManager
if (notificationManager != null) {
if (!appPreferences.isNotificationChannelUpgradedToV2) { if (!appPreferences.isNotificationChannelUpgradedToV2) {
for (notificationChannelGroup in notificationManager for (notificationChannelGroup in notificationManager
.notificationChannelGroups) { .notificationChannelGroups) {
@ -86,7 +85,6 @@ class PackageReplacedReceiver : BroadcastReceiver() {
) )
appPreferences.setNotificationChannelIsUpgradedToV3(true) appPreferences.setNotificationChannelIsUpgradedToV3(true)
} }
}
} }
} catch (e: PackageManager.NameNotFoundException) { } catch (e: PackageManager.NameNotFoundException) {

View File

@ -17,27 +17,17 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
* Part of the code in ShareUtils was inspired by BottomSheet under the Apache licence
* located here: https://github.com/Kennyc1012/BottomSheet/blob/master/library/src/main/java/com/kennyc/bottomsheet/BottomSheet.java#L425
*/ */
package com.nextcloud.talk.utils; package com.nextcloud.talk.utils;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.drawable.Drawable;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.kennyc.bottomsheet.adapters.AppAdapter;
import com.nextcloud.talk.R; import com.nextcloud.talk.R;
import com.nextcloud.talk.models.database.UserEntity; import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.models.json.conversations.Conversation; import com.nextcloud.talk.models.json.conversations.Conversation;
import com.nextcloud.talk.utils.database.user.UserUtils; import com.nextcloud.talk.utils.database.user.UserUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
public class ShareUtils { public class ShareUtils {
@ -58,47 +48,4 @@ public class ShareUtils {
return shareString; return shareString;
} }
public static List<AppAdapter.AppInfo> getShareApps(Context context, Intent intent,
@Nullable Set<String> appsFilter, @Nullable Set<String> toExclude) {
if (context == null || intent == null) return null;
PackageManager manager = context.getPackageManager();
List<ResolveInfo> apps = manager.queryIntentActivities(intent, 0);
if (apps != null && !apps.isEmpty()) {
List<AppAdapter.AppInfo> appResources = new ArrayList<>(apps.size());
boolean shouldCheckPackages = appsFilter != null && !appsFilter.isEmpty();
for (ResolveInfo resolveInfo : apps) {
String packageName = resolveInfo.activityInfo.packageName;
if (shouldCheckPackages && !appsFilter.contains(packageName)) {
continue;
}
String title = resolveInfo.loadLabel(manager).toString();
String name = resolveInfo.activityInfo.name;
Drawable drawable = resolveInfo.loadIcon(manager);
appResources.add(new AppAdapter.AppInfo(title, packageName, name, drawable));
}
if (toExclude != null && !toExclude.isEmpty()) {
List<AppAdapter.AppInfo> toRemove = new ArrayList<>();
for (AppAdapter.AppInfo appInfo : appResources) {
if (toExclude.contains(appInfo.packageName)) {
toRemove.add(appInfo);
}
}
if (!toRemove.isEmpty()) appResources.removeAll(toRemove);
}
return appResources;
}
return null;
}
} }

View File

@ -21,20 +21,24 @@
package com.nextcloud.talk.utils.preferences.preferencestorage; package com.nextcloud.talk.utils.preferences.preferencestorage;
import android.content.Context; import android.content.Context;
import com.nextcloud.talk.interfaces.ConversationInfoInterface;
import com.nextcloud.talk.models.database.UserEntity; import com.nextcloud.talk.models.database.UserEntity;
import com.yarolegovich.mp.io.StorageModule; import com.yarolegovich.mp.io.StorageModule;
public class DatabaseStorageFactory implements StorageModule.Factory { public class DatabaseStorageFactory implements StorageModule.Factory {
private UserEntity conversationUser; private UserEntity conversationUser;
private String conversationToken; private String conversationToken;
private ConversationInfoInterface conversationInfoInterface;
public DatabaseStorageFactory(UserEntity conversationUser, String conversationToken) { public DatabaseStorageFactory(UserEntity conversationUser, String conversationToken,
ConversationInfoInterface conversationInfoInterface) {
this.conversationUser = conversationUser; this.conversationUser = conversationUser;
this.conversationToken = conversationToken; this.conversationToken = conversationToken;
this.conversationInfoInterface = conversationInfoInterface;
} }
@Override @Override
public StorageModule create(Context context) { public StorageModule create(Context context) {
return new DatabaseStorageModule(conversationUser, conversationToken); return new DatabaseStorageModule(conversationUser, conversationToken, conversationInfoInterface);
} }
} }

View File

@ -25,6 +25,7 @@ import android.text.TextUtils;
import autodagger.AutoInjector; import autodagger.AutoInjector;
import com.nextcloud.talk.api.NcApi; import com.nextcloud.talk.api.NcApi;
import com.nextcloud.talk.application.NextcloudTalkApplication; import com.nextcloud.talk.application.NextcloudTalkApplication;
import com.nextcloud.talk.interfaces.ConversationInfoInterface;
import com.nextcloud.talk.models.database.ArbitraryStorageEntity; import com.nextcloud.talk.models.database.ArbitraryStorageEntity;
import com.nextcloud.talk.models.database.UserEntity; import com.nextcloud.talk.models.database.UserEntity;
import com.nextcloud.talk.models.json.generic.GenericOverall; import com.nextcloud.talk.models.json.generic.GenericOverall;
@ -50,10 +51,17 @@ public class DatabaseStorageModule implements StorageModule {
private long accountIdentifier; private long accountIdentifier;
private boolean lobbyValue; private boolean lobbyValue;
private boolean favoriteConversationValue;
private boolean allowGuestsValue;
private Boolean hasPassword;
private String conversationNameValue;
private String messageNotificationLevel; private String messageNotificationLevel;
private ConversationInfoInterface conversationInfoInterface;
public DatabaseStorageModule(UserEntity conversationUser, String conversationToken) { public DatabaseStorageModule(UserEntity conversationUser, String conversationToken,
ConversationInfoInterface conversationInfoInterface) {
NextcloudTalkApplication.Companion.getSharedApplication() NextcloudTalkApplication.Companion.getSharedApplication()
.getComponentApplication() .getComponentApplication()
.inject(this); .inject(this);
@ -61,23 +69,39 @@ public class DatabaseStorageModule implements StorageModule {
this.conversationUser = conversationUser; this.conversationUser = conversationUser;
this.accountIdentifier = conversationUser.getId(); this.accountIdentifier = conversationUser.getId();
this.conversationToken = conversationToken; this.conversationToken = conversationToken;
this.conversationInfoInterface = conversationInfoInterface;
} }
@Override @Override
public void saveBoolean(String key, boolean value) { public void saveBoolean(String key, boolean value) {
if (!key.equals("conversation_lobby")) { if (!key.equals("conversation_lobby") && !key.equals("allow_guests") && !key.equals(
"favorite_conversation")) {
arbitraryStorageUtils.storeStorageSetting(accountIdentifier, key, Boolean.toString(value), arbitraryStorageUtils.storeStorageSetting(accountIdentifier, key, Boolean.toString(value),
conversationToken); conversationToken);
} else { } else {
switch (key) {
case "conversation_lobby":
lobbyValue = value; lobbyValue = value;
break;
case "allow_guests":
allowGuestsValue = value;
break;
case "favorite_conversation":
favoriteConversationValue = value;
break;
default:
}
} }
} }
@Override @Override
public void saveString(String key, String value) { public void saveString(String key, String value) {
if (!key.equals("message_notification_level")) { if (!key.equals("message_notification_level")
&& !key.equals("conversation_name")
&& !key.equals("conversation_password")) {
arbitraryStorageUtils.storeStorageSetting(accountIdentifier, key, value, conversationToken); arbitraryStorageUtils.storeStorageSetting(accountIdentifier, key, value, conversationToken);
} else { } else {
if (key.equals("message_notification_level")) {
if (conversationUser.hasSpreedFeatureCapability("notification-levels")) { if (conversationUser.hasSpreedFeatureCapability("notification-levels")) {
if (!TextUtils.isEmpty(messageNotificationLevel) && !messageNotificationLevel.equals( if (!TextUtils.isEmpty(messageNotificationLevel) && !messageNotificationLevel.equals(
value)) { value)) {
@ -97,7 +121,8 @@ public class DatabaseStorageModule implements StorageModule {
} }
ncApi.setNotificationLevel( ncApi.setNotificationLevel(
ApiUtils.getCredentials(conversationUser.getUsername(), conversationUser.getToken()), ApiUtils.getCredentials(conversationUser.getUsername(),
conversationUser.getToken()),
ApiUtils.getUrlForSettingNotificationlevel(conversationUser.getBaseUrl(), ApiUtils.getUrlForSettingNotificationlevel(conversationUser.getBaseUrl(),
conversationToken), conversationToken),
intValue) intValue)
@ -126,6 +151,68 @@ public class DatabaseStorageModule implements StorageModule {
messageNotificationLevel = value; messageNotificationLevel = value;
} }
} }
} else if (key.equals("conversation_password")) {
if (hasPassword != null) {
ncApi.setPassword(ApiUtils.getCredentials(conversationUser.getUsername(),
conversationUser.getToken()),
ApiUtils.getUrlForPassword(conversationUser.getBaseUrl(),
conversationToken), value)
.subscribeOn(Schedulers.io())
.subscribe(new Observer<GenericOverall>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(GenericOverall genericOverall) {
hasPassword = !TextUtils.isEmpty(value);
conversationInfoInterface.passwordSet(TextUtils.isEmpty(value));
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
} else {
hasPassword = Boolean.parseBoolean(value);
}
} else if (key.equals("conversation_name")) {
if (!TextUtils.isEmpty(conversationNameValue) && !conversationNameValue.equals(value)) {
ncApi.renameRoom(ApiUtils.getCredentials(conversationUser.getUsername(),
conversationUser.getToken()), ApiUtils.getRoom(conversationUser.getBaseUrl(),
conversationToken), value)
.subscribeOn(Schedulers.io())
.subscribe(new Observer<GenericOverall>() {
@Override
public void onSubscribe(Disposable d) {
}
@Override
public void onNext(GenericOverall genericOverall) {
conversationNameValue = value;
conversationInfoInterface.conversationNameSet(value);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
} else {
conversationNameValue = value;
}
}
} }
} }
@ -144,6 +231,10 @@ public class DatabaseStorageModule implements StorageModule {
public boolean getBoolean(String key, boolean defaultVal) { public boolean getBoolean(String key, boolean defaultVal) {
if (key.equals("conversation_lobby")) { if (key.equals("conversation_lobby")) {
return lobbyValue; return lobbyValue;
} else if (key.equals("allow_guests")) {
return allowGuestsValue;
} else if (key.equals("favorite_conversation")) {
return favoriteConversationValue;
} else { } else {
ArbitraryStorageEntity valueFromDb = ArbitraryStorageEntity valueFromDb =
arbitraryStorageUtils.getStorageSetting(accountIdentifier, key, conversationToken); arbitraryStorageUtils.getStorageSetting(accountIdentifier, key, conversationToken);
@ -157,7 +248,9 @@ public class DatabaseStorageModule implements StorageModule {
@Override @Override
public String getString(String key, String defaultVal) { public String getString(String key, String defaultVal) {
if (!key.equals("message_notification_level")) { if (!key.equals("message_notification_level")
&& !key.equals("conversation_name")
&& !key.equals("conversation_password")) {
ArbitraryStorageEntity valueFromDb = ArbitraryStorageEntity valueFromDb =
arbitraryStorageUtils.getStorageSetting(accountIdentifier, key, conversationToken); arbitraryStorageUtils.getStorageSetting(accountIdentifier, key, conversationToken);
if (valueFromDb == null) { if (valueFromDb == null) {
@ -165,9 +258,15 @@ public class DatabaseStorageModule implements StorageModule {
} else { } else {
return valueFromDb.getValue(); return valueFromDb.getValue();
} }
} else { } else if (key.equals("message_notification_level")) {
return messageNotificationLevel; return messageNotificationLevel;
} else if (key.equals("conversation_name")) {
return conversationNameValue;
} else if (key.equals("conversation_password")) {
return "";
} }
return "";
} }
@Override @Override

View File

@ -18,12 +18,11 @@
~ along with this program. If not, see <http://www.gnu.org/licenses/>. ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
--> -->
<vector xmlns:tools="http://schemas.android.com/tools" <vector xmlns:android="http://schemas.android.com/apk/res/android"
android:autoMirrored="true" android:height="24dp" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0" android:width="24dp"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> android:viewportWidth="24"
<path android:fillColor="#000000" android:fillType="nonZero" android:viewportHeight="24">
android:pathData="M13,5.921L9.818,9.105C9.111,9.812 8.781,10.723 8.83,11.562C8.88,12.401 9.263,13.146 9.818,13.701L11.23,12.285C10.663,11.717 10.686,11.065 11.232,10.519L14.414,7.337C14.939,6.812 15.664,6.814 16.186,7.335C16.668,7.891 16.713,8.574 16.182,9.105L15.362,9.925C15.917,10.71 16.007,11.291 15.955,12.16L17.596,10.519C18.833,9.282 18.833,7.154 17.596,5.917C16.36,4.681 14.254,4.706 13,5.921L13,5.921ZM13.707,9.806L12.293,11.224L12.297,11.224C12.847,11.774 12.804,12.482 12.293,12.994L9.111,16.175C8.415,16.767 7.813,16.646 7.342,16.175C6.715,15.549 6.842,14.907 7.342,14.407L8.192,13.56C7.636,12.777 7.543,12.195 7.594,11.328L5.928,12.994C4.689,14.233 4.692,16.354 5.928,17.589C7.163,18.825 9.29,18.825 10.526,17.589L13.707,14.407C14.416,13.699 14.747,12.789 14.698,11.949C14.65,11.109 14.266,10.362 13.709,9.808L13.707,9.806Z" <path android:fillColor="#000000"
android:strokeColor="#00000000" android:strokeWidth="1" android:pathData="M10.59,13.41C11,13.8 11,14.44 10.59,14.83C10.2,15.22 9.56,15.22 9.17,14.83C7.22,12.88 7.22,9.71 9.17,7.76V7.76L12.71,4.22C14.66,2.27 17.83,2.27 19.78,4.22C21.73,6.17 21.73,9.34 19.78,11.29L18.29,12.78C18.3,11.96 18.17,11.14 17.89,10.36L18.36,9.88C19.54,8.71 19.54,6.81 18.36,5.64C17.19,4.46 15.29,4.46 14.12,5.64L10.59,9.17C9.41,10.34 9.41,12.24 10.59,13.41M13.41,9.17C13.8,8.78 14.44,8.78 14.83,9.17C16.78,11.12 16.78,14.29 14.83,16.24V16.24L11.29,19.78C9.34,21.73 6.17,21.73 4.22,19.78C2.27,17.83 2.27,14.66 4.22,12.71L5.71,11.22C5.7,12.04 5.83,12.86 6.11,13.65L5.64,14.12C4.46,15.29 4.46,17.19 5.64,18.36C6.81,19.54 8.71,19.54 9.88,18.36L13.41,14.83C14.59,13.66 14.59,11.76 13.41,10.59C13,10.2 13,9.56 13.41,9.17Z" />
tools:ignore="VectorPath" />
</vector> </vector>

View File

@ -1,29 +0,0 @@
<!--
~ Nextcloud Talk application
~
~ @author Mario Danic
~ Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<vector xmlns:tools="http://schemas.android.com/tools"
android:autoMirrored="true" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#757575" android:fillType="nonZero"
android:pathData="M13,5.921L9.818,9.105C9.111,9.812 8.781,10.723 8.83,11.562C8.88,12.401 9.263,13.146 9.818,13.701L11.23,12.285C10.663,11.717 10.686,11.065 11.232,10.519L14.414,7.337C14.939,6.812 15.664,6.814 16.186,7.335C16.668,7.891 16.713,8.574 16.182,9.105L15.362,9.925C15.917,10.71 16.007,11.291 15.955,12.16L17.596,10.519C18.833,9.282 18.833,7.154 17.596,5.917C16.36,4.681 14.254,4.706 13,5.921L13,5.921ZM13.707,9.806L12.293,11.224L12.297,11.224C12.847,11.774 12.804,12.482 12.293,12.994L9.111,16.175C8.415,16.767 7.813,16.646 7.342,16.175C6.715,15.549 6.842,14.907 7.342,14.407L8.192,13.56C7.636,12.777 7.543,12.195 7.594,11.328L5.928,12.994C4.689,14.233 4.692,16.354 5.928,17.589C7.163,18.825 9.29,18.825 10.526,17.589L13.707,14.407C14.416,13.699 14.747,12.789 14.698,11.949C14.65,11.109 14.266,10.362 13.709,9.808L13.707,9.806Z"
android:strokeColor="#00000000" android:strokeWidth="1"
tools:ignore="VectorPath" />
</vector>

View File

@ -0,0 +1,25 @@
<!--
~ Nextcloud Talk application
~
~ @author Mario Danic
~ Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM18,14L6,14v-2h12v2zM18,11L6,11L6,9h12v2zM18,8L6,8L6,6h12v2z"/>
</vector>

View File

@ -1,25 +0,0 @@
<!--
~ Nextcloud Talk application
~
~ @author Mario Danic
~ Copyright (C) 2017-2018 Mario Danic <mario@lovelyhq.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<vector android:autoMirrored="true" android:height="24dp"
android:viewportHeight="16.0" android:viewportWidth="16.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="m9.236,2.166 l-3.182,3.184c-0.707,0.707 -1.038,1.618 -0.988,2.457 0.05,0.839 0.433,1.584 0.988,2.139l1.412,-1.416c-0.567,-0.567 -0.544,-1.219 0.002,-1.766l3.181,-3.182c0.525,-0.525 1.251,-0.523 1.772,-0.002 0.482,0.556 0.527,1.238 -0.004,1.77l-0.82,0.82c0.555,0.785 0.645,1.366 0.593,2.234l1.641,-1.641c1.237,-1.237 1.237,-3.365 0,-4.602 -1.236,-1.236 -3.342,-1.211 -4.596,0.004zM9.943,6.051 L8.529,7.469c0,0 0.003,0 0.004,0 0.55,0.55 0.507,1.258 -0.004,1.77l-3.182,3.182c-0.696,0.592 -1.298,0.471 -1.77,0 -0.626,-0.626 -0.5,-1.268 0,-1.768l0.85,-0.847c-0.556,-0.784 -0.648,-1.365 -0.598,-2.232l-1.666,1.666c-1.239,1.239 -1.236,3.36 0,4.596 1.235,1.235 3.362,1.236 4.598,0l3.182,-3.182c0.709,-0.708 1.04,-1.618 0.991,-2.459 -0.048,-0.84 -0.432,-1.586 -0.989,-2.141z"/>
</vector>

View File

@ -0,0 +1,26 @@
<!--
~ Nextcloud Talk application
~
~ @author Mario Danic
~ Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<vector android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@color/grey_600"
android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"/>
</vector>

View File

@ -0,0 +1,25 @@
<!--
~ Nextcloud Talk application
~
~ @author Mario Danic
~ Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M13.5,0.67s0.74,2.65 0.74,4.8c0,2.06 -1.35,3.73 -3.41,3.73 -2.07,0 -3.63,-1.67 -3.63,-3.73l0.03,-0.36C5.21,7.51 4,10.62 4,14c0,4.42 3.58,8 8,8s8,-3.58 8,-8C20,8.61 17.41,3.8 13.5,0.67zM11.71,19c-1.78,0 -3.22,-1.4 -3.22,-3.14 0,-1.62 1.05,-2.76 2.81,-3.12 1.77,-0.36 3.6,-1.21 4.62,-2.58 0.39,1.29 0.59,2.65 0.59,4.04 0,2.65 -2.15,4.8 -4.8,4.8z"/>
</vector>

View File

@ -0,0 +1,29 @@
<!--
~ Nextcloud Talk application
~
~ @author Mario Danic
~ Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<!-- drawable/link_variant.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="@color/grey_600"
android:pathData="M10.59,13.41C11,13.8 11,14.44 10.59,14.83C10.2,15.22 9.56,15.22 9.17,14.83C7.22,12.88 7.22,9.71 9.17,7.76V7.76L12.71,4.22C14.66,2.27 17.83,2.27 19.78,4.22C21.73,6.17 21.73,9.34 19.78,11.29L18.29,12.78C18.3,11.96 18.17,11.14 17.89,10.36L18.36,9.88C19.54,8.71 19.54,6.81 18.36,5.64C17.19,4.46 15.29,4.46 14.12,5.64L10.59,9.17C9.41,10.34 9.41,12.24 10.59,13.41M13.41,9.17C13.8,8.78 14.44,8.78 14.83,9.17C16.78,11.12 16.78,14.29 14.83,16.24V16.24L11.29,19.78C9.34,21.73 6.17,21.73 4.22,19.78C2.27,17.83 2.27,14.66 4.22,12.71L5.71,11.22C5.7,12.04 5.83,12.86 6.11,13.65L5.64,14.12C4.46,15.29 4.46,17.19 5.64,18.36C6.81,19.54 8.71,19.54 9.88,18.36L13.41,14.83C14.59,13.66 14.59,11.76 13.41,10.59C13,10.2 13,9.56 13.41,9.17Z" />
</vector>

View File

@ -75,24 +75,12 @@
</RelativeLayout> </RelativeLayout>
</com.yarolegovich.mp.MaterialPreferenceCategory> </com.yarolegovich.mp.MaterialPreferenceCategory>
<com.yarolegovich.mp.MaterialPreferenceCategory
android:id="@+id/otherRoomOptions" <include layout="@layout/general_info_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/conversation_info_name" android:layout_below="@id/conversation_info_name"
android:visibility="gone">
<com.yarolegovich.mp.MaterialStandardPreference
android:id="@+id/favoriteConversationAction"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
apc:mp_icon="@drawable/ic_star_black_24dp" android:layout_width="match_parent"
apc:mp_icon_tint="@color/grey_600" />
apc:mp_title="@string/nc_add_to_favorites">
</com.yarolegovich.mp.MaterialStandardPreference>
</com.yarolegovich.mp.MaterialPreferenceCategory>
<com.nextcloud.talk.utils.ui.MaterialPreferenceCategoryWithRightLink <com.nextcloud.talk.utils.ui.MaterialPreferenceCategoryWithRightLink
android:id="@+id/participants_list_category" android:id="@+id/participants_list_category"
@ -142,7 +130,7 @@
layout="@layout/notification_settings_item" layout="@layout/notification_settings_item"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/otherRoomOptions" android:layout_below="@id/generalConversationOptions"
android:visibility="gone" /> android:visibility="gone" />
<include <include

View File

@ -38,7 +38,7 @@
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:contentDescription="@null" android:contentDescription="@null"
android:src="@drawable/ic_public_black_24px" android:src="@drawable/link_variant"
android:tint="@color/colorPrimary" /> android:tint="@color/colorPrimary" />
<TextView <TextView

View File

@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Nextcloud Talk application
~
~ @author Mario Danic
~ Copyright (C) 2017-2019 Mario Danic <mario@lovelyhq.com>
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<com.yarolegovich.mp.MaterialPreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:apc="http://schemas.android.com/apk/res-auto"
android:id="@+id/generalConversationOptions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
>
<com.yarolegovich.mp.MaterialPreferenceCategory
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
apc:mpc_title="@string/nc_general_settings"
apc:mpc_title_color="@color/colorPrimary"
>
<com.yarolegovich.mp.MaterialEditTextPreference
android:id="@+id/changeConversationName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
apc:mp_icon="@drawable/ic_pencil_grey600_24dp"
apc:mp_icon_tint="@color/grey_600"
apc:mp_key="conversation_name"
apc:mp_title="@string/nc_rename"
/>
<com.yarolegovich.mp.MaterialSwitchPreference
android:id="@+id/favoriteConversationAction"
android:layout_width="match_parent"
android:layout_height="wrap_content"
apc:mp_icon="@drawable/ic_star_black_24dp"
apc:mp_icon_tint="@color/grey_600"
apc:mp_key="favorite_conversation"
apc:mp_summary="@string/nc_favorites_explanation"
apc:mp_title="@string/nc_favorite_conversation"
/>
<com.yarolegovich.mp.MaterialSwitchPreference
android:id="@+id/allowGuestsAction"
android:layout_width="match_parent"
android:layout_height="wrap_content"
apc:mp_icon="@drawable/link_variant"
apc:mp_icon_tint="@color/grey_600"
apc:mp_key="allow_guests"
apc:mp_title="@string/nc_allow_guests"
/>
<com.yarolegovich.mp.MaterialEditTextPreference
android:id="@+id/passwordAction"
android:layout_width="match_parent"
android:layout_height="wrap_content"
apc:mp_icon="@drawable/ic_lock_grey600_24px"
apc:mp_icon_tint="@color/grey_600"
apc:mp_key="conversation_password"
android:visibility="gone"
apc:mp_summary="@string/nc_manual"
apc:mp_title="@string/nc_password"
/>
<com.yarolegovich.mp.MaterialStandardPreference
android:id="@+id/shareAction"
android:layout_width="match_parent"
android:layout_height="wrap_content"
apc:mp_icon="@drawable/ic_share_black_24dp"
apc:mp_icon_tint="@color/grey_600"
android:visibility="gone"
apc:mp_title="@string/nc_share_link"
>
</com.yarolegovich.mp.MaterialStandardPreference>
</com.yarolegovich.mp.MaterialPreferenceCategory>
</com.yarolegovich.mp.MaterialPreferenceScreen>

View File

@ -33,7 +33,7 @@
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:contentDescription="@null" android:contentDescription="@null"
android:src="@drawable/ic_public_black_24px" android:src="@drawable/link_variant"
android:tint="@color/colorPrimary" /> android:tint="@color/colorPrimary" />
<TextView <TextView

View File

@ -37,6 +37,8 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
apc:mp_default_value="false" apc:mp_default_value="false"
apc:mp_icon="@drawable/ic_whatshot_black_24dp"
apc:mp_icon_tint="@color/grey_600"
apc:mp_key="important_conversation" apc:mp_key="important_conversation"
apc:mp_title="@string/nc_important_conversation" apc:mp_title="@string/nc_important_conversation"
apc:mp_summary="@string/nc_important_conversation_desc"/> apc:mp_summary="@string/nc_important_conversation_desc"/>
@ -45,6 +47,8 @@
android:id="@+id/conversation_info_message_notifications" android:id="@+id/conversation_info_message_notifications"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
apc:mp_icon="@drawable/ic_message_black_24dp"
apc:mp_icon_tint="@color/grey_600"
apc:mp_entry_descriptions="@array/message_notification_levels" apc:mp_entry_descriptions="@array/message_notification_levels"
apc:mp_entry_values="@array/message_notification_levels_entry_values" apc:mp_entry_values="@array/message_notification_levels_entry_values"
apc:mp_key="message_notification_level" apc:mp_key="message_notification_level"
@ -57,6 +61,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
apc:mp_default_value="false" apc:mp_default_value="false"
apc:mp_key="mute_calls" apc:mp_key="mute_calls"
apc:mp_icon="@drawable/ic_volume_mute_white_24dp"
apc:mp_icon_tint="@color/grey_600"
apc:mp_title="@string/nc_mute_calls" apc:mp_title="@string/nc_mute_calls"
apc:mp_summary="@string/nc_mute_calls_desc"/> apc:mp_summary="@string/nc_mute_calls_desc"/>

View File

@ -46,7 +46,6 @@
android:layout_toStartOf="@id/checkedImageView" android:layout_toStartOf="@id/checkedImageView"
android:layout_toEndOf="@id/simple_drawee_view" android:layout_toEndOf="@id/simple_drawee_view"
android:ellipsize="end" android:ellipsize="end"
android:textAppearance="@style/ListItem"
tools:text="Contact item text" /> tools:text="Contact item text" />
<com.facebook.drawee.view.SimpleDraweeView <com.facebook.drawee.view.SimpleDraweeView

View File

@ -61,13 +61,13 @@
android:padding="4dp" android:padding="4dp"
android:scaleType="centerInside" /> android:scaleType="centerInside" />
<androidx.legacy.widget.Space <Space
android:id="@id/attachmentButtonSpace" android:id="@id/attachmentButtonSpace"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_toEndOf="@id/attachmentButton" /> android:layout_toEndOf="@id/attachmentButton" />
<androidx.legacy.widget.Space <Space
android:id="@id/sendButtonSpace" android:id="@id/sendButtonSpace"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"

View File

@ -132,6 +132,7 @@
<string name="nc_no_proxy">No proxy</string> <string name="nc_no_proxy">No proxy</string>
<string name="nc_username">Username</string> <string name="nc_username">Username</string>
<string name="nc_password">Password</string> <string name="nc_password">Password</string>
<string name="nc_password_redacted">Redacted for privacy reasons</string>
<string name="nc_conversation_link">Conversation link</string> <string name="nc_conversation_link">Conversation link</string>
<string name="nc_new_password">New password</string> <string name="nc_new_password">New password</string>
<string name="nc_wrong_password">Wrong password</string> <string name="nc_wrong_password">Wrong password</string>
@ -169,8 +170,11 @@
<string name="nc_new_conversation">New conversation</string> <string name="nc_new_conversation">New conversation</string>
<string name="nc_join_via_link">Join with a link</string> <string name="nc_join_via_link">Join with a link</string>
<string name="nc_join_via_web">Join via web</string> <string name="nc_join_via_web">Join via web</string>
<string name="nc_favorite_conversation">Favorite conversation</string>
<string name="nc_add_to_favorites">Add to favorites</string> <string name="nc_add_to_favorites">Add to favorites</string>
<string name="nc_remove_from_favorites">Remove from favorites</string> <string name="nc_remove_from_favorites">Remove from favorites</string>
<string name="nc_favorites_explanation">Conversation will be pinned to the top of the
conversations list</string>
<!-- Contacts --> <!-- Contacts -->
<string name="nc_select_contacts">Select contacts</string> <string name="nc_select_contacts">Select contacts</string>
@ -311,4 +315,7 @@
<string name="nc_not_defined_error">Unknown error</string> <string name="nc_not_defined_error">Unknown error</string>
<string name="nc_unauthorized_error">No Unauthorized</string> <string name="nc_unauthorized_error">No Unauthorized</string>
<string name="nc_general_settings">General</string>
<string name="nc_allow_guests">Allow guests</string>
</resources> </resources>

View File

@ -39,10 +39,6 @@
<item name="android:textSize">12sp</item> <item name="android:textSize">12sp</item>
</style> </style>
<style name="ListItem" parent="BottomSheet.ListItem.TextAppearance">
<item name="android:textColor">@color/nc_incoming_text_default</item>
</style>
<style name="ChipIncomingTextAppearance" parent="TextAppearance.MaterialComponents.Chip"> <style name="ChipIncomingTextAppearance" parent="TextAppearance.MaterialComponents.Chip">
<item name="android:textColor">@color/nc_incoming_text_default</item> <item name="android:textColor">@color/nc_incoming_text_default</item>
</style> </style>