Skip to content

Commit

Permalink
Add capability to add and remove a room from the favorites (#1217)
Browse files Browse the repository at this point in the history
  • Loading branch information
bmarty committed Jun 9, 2020
1 parent 0a7f77e commit d8317f7
Show file tree
Hide file tree
Showing 25 changed files with 395 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Improvements 🙌:
- Correctly handle SSO login redirection
- SSO login is now performed in the default browser, or in Chrome Custom tab if available (#1400)
- Improve checking of homeserver version support (#1442)
- Add capability to add and remove a room from the favorites (#1217)

Bugfix 🐛:
- Switch theme is not fully taken into account without restarting the app
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import im.vector.matrix.android.api.session.room.reporting.ReportingService
import im.vector.matrix.android.api.session.room.send.DraftService
import im.vector.matrix.android.api.session.room.send.SendService
import im.vector.matrix.android.api.session.room.state.StateService
import im.vector.matrix.android.api.session.room.tags.TagsService
import im.vector.matrix.android.api.session.room.timeline.TimelineService
import im.vector.matrix.android.api.session.room.typing.TypingService
import im.vector.matrix.android.api.session.room.uploads.UploadsService
Expand All @@ -41,6 +42,7 @@ interface Room :
DraftService,
ReadService,
TypingService,
TagsService,
MembershipService,
StateService,
UploadsService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ data class RoomSummary constructor(
val hasNewMessages: Boolean
get() = notificationCount != 0

val isFavorite: Boolean
get() = tags.any { it.name == RoomTag.ROOM_TAG_FAVOURITE }

companion object {
const val NOT_IN_BREADCRUMBS = -1
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@ data class RoomTag(
) {

companion object {
val ROOM_TAG_FAVOURITE = "m.favourite"
val ROOM_TAG_LOW_PRIORITY = "m.lowpriority"
val ROOM_TAG_NO_TAG = "m.recent"
val ROOM_TAG_SERVER_NOTICE = "m.server_notice"
const val ROOM_TAG_FAVOURITE = "m.favourite"
const val ROOM_TAG_LOW_PRIORITY = "m.lowpriority"
const val ROOM_TAG_SERVER_NOTICE = "m.server_notice"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (c) 2020 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.matrix.android.api.session.room.tags

import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.util.Cancelable

/**
* This interface defines methods to handle tags of a room. It's implemented at the room level.
*/
interface TagsService {
/**
* Add a tag to a room
*/
fun addTag(tag: String, order: Double?, callback: MatrixCallback<Unit>): Cancelable

/**
* Remove tag form a room
*/
fun deleteTag(tag: String, callback: MatrixCallback<Unit>): Cancelable
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import im.vector.matrix.android.api.session.room.reporting.ReportingService
import im.vector.matrix.android.api.session.room.send.DraftService
import im.vector.matrix.android.api.session.room.send.SendService
import im.vector.matrix.android.api.session.room.state.StateService
import im.vector.matrix.android.api.session.room.tags.TagsService
import im.vector.matrix.android.api.session.room.timeline.TimelineService
import im.vector.matrix.android.api.session.room.typing.TypingService
import im.vector.matrix.android.api.session.room.uploads.UploadsService
Expand Down Expand Up @@ -59,6 +60,7 @@ internal class DefaultRoom @Inject constructor(override val roomId: String,
private val reportingService: ReportingService,
private val readService: ReadService,
private val typingService: TypingService,
private val tagsService: TagsService,
private val cryptoService: CryptoService,
private val relationService: RelationService,
private val roomMembersService: MembershipService,
Expand All @@ -74,6 +76,7 @@ internal class DefaultRoom @Inject constructor(override val roomId: String,
ReportingService by reportingService,
ReadService by readService,
TypingService by typingService,
TagsService by tagsService,
RelationService by relationService,
MembershipService by roomMembersService,
RoomPushRuleService by roomPushRuleService {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ import im.vector.matrix.android.internal.session.room.membership.joining.InviteB
import im.vector.matrix.android.internal.session.room.relation.RelationsResponse
import im.vector.matrix.android.internal.session.room.reporting.ReportContentBody
import im.vector.matrix.android.internal.session.room.send.SendResponse
import im.vector.matrix.android.internal.session.room.tags.TagBody
import im.vector.matrix.android.internal.session.room.timeline.EventContextResponse
import im.vector.matrix.android.internal.session.room.timeline.PaginationResponse
import im.vector.matrix.android.internal.session.room.typing.TypingBody
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.Headers
import retrofit2.http.POST
Expand Down Expand Up @@ -288,4 +290,25 @@ internal interface RoomAPI {
fun sendTypingState(@Path("roomId") roomId: String,
@Path("userId") userId: String,
@Body body: TypingBody): Call<Unit>

/**
* Room tagging
*/

/**
* Add a tag to a room.
*/
@PUT(NetworkConstants.URI_API_PREFIX_PATH_R0 + "user/{userId}/rooms/{roomId}/tags/{tag}")
fun putTag(@Path("userId") userId: String,
@Path("roomId") roomId: String,
@Path("tag") tag: String,
@Body body: TagBody): Call<Unit>

/**
* Delete a tag from a room.
*/
@DELETE(NetworkConstants.URI_API_PREFIX_PATH_R0 + "user/{userId}/rooms/{roomId}/tags/{tag}")
fun deleteTag(@Path("userId") userId: String,
@Path("roomId") roomId: String,
@Path("tag") tag: String): Call<Unit>
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import im.vector.matrix.android.internal.session.room.reporting.DefaultReporting
import im.vector.matrix.android.internal.session.room.send.DefaultSendService
import im.vector.matrix.android.internal.session.room.state.DefaultStateService
import im.vector.matrix.android.internal.session.room.state.SendStateTask
import im.vector.matrix.android.internal.session.room.tags.DefaultTagsService
import im.vector.matrix.android.internal.session.room.timeline.DefaultTimelineService
import im.vector.matrix.android.internal.session.room.typing.DefaultTypingService
import im.vector.matrix.android.internal.session.room.uploads.DefaultUploadsService
Expand All @@ -52,6 +53,7 @@ internal class DefaultRoomFactory @Inject constructor(private val monarchy: Mona
private val reportingServiceFactory: DefaultReportingService.Factory,
private val readServiceFactory: DefaultReadService.Factory,
private val typingServiceFactory: DefaultTypingService.Factory,
private val tagsServiceFactory: DefaultTagsService.Factory,
private val relationServiceFactory: DefaultRelationService.Factory,
private val membershipServiceFactory: DefaultMembershipService.Factory,
private val roomPushRuleServiceFactory: DefaultRoomPushRuleService.Factory,
Expand All @@ -72,6 +74,7 @@ internal class DefaultRoomFactory @Inject constructor(private val monarchy: Mona
reportingService = reportingServiceFactory.create(roomId),
readService = readServiceFactory.create(roomId),
typingService = typingServiceFactory.create(roomId),
tagsService = tagsServiceFactory.create(roomId),
cryptoService = cryptoService,
relationService = relationServiceFactory.create(roomId),
roomMembersService = membershipServiceFactory.create(roomId),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ import im.vector.matrix.android.internal.session.room.reporting.DefaultReportCon
import im.vector.matrix.android.internal.session.room.reporting.ReportContentTask
import im.vector.matrix.android.internal.session.room.state.DefaultSendStateTask
import im.vector.matrix.android.internal.session.room.state.SendStateTask
import im.vector.matrix.android.internal.session.room.tags.AddTagToRoomTask
import im.vector.matrix.android.internal.session.room.tags.DefaultAddTagToRoomTask
import im.vector.matrix.android.internal.session.room.tags.DefaultDeleteTagFromRoomTask
import im.vector.matrix.android.internal.session.room.tags.DeleteTagFromRoomTask
import im.vector.matrix.android.internal.session.room.timeline.DefaultFetchNextTokenAndPaginateTask
import im.vector.matrix.android.internal.session.room.timeline.DefaultGetContextOfEventTask
import im.vector.matrix.android.internal.session.room.timeline.DefaultPaginationTask
Expand Down Expand Up @@ -186,4 +190,10 @@ internal abstract class RoomModule {

@Binds
abstract fun bindGetUploadsTask(task: DefaultGetUploadsTask): GetUploadsTask

@Binds
abstract fun bindAddTagToRoomTask(task: DefaultAddTagToRoomTask): AddTagToRoomTask

@Binds
abstract fun bindDeleteTagFromRoomTask(task: DefaultDeleteTagFromRoomTask): DeleteTagFromRoomTask
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright (c) 2020 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.matrix.android.internal.session.room.tags

import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.room.RoomAPI
import im.vector.matrix.android.internal.task.Task
import org.greenrobot.eventbus.EventBus
import javax.inject.Inject

internal interface AddTagToRoomTask : Task<AddTagToRoomTask.Params, Unit> {

data class Params(
val roomId: String,
val tag: String,
val order: Double?
)
}

internal class DefaultAddTagToRoomTask @Inject constructor(
private val roomAPI: RoomAPI,
@UserId private val userId: String,
private val eventBus: EventBus
) : AddTagToRoomTask {

override suspend fun execute(params: AddTagToRoomTask.Params) {
executeRequest<Unit>(eventBus) {
apiCall = roomAPI.putTag(
userId = userId,
roomId = params.roomId,
tag = params.tag,
body = TagBody(
order = params.order
)
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2020 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.matrix.android.internal.session.room.tags

import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject
import im.vector.matrix.android.api.MatrixCallback
import im.vector.matrix.android.api.session.room.tags.TagsService
import im.vector.matrix.android.api.util.Cancelable
import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.task.configureWith

internal class DefaultTagsService @AssistedInject constructor(
@Assisted private val roomId: String,
private val taskExecutor: TaskExecutor,
private val addTagToRoomTask: AddTagToRoomTask,
private val deleteTagFromRoomTask: DeleteTagFromRoomTask
) : TagsService {

@AssistedInject.Factory
interface Factory {
fun create(roomId: String): TagsService
}

override fun addTag(tag: String, order: Double?, callback: MatrixCallback<Unit>): Cancelable {
val params = AddTagToRoomTask.Params(roomId, tag, order)
return addTagToRoomTask
.configureWith(params) {
this.callback = callback
}
.executeBy(taskExecutor)
}

override fun deleteTag(tag: String, callback: MatrixCallback<Unit>): Cancelable {
val params = DeleteTagFromRoomTask.Params(roomId, tag)
return deleteTagFromRoomTask
.configureWith(params) {
this.callback = callback
}
.executeBy(taskExecutor)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2020 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.matrix.android.internal.session.room.tags

import im.vector.matrix.android.internal.di.UserId
import im.vector.matrix.android.internal.network.executeRequest
import im.vector.matrix.android.internal.session.room.RoomAPI
import im.vector.matrix.android.internal.task.Task
import org.greenrobot.eventbus.EventBus
import javax.inject.Inject

internal interface DeleteTagFromRoomTask : Task<DeleteTagFromRoomTask.Params, Unit> {

data class Params(
val roomId: String,
val tag: String
)
}

internal class DefaultDeleteTagFromRoomTask @Inject constructor(
private val roomAPI: RoomAPI,
@UserId private val userId: String,
private val eventBus: EventBus
) : DeleteTagFromRoomTask {

override suspend fun execute(params: DeleteTagFromRoomTask.Params) {
executeRequest<Unit>(eventBus) {
apiCall = roomAPI.deleteTag(
userId = userId,
roomId = params.roomId,
tag = params.tag
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2020 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.matrix.android.internal.session.room.tags

import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass

@JsonClass(generateAdapter = true)
internal data class TagBody(
/**
* A number in a range [0,1] describing a relative position of the room under the given tag.
*/
@Json(name = "order")
val order: Double?
)

0 comments on commit d8317f7

Please sign in to comment.