forked from GitHub-Mirror/riotX-android
Get real push rules from server and evaluate them
This commit is contained in:
@ -137,8 +137,10 @@ class VectorApplication : Application() {
|
||||
} else {
|
||||
//TODO check if notifications are enabled for this device
|
||||
//We need to use alarm in this mode
|
||||
AlarmSyncBroadcastReceiver.scheduleAlarm(applicationContext,4_000L)
|
||||
Timber.i("Alarm scheduled to restart service")
|
||||
if (Matrix.getInstance().currentSession != null) {
|
||||
AlarmSyncBroadcastReceiver.scheduleAlarm(applicationContext, 4_000L)
|
||||
Timber.i("Alarm scheduled to restart service")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -150,6 +152,7 @@ class VectorApplication : Application() {
|
||||
it.refreshPushers()
|
||||
//bind to the sync service
|
||||
get<PushRuleTriggerListener>().startWithSession(it)
|
||||
it.fetchPushRules()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ import android.widget.TextView
|
||||
import androidx.preference.PreferenceViewHolder
|
||||
import im.vector.riotredesign.R
|
||||
|
||||
// TODO Replace by real Bingrule class
|
||||
// TODO Replace by real Bingrule class, then delete
|
||||
class BingRule(rule: BingRule) {
|
||||
fun shouldNotNotify() = false
|
||||
fun shouldNotify() = false
|
||||
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.riotredesign.core.ui.list
|
||||
|
||||
import android.widget.TextView
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.riotredesign.R
|
||||
import im.vector.riotredesign.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.riotredesign.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.riotredesign.core.extensions.setTextOrHide
|
||||
|
||||
/**
|
||||
* A generic list item.
|
||||
* Displays an item with a title, and optional description.
|
||||
* Can display an accessory on the right, that can be an image or an indeterminate progress.
|
||||
* If provided with an action, will display a button at the bottom of the list item.
|
||||
*/
|
||||
@EpoxyModelClass(layout = R.layout.item_generic_footer)
|
||||
abstract class GenericFooterItem : VectorEpoxyModel<GenericFooterItem.Holder>() {
|
||||
|
||||
|
||||
@EpoxyAttribute
|
||||
var text: String? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var style: GenericItem.STYLE = GenericItem.STYLE.NORMAL_TEXT
|
||||
|
||||
@EpoxyAttribute
|
||||
var itemClickAction: GenericItem.Action? = null
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
|
||||
holder.text.setTextOrHide(text)
|
||||
when (style) {
|
||||
GenericItem.STYLE.BIG_TEXT -> holder.text.textSize = 18f
|
||||
GenericItem.STYLE.NORMAL_TEXT -> holder.text.textSize = 14f
|
||||
}
|
||||
|
||||
|
||||
holder.view.setOnClickListener {
|
||||
itemClickAction?.perform?.run()
|
||||
}
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
val text by bind<TextView>(R.id.itemGenericFooterText)
|
||||
}
|
||||
}
|
@ -78,6 +78,7 @@ class LoginActivity : VectorBaseActivity() {
|
||||
data.setFilter(FilterService.FilterPreset.RiotFilter)
|
||||
data.startSync()
|
||||
get<PushRuleTriggerListener>().startWithSession(data)
|
||||
data.fetchPushRules()
|
||||
goToHome()
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ class NotifiableEventResolver(val context: Context) {
|
||||
|
||||
//private val eventDisplay = RiotEventDisplay(context)
|
||||
|
||||
fun resolveEvent(event: Event/*, roomState: RoomState?*/, bingRule: PushRule?, session: Session): NotifiableEvent? {
|
||||
fun resolveEvent(event: Event/*, roomState: RoomState?, bingRule: PushRule?*/, session: Session): NotifiableEvent? {
|
||||
|
||||
|
||||
// val store = session.dataHandler.store
|
||||
@ -55,7 +55,7 @@ class NotifiableEventResolver(val context: Context) {
|
||||
|
||||
when (event.getClearType()) {
|
||||
EventType.MESSAGE -> {
|
||||
return resolveMessageEvent(event, bingRule, session)
|
||||
return resolveMessageEvent(event, session)
|
||||
}
|
||||
// EventType.ENCRYPTED -> {
|
||||
// val messageEvent = resolveMessageEvent(event, bingRule, session, store)
|
||||
@ -88,12 +88,10 @@ class NotifiableEventResolver(val context: Context) {
|
||||
}
|
||||
|
||||
|
||||
private fun resolveMessageEvent(event: Event, pushRule: PushRule?, session: Session): NotifiableEvent? {
|
||||
private fun resolveMessageEvent(event: Event, session: Session): NotifiableEvent? {
|
||||
//If we are here, that means that the event should be notified to the user, we check now how it should be presented (sound)
|
||||
// val soundName = pushRule?.notificationSound
|
||||
|
||||
val noisy = true//pushRule?.notificationSound != null
|
||||
|
||||
//The event only contains an eventId, and roomId (type is m.room.*) , we need to get the displayable content (names, avatar, text, etc...)
|
||||
val room = session.getRoom(event.roomId!! /*roomID cannot be null (see Matrix SDK code)*/)
|
||||
|
||||
@ -109,7 +107,7 @@ class NotifiableEventResolver(val context: Context) {
|
||||
val notifiableEvent = NotifiableMessageEvent(
|
||||
eventId = event.eventId ?: "",
|
||||
timestamp = event.originServerTs ?: 0,
|
||||
noisy = noisy,
|
||||
noisy = false,//will be updated
|
||||
senderName = senderDisplayName,
|
||||
senderId = event.senderId,
|
||||
body = body,
|
||||
@ -130,7 +128,7 @@ class NotifiableEventResolver(val context: Context) {
|
||||
val notifiableEvent = NotifiableMessageEvent(
|
||||
eventId = event.eventId!!,
|
||||
timestamp = event.originServerTs ?: 0,
|
||||
noisy = noisy,
|
||||
noisy = false,//will be updated
|
||||
senderName = senderDisplayName,
|
||||
senderId = event.senderId,
|
||||
body = body,
|
||||
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.riotredesign.features.notifications
|
||||
|
||||
import im.vector.matrix.android.api.pushrules.Action
|
||||
|
||||
data class NotificationAction(
|
||||
val shouldNotify: Boolean,
|
||||
val highlight: Boolean = false,
|
||||
val soundName: String? = null
|
||||
) {
|
||||
companion object {
|
||||
fun extractFrom(ruleActions: List<Action>): NotificationAction {
|
||||
var shouldNotify = false
|
||||
var highlight = false
|
||||
var sound: String? = null
|
||||
ruleActions.forEach {
|
||||
if (it.type == Action.Type.NOTIFY) shouldNotify = true
|
||||
if (it.type == Action.Type.DONT_NOTIFY) shouldNotify = false
|
||||
if (it.type == Action.Type.SET_TWEAK) {
|
||||
if (it.tweak_action == "highlight") highlight = it.boolValue ?: false
|
||||
if (it.tweak_action == "sound") sound = it.stringValue
|
||||
}
|
||||
}
|
||||
return NotificationAction(shouldNotify, highlight, sound)
|
||||
}
|
||||
}
|
||||
}
|
@ -57,28 +57,6 @@ class NotificationDrawerManager(val context: Context, private val outdatedDetect
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* No multi session support for now
|
||||
*/
|
||||
private fun initWithSession(session: Session?) {
|
||||
session?.let {
|
||||
/*
|
||||
myUserDisplayName = it.myUser?.displayname ?: it.myUserId
|
||||
|
||||
// User Avatar
|
||||
it.myUser?.avatarUrl?.let { avatarUrl ->
|
||||
val userAvatarUrlPath = it.mediaCache?.thumbnailCacheFile(avatarUrl, avatarSize)
|
||||
if (userAvatarUrlPath != null) {
|
||||
myUserAvatarUrl = userAvatarUrlPath.path
|
||||
} else {
|
||||
// prepare for the next time
|
||||
session.mediaCache?.loadAvatarThumbnail(session.homeServerConfig, ImageView(context), avatarUrl, avatarSize)
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Should be called as soon as a new event is ready to be displayed.
|
||||
The notification corresponding to this event will not be displayed until
|
||||
|
@ -16,12 +16,24 @@ class PushRuleTriggerListener(
|
||||
var session: Session? = null
|
||||
|
||||
override fun onMatchRule(event: Event, actions: List<Action>) {
|
||||
Timber.v("Push rule match for event ${event.eventId}")
|
||||
if (session == null) {
|
||||
Timber.e("Called without active session")
|
||||
return
|
||||
}
|
||||
resolver.resolveEvent(event,null,session!!)?.let {
|
||||
drawerManager.onNotifiableEventReceived(it)
|
||||
val notificationAction = NotificationAction.extractFrom(actions)
|
||||
if (notificationAction.shouldNotify) {
|
||||
val resolveEvent = resolver.resolveEvent(event, session!!)
|
||||
if (resolveEvent == null) {
|
||||
Timber.v("## Failed to resolve event")
|
||||
//TODO
|
||||
} else {
|
||||
resolveEvent.noisy = !notificationAction.soundName.isNullOrBlank()
|
||||
Timber.v("New event to notify $resolveEvent tweaks:$notificationAction")
|
||||
drawerManager.onNotifiableEventReceived(resolveEvent)
|
||||
}
|
||||
} else {
|
||||
Timber.v("Matched push rule is set to not notify")
|
||||
}
|
||||
}
|
||||
|
||||
@ -43,4 +55,5 @@ class PushRuleTriggerListener(
|
||||
drawerManager.clearAllEvents()
|
||||
drawerManager.refreshNotificationDrawer()
|
||||
}
|
||||
|
||||
}
|
@ -1671,15 +1671,15 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref
|
||||
|
||||
var index = 0
|
||||
|
||||
for (pusher in mDisplayedPushers) {
|
||||
if (null != pusher.lang) {
|
||||
val isThisDeviceTarget = TextUtils.equals(pushManager.currentRegistrationToken, pusher.pushkey)
|
||||
for (pushRule in mDisplayedPushers) {
|
||||
if (null != pushRule.lang) {
|
||||
val isThisDeviceTarget = TextUtils.equals(pushManager.currentRegistrationToken, pushRule.pushkey)
|
||||
|
||||
val preference = VectorPreference(activity).apply {
|
||||
mTypeface = if (isThisDeviceTarget) Typeface.BOLD else Typeface.NORMAL
|
||||
}
|
||||
preference.title = pusher.deviceDisplayName
|
||||
preference.summary = pusher.appDisplayName
|
||||
preference.title = pushRule.deviceDisplayName
|
||||
preference.summary = pushRule.appDisplayName
|
||||
preference.key = PUSHER_PREFERENCE_KEY_BASE + index
|
||||
index++
|
||||
mPushersSettingsCategory.addPreference(preference)
|
||||
@ -1694,7 +1694,7 @@ class VectorSettingsPreferencesFragment : VectorPreferenceFragment(), SharedPref
|
||||
.setPositiveButton(R.string.remove)
|
||||
{ _, _ ->
|
||||
displayLoadingView()
|
||||
pushManager.unregister(session, pusher, object : MatrixCallback<Unit> {
|
||||
pushManager.unregister(session, pushRule, object : MatrixCallback<Unit> {
|
||||
override fun onSuccess(info: Void?) {
|
||||
refreshPushersList()
|
||||
onCommonDone(null)
|
||||
|
@ -17,7 +17,6 @@
|
||||
package im.vector.riotredesign.features.settings.push
|
||||
|
||||
import android.os.Bundle
|
||||
import android.widget.LinearLayout
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
@ -27,19 +26,21 @@ import com.airbnb.mvrx.withState
|
||||
import im.vector.riotredesign.R
|
||||
import im.vector.riotredesign.core.platform.VectorBaseActivity
|
||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||
import kotlinx.android.synthetic.main.fragment_settings_pushgateways.*
|
||||
import im.vector.riotredesign.core.resources.StringProvider
|
||||
import im.vector.riotredesign.core.ui.list.genericFooterItem
|
||||
import kotlinx.android.synthetic.main.fragment_generic_recycler_epoxy.*
|
||||
|
||||
class PushGatewaysFragment : VectorBaseFragment() {
|
||||
|
||||
override fun getLayoutResId(): Int = R.layout.fragment_settings_pushgateways
|
||||
override fun getLayoutResId(): Int = R.layout.fragment_generic_recycler_epoxy
|
||||
|
||||
private val viewModel: PushGatewaysViewModel by fragmentViewModel(PushGatewaysViewModel::class)
|
||||
|
||||
private val epoxyController by lazy { PushGateWayController() }
|
||||
private val epoxyController by lazy { PushGateWayController(StringProvider(requireContext().resources)) }
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
(activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_push_gateways)
|
||||
(activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_notifications_targets)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
@ -56,13 +57,26 @@ class PushGatewaysFragment : VectorBaseFragment() {
|
||||
epoxyController.setData(it)
|
||||
}
|
||||
|
||||
class PushGateWayController : TypedEpoxyController<PushGatewayViewState>() {
|
||||
class PushGateWayController(private val stringProvider: StringProvider) : TypedEpoxyController<PushGatewayViewState>() {
|
||||
override fun buildModels(data: PushGatewayViewState?) {
|
||||
val pushers = data?.pushgateways?.invoke() ?: return
|
||||
pushers.forEach {
|
||||
pushGatewayItem {
|
||||
id("${it.pushKey}_${it.appId}")
|
||||
pusher(it)
|
||||
data?.pushgateways?.invoke()?.let { pushers ->
|
||||
if (pushers.isEmpty()) {
|
||||
genericFooterItem {
|
||||
id("footer")
|
||||
text(stringProvider.getString(R.string.settings_push_gateway_no_pushers))
|
||||
}
|
||||
} else {
|
||||
pushers.forEach {
|
||||
pushGatewayItem {
|
||||
id("${it.pushKey}_${it.appId}")
|
||||
pusher(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
} ?: run {
|
||||
genericFooterItem {
|
||||
id("footer")
|
||||
text(stringProvider.getString(R.string.loading))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,71 @@
|
||||
package im.vector.riotredesign.features.settings.push
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.graphics.Color
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.core.view.isVisible
|
||||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import com.airbnb.epoxy.EpoxyModelWithHolder
|
||||
import im.vector.matrix.android.api.pushrules.Action
|
||||
import im.vector.matrix.android.api.pushrules.rest.PushRule
|
||||
import im.vector.riotredesign.R
|
||||
import im.vector.riotredesign.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.riotredesign.features.notifications.NotificationAction
|
||||
|
||||
|
||||
@EpoxyModelClass(layout = R.layout.item_pushrule_raw)
|
||||
abstract class PushRuleItem : EpoxyModelWithHolder<PushRuleItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
lateinit var pushRule: PushRule
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
override fun bind(holder: Holder) {
|
||||
val context = holder.view.context
|
||||
if (pushRule.enabled) {
|
||||
holder.view.setBackgroundColor(Color.TRANSPARENT)
|
||||
holder.ruleId.text = pushRule.ruleId
|
||||
} else {
|
||||
holder.view.setBackgroundColor(ContextCompat.getColor(context, R.color.vector_silver_color))
|
||||
holder.ruleId.text = "[Disabled] ${pushRule.ruleId}"
|
||||
}
|
||||
val actions = Action.mapFrom(pushRule)
|
||||
if (actions.isNullOrEmpty()) {
|
||||
holder.actionIcon.isInvisible = true
|
||||
} else {
|
||||
holder.actionIcon.isVisible = true
|
||||
val notifAction = NotificationAction.extractFrom(actions)
|
||||
|
||||
if (notifAction.shouldNotify && !notifAction.soundName.isNullOrBlank()) {
|
||||
holder.actionIcon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_action_notify_noisy))
|
||||
} else if (notifAction.shouldNotify) {
|
||||
holder.actionIcon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_action_notify_silent))
|
||||
} else {
|
||||
holder.actionIcon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_action_dont_notify))
|
||||
}
|
||||
|
||||
var description = StringBuffer()
|
||||
pushRule.conditions?.forEachIndexed { i, condition ->
|
||||
if (i > 0) description.append("\n")
|
||||
description.append(condition.asExecutableCondition()?.technicalDescription()
|
||||
?: "UNSUPPORTED")
|
||||
}
|
||||
if (description.isBlank()) {
|
||||
holder.description.text = "No Conditions"
|
||||
} else {
|
||||
holder.description.text = description
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
val ruleId by bind<TextView>(R.id.pushRuleId)
|
||||
val description by bind<TextView>(R.id.pushRuleDescription)
|
||||
val actionIcon by bind<ImageView>(R.id.pushRuleActionIcon)
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.riotredesign.features.settings.push
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.airbnb.epoxy.TypedEpoxyController
|
||||
import com.airbnb.mvrx.fragmentViewModel
|
||||
import com.airbnb.mvrx.withState
|
||||
import im.vector.riotredesign.R
|
||||
import im.vector.riotredesign.core.platform.VectorBaseActivity
|
||||
import im.vector.riotredesign.core.platform.VectorBaseFragment
|
||||
import im.vector.riotredesign.core.resources.StringProvider
|
||||
import im.vector.riotredesign.core.ui.list.genericFooterItem
|
||||
import kotlinx.android.synthetic.main.fragment_generic_recycler_epoxy.*
|
||||
|
||||
|
||||
class PushRulesFragment : VectorBaseFragment() {
|
||||
|
||||
override fun getLayoutResId(): Int = R.layout.fragment_generic_recycler_epoxy
|
||||
|
||||
private val viewModel: PushRulesViewModel by fragmentViewModel(PushRulesViewModel::class)
|
||||
|
||||
private val epoxyController by lazy { PushRulesFragment.PushRulesController(StringProvider(requireContext().resources)) }
|
||||
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
(activity as? VectorBaseActivity)?.supportActionBar?.setTitle(R.string.settings_push_rules)
|
||||
}
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
val lmgr = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
|
||||
epoxyRecyclerView.layoutManager = lmgr
|
||||
val dividerItemDecoration = DividerItemDecoration(epoxyRecyclerView.context,
|
||||
lmgr.orientation)
|
||||
epoxyRecyclerView.addItemDecoration(dividerItemDecoration)
|
||||
epoxyRecyclerView.adapter = epoxyController.adapter
|
||||
}
|
||||
|
||||
override fun invalidate() = withState(viewModel) {
|
||||
epoxyController.setData(it)
|
||||
}
|
||||
|
||||
class PushRulesController(private val stringProvider: StringProvider) : TypedEpoxyController<PushRulesViewState>() {
|
||||
|
||||
override fun buildModels(data: PushRulesViewState?) {
|
||||
data?.let {
|
||||
it.rules.forEach {
|
||||
pushRuleItem {
|
||||
id(it.ruleId)
|
||||
pushRule(it)
|
||||
}
|
||||
}
|
||||
} ?: run {
|
||||
genericFooterItem {
|
||||
id("footer")
|
||||
text(stringProvider.getString(R.string.settings_push_rules_no_rules))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.riotredesign.features.settings.push
|
||||
|
||||
import com.airbnb.mvrx.MvRxState
|
||||
import com.airbnb.mvrx.MvRxViewModelFactory
|
||||
import com.airbnb.mvrx.ViewModelContext
|
||||
import im.vector.matrix.android.api.pushrules.rest.PushRule
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.riotredesign.core.platform.VectorViewModel
|
||||
import org.koin.android.ext.android.get
|
||||
|
||||
data class PushRulesViewState(
|
||||
val rules: List<PushRule> = emptyList())
|
||||
: MvRxState
|
||||
|
||||
|
||||
class PushRulesViewModel(initialState: PushRulesViewState) : VectorViewModel<PushRulesViewState>(initialState) {
|
||||
|
||||
companion object : MvRxViewModelFactory<PushRulesViewModel, PushRulesViewState> {
|
||||
|
||||
override fun initialState(viewModelContext: ViewModelContext): PushRulesViewState? {
|
||||
val session = viewModelContext.activity.get<Session>()
|
||||
val rules = session.getPushrules()
|
||||
|
||||
return PushRulesViewState(rules)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
25
vector/src/main/res/drawable/ic_action_dont_notify.xml
Normal file
25
vector/src/main/res/drawable/ic_action_dont_notify.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="34dp"
|
||||
android:height="34dp"
|
||||
android:viewportWidth="34"
|
||||
android:viewportHeight="34">
|
||||
<path
|
||||
android:pathData="M9.7169,15L9.7169,20.2316L7.5734,23.7393C7.5254,23.8178 7.5,23.908 7.5,24C7.5,24.2761 7.7239,24.5 8,24.5L26.4339,24.5C26.5259,24.5 26.6161,24.4746 26.6946,24.4266C26.9302,24.2826 27.0045,23.9749 26.8605,23.7393L24.7169,20.2316L24.7169,15C24.7169,11.558 22.3785,8.582 19.0923,7.7363L18.7169,7.6396L18.7169,6C18.7169,5.1716 18.0454,4.5 17.2169,4.5C16.3885,4.5 15.7169,5.1716 15.7169,6L15.7169,7.6396L15.3416,7.7363C12.0554,8.582 9.7169,11.558 9.7169,15ZM14.797,26.5C15.0741,27.3506 16.0402,28 17.2169,28C18.3937,28 19.3598,27.3506 19.6369,26.5L14.797,26.5Z"
|
||||
android:strokeWidth="1"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#224955"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M17,17m-16,0a16,16 0,1 1,32 0a16,16 0,1 1,-32 0"
|
||||
android:strokeWidth="1"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#224955"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M4.5,27.25L28.2169,6"
|
||||
android:strokeWidth="1"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#224955"
|
||||
android:fillType="evenOdd"
|
||||
android:strokeLineCap="square"/>
|
||||
</vector>
|
18
vector/src/main/res/drawable/ic_action_notify_noisy.xml
Normal file
18
vector/src/main/res/drawable/ic_action_notify_noisy.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="21dp"
|
||||
android:height="25dp"
|
||||
android:viewportWidth="21"
|
||||
android:viewportHeight="25">
|
||||
<path
|
||||
android:pathData="M2.7169,11L2.7169,16.2316L0.5734,19.7393C0.5254,19.8178 0.5,19.908 0.5,20C0.5,20.2761 0.7239,20.5 1,20.5L19.4339,20.5C19.5259,20.5 19.6161,20.4746 19.6946,20.4266C19.9302,20.2826 20.0045,19.9749 19.8605,19.7393L17.7169,16.2316L17.7169,11C17.7169,7.558 15.3785,4.582 12.0923,3.7363L11.7169,3.6396L11.7169,2C11.7169,1.1716 11.0454,0.5 10.2169,0.5C9.3885,0.5 8.7169,1.1716 8.7169,2L8.7169,3.6396L8.3416,3.7363C5.0554,4.582 2.7169,7.558 2.7169,11ZM7.797,22.5C8.0741,23.3506 9.0402,24 10.2169,24C11.3937,24 12.3598,23.3506 12.6369,22.5L7.797,22.5Z"
|
||||
android:strokeWidth="1"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#224955"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M16,7m-4,0a4,4 0,1 1,8 0a4,4 0,1 1,-8 0"
|
||||
android:strokeWidth="1"
|
||||
android:fillColor="#E8707B"
|
||||
android:fillType="evenOdd"
|
||||
android:strokeColor="#00000000"/>
|
||||
</vector>
|
24
vector/src/main/res/drawable/ic_action_notify_silent.xml
Normal file
24
vector/src/main/res/drawable/ic_action_notify_silent.xml
Normal file
@ -0,0 +1,24 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="23dp"
|
||||
android:height="26dp"
|
||||
android:viewportWidth="23"
|
||||
android:viewportHeight="26">
|
||||
<path
|
||||
android:pathData="M2.7169,12L2.7169,17.2316L0.5734,20.7393C0.5254,20.8178 0.5,20.908 0.5,21C0.5,21.2761 0.7239,21.5 1,21.5L19.4339,21.5C19.5259,21.5 19.6161,21.4746 19.6946,21.4266C19.9302,21.2826 20.0045,20.9749 19.8605,20.7393L17.7169,17.2316L17.7169,12C17.7169,8.558 15.3785,5.582 12.0923,4.7363L11.7169,4.6396L11.7169,3C11.7169,2.1716 11.0454,1.5 10.2169,1.5C9.3885,1.5 8.7169,2.1716 8.7169,3L8.7169,4.6396L8.3416,4.7363C5.0554,5.582 2.7169,8.558 2.7169,12ZM7.797,23.5C8.0741,24.3506 9.0402,25 10.2169,25C11.3937,25 12.3598,24.3506 12.6369,23.5L7.797,23.5Z"
|
||||
android:strokeWidth="1"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#224955"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M17.5522,4.7158l1.1133,0l0,0.2842l-1.5366,0l0,-0.2227l1.0708,-1.6245l-1.062,0l0,-0.2856l1.4912,0l0,0.2139z"
|
||||
android:strokeWidth="1"
|
||||
android:fillColor="#4A4A4A"
|
||||
android:fillType="evenOdd"
|
||||
android:strokeColor="#00000000"/>
|
||||
<path
|
||||
android:pathData="M20.1045,4.4316l2.2266,0l0,0.5684l-3.0732,0l0,-0.4453l2.1416,-3.249l-2.124,0l0,-0.5713l2.9824,0l0,0.4277z"
|
||||
android:strokeWidth="1"
|
||||
android:fillColor="#4A4A4A"
|
||||
android:fillType="evenOdd"
|
||||
android:strokeColor="#00000000"/>
|
||||
</vector>
|
16
vector/src/main/res/layout/item_generic_footer.xml
Normal file
16
vector/src/main/res/layout/item_generic_footer.xml
Normal file
@ -0,0 +1,16 @@
|
||||
<?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:orientation="vertical"
|
||||
android:padding="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/itemGenericFooterText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
tools:text="Empty list, nothing here" />
|
||||
|
||||
</LinearLayout>
|
43
vector/src/main/res/layout/item_pushrule_raw.xml
Normal file
43
vector/src/main/res/layout/item_pushrule_raw.xml
Normal file
@ -0,0 +1,43 @@
|
||||
<?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:orientation="horizontal"
|
||||
android:padding="8dp">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pushRuleId"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
tools:text=".m.rule.contains_user_name"
|
||||
android:textStyle="bold" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pushRuleDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:textStyle=""
|
||||
tools:text="content matches valere" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/pushRuleActionIcon"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
tools:src="@drawable/ic_action_dont_notify" />
|
||||
|
||||
</LinearLayout>
|
@ -17,6 +17,8 @@
|
||||
<string name="settings_preferences">Preferences</string>
|
||||
<string name="settings_security_and_privacy">Security & Privacy</string>
|
||||
<string name="settings_expert">Expert</string>
|
||||
<string name="settings_push_gateways">Push Gateways</string>
|
||||
<string name="settings_push_rules">Push Rules</string>
|
||||
<string name="settings_push_rules_no_rules">No push rules defined</string>
|
||||
<string name="settings_push_gateway_no_pushers">No registered push gateways</string>
|
||||
|
||||
</resources>
|
@ -2,14 +2,15 @@
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<SwitchPreference
|
||||
android:key="SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY"
|
||||
android:title="@string/settings_enable_all_notif" />
|
||||
<!--<SwitchPreference-->
|
||||
<!--android:key="SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY"-->
|
||||
<!--android:title="@string/settings_enable_all_notif" />-->
|
||||
|
||||
<SwitchPreference
|
||||
android:dependency="SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY"
|
||||
|
||||
android:key="SETTINGS_ENABLE_THIS_DEVICE_PREFERENCE_KEY"
|
||||
android:title="@string/settings_enable_this_device" />
|
||||
<!--android:dependency="SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY"-->
|
||||
|
||||
<!--<im.vector.riotredesign.core.preference.VectorSwitchPreference-->
|
||||
<!--android:dependency="SETTINGS_ENABLE_ALL_NOTIF_PREFERENCE_KEY"-->
|
||||
@ -27,6 +28,7 @@
|
||||
android:persistent="false"
|
||||
android:summary="@string/settings_notification_advanced_summary"
|
||||
android:title="@string/settings_notification_advanced"
|
||||
android:enabled="false"
|
||||
app:fragment="im.vector.fragments.VectorSettingsNotificationsAdvancedFragment" />
|
||||
|
||||
<Preference
|
||||
@ -38,8 +40,15 @@
|
||||
|
||||
<Preference
|
||||
android:layout_width="match_parent"
|
||||
android:title="@string/settings_push_gateways"
|
||||
android:title="@string/settings_notifications_targets"
|
||||
android:persistent="false"
|
||||
app:fragment="im.vector.riotredesign.features.settings.push.PushGatewaysFragment" />
|
||||
|
||||
<Preference
|
||||
android:layout_width="match_parent"
|
||||
android:title="@string/settings_push_rules"
|
||||
android:persistent="false"
|
||||
app:fragment="im.vector.riotredesign.features.settings.push.PushRulesFragment" />
|
||||
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
Reference in New Issue
Block a user