diff --git a/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentPreviewController.kt b/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentPreviewController.kt deleted file mode 100644 index 273fd4272c..0000000000 --- a/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentPreviewController.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 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.riotx.features.attachments.preview - -import com.airbnb.epoxy.TypedEpoxyController -import javax.inject.Inject - -class AttachmentPreviewController @Inject constructor() : TypedEpoxyController() { - - override fun buildModels(data: AttachmentsPreviewViewState) { - data.attachments.forEach { - - } - } -} diff --git a/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentPreviewControllers.kt b/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentPreviewControllers.kt new file mode 100644 index 0000000000..9cef33d402 --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentPreviewControllers.kt @@ -0,0 +1,54 @@ +/* + * Copyright 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.riotx.features.attachments.preview + +import com.airbnb.epoxy.TypedEpoxyController +import im.vector.matrix.android.api.session.content.ContentAttachmentData +import javax.inject.Inject + +class AttachmentBigPreviewController @Inject constructor() : TypedEpoxyController() { + + override fun buildModels(data: AttachmentsPreviewViewState) { + data.attachments.forEach { + attachmentBigPreviewItem { + id(it.path) + attachment(it) + } + } + } +} + +class AttachmentMiniaturePreviewController @Inject constructor() : TypedEpoxyController() { + + interface Callback { + fun onAttachmentClicked(contentAttachmentData: ContentAttachmentData) + } + + var callback: Callback? = null + + override fun buildModels(data: AttachmentsPreviewViewState) { + data.attachments.forEach { + attachmentMiniaturePreviewItem { + id(it.path) + attachment(it) + clickListener { _ -> + callback?.onAttachmentClicked(it) + } + } + } + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentPreviewItem.kt b/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentPreviewItem.kt deleted file mode 100644 index 03ac160d62..0000000000 --- a/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentPreviewItem.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 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.riotx.features.attachments.preview - -import android.view.View -import android.widget.ImageView -import com.airbnb.epoxy.EpoxyAttribute -import com.airbnb.epoxy.EpoxyModelClass -import com.bumptech.glide.Glide -import com.bumptech.glide.request.RequestOptions -import im.vector.matrix.android.api.session.content.ContentAttachmentData -import im.vector.riotx.R -import im.vector.riotx.core.epoxy.VectorEpoxyHolder -import im.vector.riotx.core.epoxy.VectorEpoxyModel -import kotlinx.android.synthetic.main.item_attachment_preview.view.* - -@EpoxyModelClass(layout = R.layout.item_attachment_preview) -abstract class AttachmentPreviewItem : VectorEpoxyModel() { - - @EpoxyAttribute lateinit var attachment: ContentAttachmentData - @EpoxyAttribute var clickListener: View.OnClickListener? = null - - override fun bind(holder: Holder) { - holder.view.setOnClickListener(clickListener) - // If name is empty, use userId as name and force it being centered - val mimeType = attachment.mimeType - val path = attachment.path - if (mimeType != null && (mimeType.startsWith("image") || mimeType.startsWith("video"))) { - Glide.with(holder.view.context) - .asBitmap() - .load(path) - .apply(RequestOptions().frame(0)) - .into(holder.imageView) - } else { - holder.imageView.attachmentPreviewImageView.setImageResource(R.drawable.filetype_attachment) - holder.imageView.attachmentPreviewImageView.scaleType = ImageView.ScaleType.FIT_CENTER - } - } - - class Holder : VectorEpoxyHolder() { - val imageView by bind(R.id.attachmentPreviewImageView) - } -} diff --git a/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentPreviewItems.kt b/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentPreviewItems.kt new file mode 100644 index 0000000000..24d7b312ec --- /dev/null +++ b/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentPreviewItems.kt @@ -0,0 +1,82 @@ +/* + * Copyright 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.riotx.features.attachments.preview + +import android.view.View +import android.widget.ImageView +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import com.bumptech.glide.Glide +import com.bumptech.glide.request.RequestOptions +import im.vector.matrix.android.api.session.content.ContentAttachmentData +import im.vector.riotx.R +import im.vector.riotx.core.epoxy.VectorEpoxyHolder +import im.vector.riotx.core.epoxy.VectorEpoxyModel + +abstract class AttachmentPreviewItem : VectorEpoxyModel() { + + abstract val attachment: ContentAttachmentData + + override fun bind(holder: H) { + val path = attachment.path + if (attachment.type == ContentAttachmentData.Type.VIDEO || attachment.type == ContentAttachmentData.Type.IMAGE) { + Glide.with(holder.view.context) + .asBitmap() + .load(path) + .apply(RequestOptions().frame(0)) + .into(holder.imageView) + } else { + holder.imageView.setImageResource(R.drawable.filetype_attachment) + holder.imageView.scaleType = ImageView.ScaleType.FIT_CENTER + } + } + + abstract class Holder : VectorEpoxyHolder() { + abstract val imageView: ImageView + } +} + +@EpoxyModelClass(layout = R.layout.item_attachment_miniature_preview) +abstract class AttachmentMiniaturePreviewItem : AttachmentPreviewItem() { + + @EpoxyAttribute override lateinit var attachment: ContentAttachmentData + @EpoxyAttribute + var clickListener: View.OnClickListener? = null + + override fun bind(holder: Holder) { + super.bind(holder) + holder.view.setOnClickListener(clickListener) + } + + class Holder : AttachmentPreviewItem.Holder() { + override val imageView: ImageView + get() = miniatureImageView + private val miniatureImageView by bind(R.id.attachmentMiniatureImageView) + } +} + +@EpoxyModelClass(layout = R.layout.item_attachment_big_preview) +abstract class AttachmentBigPreviewItem : AttachmentPreviewItem() { + + @EpoxyAttribute override lateinit var attachment: ContentAttachmentData + + class Holder : AttachmentPreviewItem.Holder() { + override val imageView: ImageView + get() = bigImageView + private val bigImageView by bind(R.id.attachmentBigImageView) + } +} diff --git a/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentsPreviewActivity.kt b/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentsPreviewActivity.kt index 509be251c3..d8d19cd550 100644 --- a/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentsPreviewActivity.kt +++ b/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentsPreviewActivity.kt @@ -19,6 +19,8 @@ package im.vector.riotx.features.attachments.preview import android.content.Context import android.content.Intent +import android.os.Bundle +import android.view.WindowManager import androidx.appcompat.widget.Toolbar import im.vector.riotx.R import im.vector.riotx.core.extensions.addFragment @@ -30,9 +32,10 @@ class AttachmentsPreviewActivity : VectorBaseActivity(), ToolbarConfigurable { companion object { private const val EXTRA_FRAGMENT_ARGS = "EXTRA_FRAGMENT_ARGS" + const val REQUEST_CODE = 55 fun newIntent(context: Context, args: AttachmentsPreviewArgs): Intent { - return Intent(context, AttachmentsPreviewArgs::class.java).apply { + return Intent(context, AttachmentsPreviewActivity::class.java).apply { putExtra(EXTRA_FRAGMENT_ARGS, args) } } @@ -40,6 +43,11 @@ class AttachmentsPreviewActivity : VectorBaseActivity(), ToolbarConfigurable { override fun getLayoutRes() = R.layout.activity_simple + override fun onCreate(savedInstanceState: Bundle?) { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS) + super.onCreate(savedInstanceState) + } + override fun initUiAndData() { if (isFirstCreation()) { val fragmentArgs: AttachmentsPreviewArgs = intent?.extras?.getParcelable(EXTRA_FRAGMENT_ARGS) diff --git a/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentsPreviewFragment.kt b/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentsPreviewFragment.kt index 6e99758c6d..99280c3830 100644 --- a/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentsPreviewFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/attachments/preview/AttachmentsPreviewFragment.kt @@ -20,13 +20,14 @@ package im.vector.riotx.features.attachments.preview import android.os.Bundle import android.os.Parcelable import android.view.View +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.PagerSnapHelper import com.airbnb.mvrx.args import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import im.vector.matrix.android.api.session.content.ContentAttachmentData import im.vector.riotx.R import im.vector.riotx.core.extensions.cleanup -import im.vector.riotx.core.extensions.configureWith import im.vector.riotx.core.platform.VectorBaseFragment import kotlinx.android.parcel.Parcelize import kotlinx.android.synthetic.main.fragment_attachments_preview.* @@ -39,8 +40,9 @@ data class AttachmentsPreviewArgs( class AttachmentsPreviewFragment @Inject constructor( val viewModelFactory: AttachmentsPreviewViewModel.Factory, - private val attachmentPreviewController: AttachmentPreviewController -) : VectorBaseFragment() { + private val attachmentMiniaturePreviewController: AttachmentMiniaturePreviewController, + private val attachmentBigPreviewController: AttachmentBigPreviewController +) : VectorBaseFragment(), AttachmentMiniaturePreviewController.Callback { private val fragmentArgs: AttachmentsPreviewArgs by args() private val viewModel: AttachmentsPreviewViewModel by fragmentViewModel() @@ -49,19 +51,36 @@ class AttachmentsPreviewFragment @Inject constructor( override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - setupRecyclerView() + setupRecyclerViews() + setupToolbar(attachmentPreviewerToolbar) } override fun onDestroyView() { super.onDestroyView() - attachmentPreviewerList.cleanup() + attachmentPreviewerMiniatureList.cleanup() } - private fun setupRecyclerView() { - attachmentPreviewerList.configureWith(attachmentPreviewController, hasFixedSize = true) + private fun setupRecyclerViews() { + attachmentPreviewerMiniatureList.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) + attachmentPreviewerMiniatureList.setHasFixedSize(true) + attachmentPreviewerMiniatureList.adapter = attachmentMiniaturePreviewController.adapter + attachmentMiniaturePreviewController.callback = this + + attachmentPreviewerBigList.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) + val snapHelper = PagerSnapHelper() + snapHelper.attachToRecyclerView(attachmentPreviewerBigList) + attachmentPreviewerBigList.setHasFixedSize(true) + attachmentPreviewerBigList.adapter = attachmentBigPreviewController.adapter + } override fun invalidate() = withState(viewModel) { state -> + attachmentMiniaturePreviewController.setData(state) + attachmentBigPreviewController.setData(state) + } + + override fun onAttachmentClicked(contentAttachmentData: ContentAttachmentData) { } + } diff --git a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt index 5cb3024712..71ab8f2852 100644 --- a/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt +++ b/vector/src/main/java/im/vector/riotx/features/home/room/detail/RoomDetailFragment.kt @@ -116,6 +116,8 @@ import im.vector.riotx.core.utils.toast import im.vector.riotx.features.attachments.AttachmentTypeSelectorView import im.vector.riotx.features.attachments.AttachmentsHelper import im.vector.riotx.features.attachments.ContactAttachment +import im.vector.riotx.features.attachments.preview.AttachmentsPreviewActivity +import im.vector.riotx.features.attachments.preview.AttachmentsPreviewArgs import im.vector.riotx.features.command.Command import im.vector.riotx.features.crypto.util.toImageRes import im.vector.riotx.features.crypto.verification.VerificationBottomSheet @@ -1337,7 +1339,8 @@ class RoomDetailFragment @Inject constructor( // AttachmentsHelper.Callback override fun onContentAttachmentsReady(attachments: List) { - roomDetailViewModel.handle(RoomDetailAction.SendMedia(attachments)) + val intent = AttachmentsPreviewActivity.newIntent(requireContext(), AttachmentsPreviewArgs(attachments)) + startActivityForResult(intent, AttachmentsPreviewActivity.REQUEST_CODE) } override fun onAttachmentsProcessFailed() { diff --git a/vector/src/main/res/layout/fragment_attachments_preview.xml b/vector/src/main/res/layout/fragment_attachments_preview.xml index 60d311b96d..5acc8835b0 100644 --- a/vector/src/main/res/layout/fragment_attachments_preview.xml +++ b/vector/src/main/res/layout/fragment_attachments_preview.xml @@ -1,57 +1,32 @@ - + android:layout_height="match_parent" + xmlns:tools="http://schemas.android.com/tools"> - + + - - - - - - - - - - - - - - - - + diff --git a/vector/src/main/res/layout/item_attachment_big_preview.xml b/vector/src/main/res/layout/item_attachment_big_preview.xml new file mode 100644 index 0000000000..3705965520 --- /dev/null +++ b/vector/src/main/res/layout/item_attachment_big_preview.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/vector/src/main/res/layout/item_attachment_preview.xml b/vector/src/main/res/layout/item_attachment_miniature_preview.xml similarity index 67% rename from vector/src/main/res/layout/item_attachment_preview.xml rename to vector/src/main/res/layout/item_attachment_miniature_preview.xml index 3c769d17d9..23dfcf381b 100644 --- a/vector/src/main/res/layout/item_attachment_preview.xml +++ b/vector/src/main/res/layout/item_attachment_miniature_preview.xml @@ -1,19 +1,18 @@ - - \ No newline at end of file + \ No newline at end of file