From be6bd86a893f6f1fe8050a2cbea52bda78ef43c3 Mon Sep 17 00:00:00 2001 From: Taras Smakula <tarassmakula@gmail.com> Date: Thu, 1 Jun 2023 17:28:35 +0300 Subject: [PATCH] Core and gallery changes --- app/build.gradle | 6 - app/src/main/AndroidManifest.xml | 2 +- app/src/main/java/org/futo/circles/App.kt | 2 + .../java/org/futo/circles/MainActivity.kt | 2 +- .../org/futo/circles/base/RoomsListener.kt | 2 +- .../futo/circles/base/SelectRoomsListener.kt | 7 - .../di/data_source/SettingsDsModule.kt | 4 +- .../di/data_source/TimelineDsModule.kt | 4 +- .../futo/circles/di/ui/SettingsUiModule.kt | 2 +- .../futo/circles/di/ui/TimelineUiModule.kt | 2 +- .../circles/extensions/ContextExtensions.kt | 12 -- .../AcceptCircleInviteDataSource.kt | 2 +- .../AcceptCircleInviteDialogFragment.kt | 4 +- .../AcceptCircleInviteViewModel.kt | 2 +- .../feature/photos/PhotosDataSource.kt | 25 --- .../circles/feature/photos/PhotosFragment.kt | 105 ---------- .../circles/feature/photos/PhotosViewModel.kt | 11 -- .../photos/UpdateGalleryDialogFragment.kt | 67 ------- .../photos/backup/MediaBackupDataSource.kt | 152 --------------- .../backup/MediaBackupDialogFragment.kt | 107 ----------- .../photos/backup/MediaBackupViewModel.kt | 83 -------- .../backup/list/MediaFolderViewHolder.kt | 44 ----- .../backup/list/MediaFoldersListAdapter.kt | 22 --- .../backup/service/MediaBackupService.kt | 81 -------- .../service/MediaBackupServiceManager.kt | 78 -------- .../backup/service/MediaBackupWorker.kt | 36 ---- .../create/CreateGalleryDialogFragment.kt | 45 ----- .../feature/photos/gallery/GalleryFragment.kt | 159 ---------------- .../photos/gallery/GalleryViewModel.kt | 72 ------- .../gallery/list/GalleryItemViewHolder.kt | 43 ----- .../gallery/list/GalleryItemsAdapter.kt | 25 --- .../feature/photos/list/GalleryViewHolder.kt | 30 --- .../feature/photos/list/PhotosListAdapter.kt | 23 --- .../photos/preview/MediaPreviewDataSource.kt | 34 ---- .../preview/MediaPreviewDialogFragment.kt | 179 ------------------ .../photos/preview/MediaPreviewViewModel.kt | 59 ------ .../save/SavePostToGalleryDataSource.kt | 33 ---- .../photos/save/SavePostToGalleryViewModel.kt | 27 --- .../save/SavePostToGalleyDialogFragment.kt | 69 ------- .../select/SelectGalleriesDataSource.kt | 33 ---- .../photos/select/SelectGalleriesFragment.kt | 65 ------- .../photos/select/SelectGalleriesViewModel.kt | 16 -- .../select/list/SelectGalleryAdapter.kt | 23 --- .../select/list/SelectGalleryViewHolder.kt | 34 ---- .../room/select/SelectRoomsDataSource.kt | 2 +- .../room/select/SelectRoomsFragment.kt | 4 +- .../room/select/SelectRoomsViewModel.kt | 2 +- .../room/select/list/SelectRoomsAdapter.kt | 2 +- .../room/select/list/SelectRoomsViewHolder.kt | 2 +- .../select/list/SelectedChipsRoomsAdapter.kt | 2 +- .../verify/qr/QrScannerActivity.kt | 2 +- .../share/circle/ShareWithCircleActivity.kt | 5 +- .../share/group/ShareWithGroupActivity.kt | 4 +- .../feature/timeline/TimelineFragment.kt | 2 +- .../feature/timeline/TimelineViewModel.kt | 6 +- ...stItemMapping.kt => RoomSummaryMapping.kt} | 7 - .../futo/circles/model/ConfirmationType.kt | 5 - app/src/main/res/values/strings.xml | 6 - core/build.gradle | 3 + .../org/futo/circles/core}/BaseActivity.kt | 11 +- .../org/futo/circles/core/CirclesAppConfig.kt | 8 +- .../core/extensions/ContextExtensions.kt | 11 ++ .../core/mapping/RoomSummaryMapping.kt | 7 + .../core}/model/SelectableRoomListItem.kt | 2 +- .../circles/core/model}/SharableContent.kt | 4 +- .../core}/rageshake/BugReportDataCollector.kt | 6 +- .../core}/rageshake/BugReportDataSource.kt | 2 +- .../rageshake/BugReportDialogFragment.kt | 2 +- .../core}/rageshake/BugReportViewModel.kt | 2 +- .../futo/circles/core}/rageshake/RageShake.kt | 3 +- .../circles/core/room/select/RoomsPicker.kt | 8 + .../core/room/select/SelectRoomsListener.kt | 7 + .../circles/core}/share/BaseShareActivity.kt | 18 +- .../circles/core}/share/BaseShareViewModel.kt | 4 +- .../futo/circles/core}/share/ShareProvider.kt | 7 +- .../timeline/post/PostOptionsDataSource.kt | 14 +- .../{ => post}/SendMessageDataSource.kt | 2 +- .../main/res/layout/activity_base_share.xml | 3 +- core/src/main/res/values/strings.xml | 1 + .../feature/backup/MediaBackupDataSource.kt | 2 +- .../feature/gallery/GalleryViewModel.kt | 2 +- .../gallery/list/GalleryItemViewHolder.kt | 1 + .../preview/MediaPreviewDialogFragment.kt | 8 +- .../feature/preview/MediaPreviewViewModel.kt | 4 +- .../save/SavePostToGalleryDataSource.kt | 4 +- .../save/SavePostToGalleryViewModel.kt | 2 +- .../save/SavePostToGalleyDialogFragment.kt | 6 +- .../select/SelectGalleriesDataSource.kt | 4 +- .../feature/select/SelectGalleriesFragment.kt | 14 +- .../select/SelectGalleriesViewModel.kt | 2 +- .../select/list/SelectGalleryAdapter.kt | 2 +- .../select/list/SelectGalleryViewHolder.kt | 6 +- .../feature/share}/UploadToGalleryActivity.kt | 10 +- .../circles/gallery/model/ConfirmationType.kt | 6 + .../gallery/model/SelectableRoomListItem.kt | 10 - .../res/layout/fragment_select_galleries.xml | 0 .../res/layout/list_item_select_gallery.xml | 0 gallery/src/main/res/values/strings.xml | 10 + 98 files changed, 166 insertions(+), 1936 deletions(-) delete mode 100644 app/src/main/java/org/futo/circles/base/SelectRoomsListener.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/PhotosDataSource.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/PhotosFragment.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/PhotosViewModel.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/UpdateGalleryDialogFragment.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/backup/MediaBackupDataSource.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/backup/MediaBackupDialogFragment.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/backup/MediaBackupViewModel.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/backup/list/MediaFolderViewHolder.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/backup/list/MediaFoldersListAdapter.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/backup/service/MediaBackupService.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/backup/service/MediaBackupServiceManager.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/backup/service/MediaBackupWorker.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/create/CreateGalleryDialogFragment.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/gallery/GalleryFragment.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/gallery/GalleryViewModel.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/gallery/list/GalleryItemViewHolder.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/gallery/list/GalleryItemsAdapter.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/list/GalleryViewHolder.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/list/PhotosListAdapter.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/preview/MediaPreviewDataSource.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/preview/MediaPreviewDialogFragment.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/preview/MediaPreviewViewModel.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/save/SavePostToGalleryDataSource.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/save/SavePostToGalleryViewModel.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/save/SavePostToGalleyDialogFragment.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/select/SelectGalleriesDataSource.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/select/SelectGalleriesFragment.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/select/SelectGalleriesViewModel.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/select/list/SelectGalleryAdapter.kt delete mode 100644 app/src/main/java/org/futo/circles/feature/photos/select/list/SelectGalleryViewHolder.kt rename app/src/main/java/org/futo/circles/mapping/{RoomListItemMapping.kt => RoomSummaryMapping.kt} (92%) rename {app/src/main/java/org/futo/circles/base => core/src/main/java/org/futo/circles/core}/BaseActivity.kt (69%) create mode 100644 core/src/main/java/org/futo/circles/core/extensions/ContextExtensions.kt rename {app/src/main/java/org/futo/circles => core/src/main/java/org/futo/circles/core}/model/SelectableRoomListItem.kt (83%) rename {app/src/main/java/org/futo/circles/feature/share => core/src/main/java/org/futo/circles/core/model}/SharableContent.kt (71%) rename {app/src/main/java/org/futo/circles/feature => core/src/main/java/org/futo/circles/core}/rageshake/BugReportDataCollector.kt (98%) rename {app/src/main/java/org/futo/circles/feature => core/src/main/java/org/futo/circles/core}/rageshake/BugReportDataSource.kt (95%) rename {app/src/main/java/org/futo/circles/feature => core/src/main/java/org/futo/circles/core}/rageshake/BugReportDialogFragment.kt (98%) rename {app/src/main/java/org/futo/circles/feature => core/src/main/java/org/futo/circles/core}/rageshake/BugReportViewModel.kt (95%) rename {app/src/main/java/org/futo/circles/feature => core/src/main/java/org/futo/circles/core}/rageshake/RageShake.kt (96%) create mode 100644 core/src/main/java/org/futo/circles/core/room/select/RoomsPicker.kt create mode 100644 core/src/main/java/org/futo/circles/core/room/select/SelectRoomsListener.kt rename {app/src/main/java/org/futo/circles/feature => core/src/main/java/org/futo/circles/core}/share/BaseShareActivity.kt (81%) rename {app/src/main/java/org/futo/circles/feature => core/src/main/java/org/futo/circles/core}/share/BaseShareViewModel.kt (88%) rename {app/src/main/java/org/futo/circles/feature => core/src/main/java/org/futo/circles/core}/share/ShareProvider.kt (82%) rename {app/src/main/java/org/futo/circles/feature => core/src/main/java/org/futo/circles/core}/timeline/post/PostOptionsDataSource.kt (92%) rename core/src/main/java/org/futo/circles/core/timeline/{ => post}/SendMessageDataSource.kt (99%) rename {app => core}/src/main/res/layout/activity_base_share.xml (95%) rename {app/src/main/java/org/futo/circles/feature/share/gallery => gallery/src/main/java/org/futo/circles/gallery/feature/share}/UploadToGalleryActivity.kt (52%) delete mode 100644 gallery/src/main/java/org/futo/circles/gallery/model/SelectableRoomListItem.kt rename {app => gallery}/src/main/res/layout/fragment_select_galleries.xml (100%) rename {app => gallery}/src/main/res/layout/list_item_select_gallery.xml (100%) diff --git a/app/build.gradle b/app/build.gradle index 1a9ffd564..47dd48888 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,9 +13,6 @@ android { versionName "1.0.11" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" - - buildConfigField "boolean", "RAGESHAKE_ENABLED", "false" - buildConfigField "boolean", "MEDIA_BACKUP_ENABLED", "false" } buildFeatures { @@ -100,9 +97,6 @@ dependencies { //Mentions autocomplete implementation "com.otaliastudios:autocomplete:1.1.0" - //Shake detection - implementation 'com.squareup:seismic:1.0.3' - //Coroutines def coroutines_version = "1.6.4" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 40c7e26b3..ef5722ae1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -44,7 +44,7 @@ </intent-filter> </activity> <activity - android:name=".feature.share.gallery.UploadToGalleryActivity" + android:name=".gallery.feature.share.UploadToGalleryActivity" android:exported="true" android:launchMode="singleTask" android:screenOrientation="portrait" diff --git a/app/src/main/java/org/futo/circles/App.kt b/app/src/main/java/org/futo/circles/App.kt index bab8a2a99..4884889ed 100644 --- a/app/src/main/java/org/futo/circles/App.kt +++ b/app/src/main/java/org/futo/circles/App.kt @@ -40,6 +40,8 @@ class App : Application() { .euDomain(getString(R.string.debug_eu_domain), getString(R.string.release_eu_domain)) .usDomain(getString(R.string.debug_us_domain), getString(R.string.release_us_domain)) .isSubscriptionEnabled(false) + .isMediaBackupEnabled(false) + .isRageshakeEnabled(false) .init() MatrixSessionProvider.initSession( diff --git a/app/src/main/java/org/futo/circles/MainActivity.kt b/app/src/main/java/org/futo/circles/MainActivity.kt index 51e4bd750..9c627c518 100644 --- a/app/src/main/java/org/futo/circles/MainActivity.kt +++ b/app/src/main/java/org/futo/circles/MainActivity.kt @@ -8,7 +8,7 @@ import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch -import org.futo.circles.base.BaseActivity +import org.futo.circles.core.BaseActivity import org.futo.circles.core.provider.MatrixSessionListenerProvider import org.futo.circles.core.provider.MatrixSessionProvider diff --git a/app/src/main/java/org/futo/circles/base/RoomsListener.kt b/app/src/main/java/org/futo/circles/base/RoomsListener.kt index dd88a583e..6cba8c28d 100644 --- a/app/src/main/java/org/futo/circles/base/RoomsListener.kt +++ b/app/src/main/java/org/futo/circles/base/RoomsListener.kt @@ -1,6 +1,6 @@ package org.futo.circles.base -import org.futo.circles.model.SelectableRoomListItem +import org.futo.circles.core.model.SelectableRoomListItem interface RoomsListener { fun onRoomsListChanged(rooms: List<SelectableRoomListItem>) diff --git a/app/src/main/java/org/futo/circles/base/SelectRoomsListener.kt b/app/src/main/java/org/futo/circles/base/SelectRoomsListener.kt deleted file mode 100644 index 1babe474f..000000000 --- a/app/src/main/java/org/futo/circles/base/SelectRoomsListener.kt +++ /dev/null @@ -1,7 +0,0 @@ -package org.futo.circles.base - -import org.futo.circles.model.SelectableRoomListItem - -interface SelectRoomsListener { - fun onRoomsSelected(rooms: List<SelectableRoomListItem>) -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/di/data_source/SettingsDsModule.kt b/app/src/main/java/org/futo/circles/di/data_source/SettingsDsModule.kt index d2c3c00ce..b57a6b71f 100644 --- a/app/src/main/java/org/futo/circles/di/data_source/SettingsDsModule.kt +++ b/app/src/main/java/org/futo/circles/di/data_source/SettingsDsModule.kt @@ -7,8 +7,8 @@ import org.futo.circles.auth.feature.pass_phrase.restore.SSSSDataSource import org.futo.circles.auth.feature.sign_up.username.UsernameDataSource import org.futo.circles.core.provider.PreferencesProvider import org.futo.circles.feature.photos.backup.service.MediaBackupServiceManager -import org.futo.circles.feature.rageshake.BugReportDataCollector -import org.futo.circles.feature.rageshake.BugReportDataSource +import org.futo.circles.core.rageshake.BugReportDataCollector +import org.futo.circles.core.rageshake.BugReportDataSource import org.futo.circles.feature.settings.SettingsDataSource import org.futo.circles.feature.settings.active_sessions.ActiveSessionsDataSource import org.futo.circles.feature.settings.change_password.ChangePasswordDataSource diff --git a/app/src/main/java/org/futo/circles/di/data_source/TimelineDsModule.kt b/app/src/main/java/org/futo/circles/di/data_source/TimelineDsModule.kt index 2401f930e..813cdc018 100644 --- a/app/src/main/java/org/futo/circles/di/data_source/TimelineDsModule.kt +++ b/app/src/main/java/org/futo/circles/di/data_source/TimelineDsModule.kt @@ -12,10 +12,10 @@ import org.futo.circles.core.select_users.SearchUserDataSource import org.futo.circles.core.select_users.SelectUsersDataSource import org.futo.circles.feature.timeline.data_source.AccessLevelDataSource import org.futo.circles.feature.timeline.data_source.ReadMessageDataSource -import org.futo.circles.core.timeline.SendMessageDataSource +import org.futo.circles.core.timeline.post.SendMessageDataSource import org.futo.circles.core.timeline.TimelineBuilder import org.futo.circles.core.timeline.TimelineDataSource -import org.futo.circles.feature.timeline.post.PostOptionsDataSource +import org.futo.circles.core.timeline.post.PostOptionsDataSource import org.futo.circles.feature.timeline.post.report.ReportDataSource import org.koin.dsl.module diff --git a/app/src/main/java/org/futo/circles/di/ui/SettingsUiModule.kt b/app/src/main/java/org/futo/circles/di/ui/SettingsUiModule.kt index c805e14c5..a05efd4c7 100644 --- a/app/src/main/java/org/futo/circles/di/ui/SettingsUiModule.kt +++ b/app/src/main/java/org/futo/circles/di/ui/SettingsUiModule.kt @@ -4,7 +4,7 @@ import org.futo.circles.auth.feature.sign_up.username.UsernameViewModel import org.futo.circles.feature.home.SystemNoticesCountSharedViewModel import org.futo.circles.feature.notices.SystemNoticesTimelineViewModel import org.futo.circles.feature.people.user.UserViewModel -import org.futo.circles.feature.rageshake.BugReportViewModel +import org.futo.circles.core.rageshake.BugReportViewModel import org.futo.circles.feature.settings.SettingsViewModel import org.futo.circles.feature.settings.active_sessions.ActiveSessionsViewModel import org.futo.circles.feature.settings.active_sessions.verify.VerifySessionViewModel diff --git a/app/src/main/java/org/futo/circles/di/ui/TimelineUiModule.kt b/app/src/main/java/org/futo/circles/di/ui/TimelineUiModule.kt index 6c737df4a..7978958e0 100644 --- a/app/src/main/java/org/futo/circles/di/ui/TimelineUiModule.kt +++ b/app/src/main/java/org/futo/circles/di/ui/TimelineUiModule.kt @@ -4,7 +4,7 @@ import org.futo.circles.feature.circles.following.FollowingViewModel import org.futo.circles.feature.room.invite.InviteMembersViewModel import org.futo.circles.feature.room.manage_members.ManageMembersViewModel import org.futo.circles.feature.room.manage_members.change_role.ChangeAccessLevelViewModel -import org.futo.circles.feature.share.BaseShareViewModel +import org.futo.circles.core.share.BaseShareViewModel import org.futo.circles.feature.timeline.TimelineViewModel import org.futo.circles.feature.timeline.post.report.ReportViewModel import org.koin.androidx.viewmodel.dsl.viewModel diff --git a/app/src/main/java/org/futo/circles/extensions/ContextExtensions.kt b/app/src/main/java/org/futo/circles/extensions/ContextExtensions.kt index dfab03cac..cf6045dcd 100644 --- a/app/src/main/java/org/futo/circles/extensions/ContextExtensions.kt +++ b/app/src/main/java/org/futo/circles/extensions/ContextExtensions.kt @@ -4,28 +4,16 @@ import android.content.Context import android.content.pm.PackageManager import android.graphics.Bitmap import android.graphics.Canvas -import android.net.ConnectivityManager -import android.net.NetworkCapabilities import android.util.DisplayMetrics import android.util.TypedValue import androidx.annotation.DimenRes import androidx.annotation.DrawableRes import androidx.annotation.Px -import androidx.core.content.getSystemService import androidx.core.content.res.ResourcesCompat -import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.util.getApplicationInfoCompat fun Context.dimen(@DimenRes resource: Int): Int = resources.getDimensionPixelSize(resource) -fun Context.disableScreenScale(): Context { - val overrideConfiguration = resources.configuration.apply { - fontScale = 1f - densityDpi = resources.displayMetrics.xdpi.toInt() - } - return createConfigurationContext(overrideConfiguration) -} - fun Context.convertDpToPixel(dp: Float): Float { return dp * (resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT) } diff --git a/app/src/main/java/org/futo/circles/feature/circles/accept_invite/AcceptCircleInviteDataSource.kt b/app/src/main/java/org/futo/circles/feature/circles/accept_invite/AcceptCircleInviteDataSource.kt index d061ad948..2b6e3a172 100644 --- a/app/src/main/java/org/futo/circles/feature/circles/accept_invite/AcceptCircleInviteDataSource.kt +++ b/app/src/main/java/org/futo/circles/feature/circles/accept_invite/AcceptCircleInviteDataSource.kt @@ -3,7 +3,7 @@ package org.futo.circles.feature.circles.accept_invite import org.futo.circles.core.extensions.createResult import org.futo.circles.core.provider.MatrixSessionProvider import org.futo.circles.core.room.RoomRelationsBuilder -import org.futo.circles.model.SelectableRoomListItem +import org.futo.circles.core.model.SelectableRoomListItem class AcceptCircleInviteDataSource( private val roomId: String, diff --git a/app/src/main/java/org/futo/circles/feature/circles/accept_invite/AcceptCircleInviteDialogFragment.kt b/app/src/main/java/org/futo/circles/feature/circles/accept_invite/AcceptCircleInviteDialogFragment.kt index 20c0ac50d..a4b9d6869 100644 --- a/app/src/main/java/org/futo/circles/feature/circles/accept_invite/AcceptCircleInviteDialogFragment.kt +++ b/app/src/main/java/org/futo/circles/feature/circles/accept_invite/AcceptCircleInviteDialogFragment.kt @@ -7,7 +7,7 @@ import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs import org.futo.circles.R import org.futo.circles.base.RoomsListener -import org.futo.circles.base.SelectRoomsListener +import org.futo.circles.core.room.select.SelectRoomsListener import org.futo.circles.core.extensions.observeResponse import org.futo.circles.core.extensions.onBackPressed import org.futo.circles.core.extensions.setIsVisible @@ -15,7 +15,7 @@ import org.futo.circles.core.fragment.BaseFullscreenDialogFragment import org.futo.circles.core.fragment.HasLoadingState import org.futo.circles.databinding.DialogFragmentAcceptCircleInviteBinding import org.futo.circles.feature.room.select.SelectRoomsFragment -import org.futo.circles.model.SelectableRoomListItem +import org.futo.circles.core.model.SelectableRoomListItem import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.core.parameter.parametersOf diff --git a/app/src/main/java/org/futo/circles/feature/circles/accept_invite/AcceptCircleInviteViewModel.kt b/app/src/main/java/org/futo/circles/feature/circles/accept_invite/AcceptCircleInviteViewModel.kt index 70d9d0a34..1d2e8321f 100644 --- a/app/src/main/java/org/futo/circles/feature/circles/accept_invite/AcceptCircleInviteViewModel.kt +++ b/app/src/main/java/org/futo/circles/feature/circles/accept_invite/AcceptCircleInviteViewModel.kt @@ -4,7 +4,7 @@ import androidx.lifecycle.ViewModel import org.futo.circles.core.SingleEventLiveData import org.futo.circles.core.extensions.Response import org.futo.circles.core.extensions.launchBg -import org.futo.circles.model.SelectableRoomListItem +import org.futo.circles.core.model.SelectableRoomListItem class AcceptCircleInviteViewModel( private val acceptInviteDataSource: AcceptCircleInviteDataSource diff --git a/app/src/main/java/org/futo/circles/feature/photos/PhotosDataSource.kt b/app/src/main/java/org/futo/circles/feature/photos/PhotosDataSource.kt deleted file mode 100644 index e29fe98bb..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/PhotosDataSource.kt +++ /dev/null @@ -1,25 +0,0 @@ -package org.futo.circles.feature.photos - -import androidx.lifecycle.map -import org.futo.circles.core.model.GALLERY_TYPE -import org.futo.circles.core.provider.MatrixSessionProvider -import org.futo.circles.mapping.toGalleryListItem -import org.futo.circles.model.GalleryListItem -import org.matrix.android.sdk.api.session.room.model.Membership -import org.matrix.android.sdk.api.session.room.model.RoomSummary -import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams - -class PhotosDataSource { - - fun getGalleriesLiveData() = MatrixSessionProvider.currentSession?.roomService() - ?.getRoomSummariesLive(roomSummaryQueryParams()) - ?.map { list -> filterGalleries(list) } - - private fun filterGalleries(list: List<RoomSummary>): List<GalleryListItem> { - return list.mapNotNull { summary -> - if (summary.roomType == GALLERY_TYPE && summary.membership == Membership.JOIN) { - summary.toGalleryListItem() - } else null - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/PhotosFragment.kt b/app/src/main/java/org/futo/circles/feature/photos/PhotosFragment.kt deleted file mode 100644 index 35f533ba3..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/PhotosFragment.kt +++ /dev/null @@ -1,105 +0,0 @@ -package org.futo.circles.feature.photos - -import android.Manifest -import android.annotation.SuppressLint -import android.content.Context -import android.os.Build -import android.os.Bundle -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem -import android.view.View -import androidx.annotation.RequiresApi -import androidx.appcompat.view.menu.MenuBuilder -import androidx.core.view.MenuProvider -import androidx.fragment.app.Fragment -import androidx.navigation.fragment.findNavController -import by.kirich1409.viewbindingdelegate.viewBinding -import org.futo.circles.BuildConfig -import org.futo.circles.R -import org.futo.circles.gallery.feature.pick.PickGalleryListener -import org.futo.circles.core.extensions.bindToFab -import org.futo.circles.core.extensions.observeData -import org.futo.circles.core.extensions.setIsVisible -import org.futo.circles.core.picker.RuntimePermissionHelper -import org.futo.circles.databinding.FragmentRoomsBinding -import org.futo.circles.extensions.* -import org.futo.circles.feature.photos.list.PhotosListAdapter -import org.futo.circles.model.GalleryListItem -import org.koin.androidx.viewmodel.ext.android.viewModel - -class PhotosFragment : Fragment(R.layout.fragment_rooms), MenuProvider { - - private val viewModel by viewModel<PhotosViewModel>() - private val binding by viewBinding(FragmentRoomsBinding::bind) - - private var pickGalleryListener: PickGalleryListener? = null - private val listAdapter by lazy { - PhotosListAdapter(onRoomClicked = { roomListItem -> onRoomListItemClicked(roomListItem) }) - } - - @RequiresApi(Build.VERSION_CODES.TIRAMISU) - private val readMediaPermissionHelper = - RuntimePermissionHelper(this, Manifest.permission.READ_MEDIA_IMAGES) - - override fun onAttach(context: Context) { - super.onAttach(context) - pickGalleryListener = parentFragment as? PickGalleryListener - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - setupViews() - setupObservers() - activity?.addMenuProvider(this, viewLifecycleOwner) - } - - @SuppressLint("RestrictedApi") - override fun onCreateMenu(menu: Menu, inflater: MenuInflater) { - menu.clear() - if (BuildConfig.MEDIA_BACKUP_ENABLED.not()) return - (menu as? MenuBuilder)?.setOptionalIconsVisible(true) - inflater.inflate(R.menu.photos_tab_menu, menu) - } - - - override fun onMenuItemSelected(item: MenuItem): Boolean { - when (item.itemId) { - R.id.backup -> openBackupSettingsWithNecessaryPermissions() - } - return true - } - - private fun setupViews() { - binding.fbAddRoom.setIsVisible(pickGalleryListener == null) - binding.rvRooms.apply { - adapter = listAdapter - bindToFab(binding.fbAddRoom) - } - binding.fbAddRoom.setOnClickListener { navigateToCreateRoom() } - } - - private fun setupObservers() { - viewModel.roomsLiveData?.observeData(this) { listAdapter.submitList(it) } - } - - private fun onRoomListItemClicked(room: GalleryListItem) { - pickGalleryListener?.onGalleryChosen(room.id) ?: run { - findNavController().navigate(PhotosFragmentDirections.toGalleryFragment(room.id)) - } - } - - private fun openBackupSettingsWithNecessaryPermissions() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) - readMediaPermissionHelper.runWithPermission { navigateToBackupSettings() } - else navigateToBackupSettings() - } - - private fun navigateToCreateRoom() { - findNavController().navigate(PhotosFragmentDirections.toCreateGalleryDialogFragment()) - } - - private fun navigateToBackupSettings() { - findNavController().navigate(PhotosFragmentDirections.toMediaBackupDialogFragment()) - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/PhotosViewModel.kt b/app/src/main/java/org/futo/circles/feature/photos/PhotosViewModel.kt deleted file mode 100644 index 9e612084d..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/PhotosViewModel.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.futo.circles.feature.photos - -import androidx.lifecycle.ViewModel - -class PhotosViewModel( - dataSource: PhotosDataSource -) : ViewModel() { - - val roomsLiveData = dataSource.getGalleriesLiveData() - -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/UpdateGalleryDialogFragment.kt b/app/src/main/java/org/futo/circles/feature/photos/UpdateGalleryDialogFragment.kt deleted file mode 100644 index 3f9296908..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/UpdateGalleryDialogFragment.kt +++ /dev/null @@ -1,67 +0,0 @@ -package org.futo.circles.feature.photos - - -import android.net.Uri -import android.os.Bundle -import android.view.View -import androidx.core.widget.doAfterTextChanged -import androidx.fragment.app.Fragment -import androidx.navigation.fragment.navArgs -import org.futo.circles.R -import org.futo.circles.core.extensions.getText -import org.futo.circles.core.extensions.loadProfileIcon -import org.futo.circles.core.picker.MediaPickerHelper -import org.futo.circles.databinding.DialogFragmentUpdateGalleryBinding -import org.futo.circles.core.room.update.UpdateRoomDialogFragment -import org.matrix.android.sdk.api.session.room.model.RoomSummary - -class UpdateGalleryDialogFragment : - UpdateRoomDialogFragment(DialogFragmentUpdateGalleryBinding::inflate) { - - private val args: UpdateGalleryDialogFragmentArgs by navArgs() - override val roomId: String get() = args.roomId - override val fragment: Fragment = this - override val mediaPickerHelper: MediaPickerHelper = MediaPickerHelper(this) - override val successMessageResId: Int = R.string.gallery_updated - - private val binding by lazy { - getBinding() as DialogFragmentUpdateGalleryBinding - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - setupViews() - } - - override fun onCoverImageSelected(uri: Uri) { - binding.ivCover.setImageURI(uri) - onInputDataChanged() - } - - override fun setInitialGroupData(room: RoomSummary) { - binding.ivCover.loadProfileIcon(room.avatarUrl, room.displayName) - binding.tilName.editText?.setText(room.displayName) - } - - override fun setUpdateButtonEnabled(isEnabled: Boolean) { - binding.btnSave.isEnabled = isEnabled - } - - private fun setupViews() { - with(binding) { - ivCover.setOnClickListener { changeCoverImage() } - btnChangeIcon.setOnClickListener { changeCoverImage() } - tilName.editText?.doAfterTextChanged { - it?.let { onInputDataChanged() } - } - btnSave.setOnClickListener { - updateRoom(tilName.getText()) - startLoading(btnSave) - } - } - } - - private fun onInputDataChanged() { - onInputRoomDataChanged(binding.tilName.getText()) - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/backup/MediaBackupDataSource.kt b/app/src/main/java/org/futo/circles/feature/photos/backup/MediaBackupDataSource.kt deleted file mode 100644 index 93505e248..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/backup/MediaBackupDataSource.kt +++ /dev/null @@ -1,152 +0,0 @@ -package org.futo.circles.feature.photos.backup - -import android.content.Context -import android.database.Cursor -import android.provider.MediaStore -import org.futo.circles.core.model.Gallery -import org.futo.circles.core.picker.MediaType -import org.futo.circles.core.room.CreateRoomDataSource -import org.futo.circles.core.utils.getJoinedRoomIdByTag -import org.futo.circles.gallery.feature.backup.RoomAccountDataSource -import org.futo.circles.core.timeline.SendMessageDataSource -import org.futo.circles.model.MediaFolderListItem -import org.futo.circles.model.MediaToBackupItem -import org.futo.circles.model.toMediaToBackupItem -import java.io.File - - -class MediaBackupDataSource( - private val context: Context, - private val sendMessageDataSource: SendMessageDataSource, - private val createRoomDataSource: CreateRoomDataSource, - private val roomAccountDataSource: RoomAccountDataSource -) { - - suspend fun startMediaBackup() { - val settings = roomAccountDataSource.getMediaBackupSettings() - if (settings.shouldStartBackup(context)) - settings.folders.forEach { backupMediasInFolder(it) } - } - - suspend fun startBackupByFilePath(path: String) { - val bucketId = getBucketIdByChildFilePath(path) ?: return - val foldersToBackup = roomAccountDataSource.getMediaBackupSettings().folders - if (foldersToBackup.contains(bucketId)) backupMediasInFolder(bucketId) - } - - fun getAllMediaFolders( - selectedFoldersIds: List<String> - ): List<MediaFolderListItem> { - val folders = mutableMapOf<String, MediaFolderListItem>() - getMediaCursor()?.use { cursor -> - val bucketIdColumn = - cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_ID) - val bucketNameColumn = - cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME) - val mediaDataColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA) - while (cursor.moveToNext()) { - val bucketId = cursor.getString(bucketIdColumn) - val bucketName = cursor.getString(bucketNameColumn) - val file = File(cursor.getString(mediaDataColumn)) - val fileSize = file.length() - val size = if (folders.containsKey(bucketId)) - (folders[bucketId]?.size ?: 0) + fileSize - else fileSize - folders[bucketId] = MediaFolderListItem(bucketId, bucketName, size) - } - } - return folders.values.toList().map { - it.copy(isSelected = selectedFoldersIds.contains(it.id)) - } - } - - private suspend fun backupMediasInFolder(bucketId: String) { - val roomId = createGalleryIfNotExist(bucketId) - val dateModified = roomAccountDataSource.getMediaBackupDateModified(roomId) - val mediaInFolder = getMediasToBackupInBucket(bucketId, dateModified) - mediaInFolder.forEach { item -> - val sendCancelable = sendMessageDataSource.sendMedia( - roomId, item.uri, null, null, MediaType.Image - ) - val isUploaded = sendMessageDataSource.awaitForUploading(sendCancelable) - if (isUploaded) - roomAccountDataSource.saveMediaBackupDateModified(roomId, item.dateModified) - } - } - - private suspend fun createGalleryIfNotExist(bucketId: String): String { - var roomId = getJoinedRoomIdByTag(bucketId) - if (roomId == null) { - roomId = createRoomDataSource.createRoom( - circlesRoom = Gallery(tag = bucketId), - name = getFolderNameBy(bucketId) - ) - } - return roomId - } - - private fun getMediaCursor( - selection: String? = null - ): Cursor? { - val projection = - arrayOf( - MediaStore.Images.Media.BUCKET_ID, - MediaStore.Images.Media.BUCKET_DISPLAY_NAME, - MediaStore.Images.Media.DATA - ) - val sortOrder = "${MediaStore.Images.Media.DATE_MODIFIED} DESC" - val uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI - return try { - context.contentResolver - .query(uri, projection, selection, null, sortOrder) - } catch (_: Exception) { - null - } - } - - private fun getFolderNameBy(bucketId: String): String? { - val projection = arrayOf(MediaStore.Images.Media.BUCKET_DISPLAY_NAME) - val selection = "${MediaStore.Images.Media.BUCKET_ID} = ?" - val selectionArgs = arrayOf(bucketId) - val uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI - context.contentResolver.query(uri, projection, selection, selectionArgs, null) - ?.use { cursor -> - if (cursor.moveToFirst()) - return cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_DISPLAY_NAME)) - - } - return null - } - - private fun getBucketIdByChildFilePath(path: String): String? { - val projection = arrayOf(MediaStore.Images.Media.BUCKET_ID) - val selection = "${MediaStore.Images.Media.DATA} = ?" - val selectionArgs = arrayOf(path) - val uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI - context.contentResolver.query(uri, projection, selection, selectionArgs, null) - ?.use { cursor -> - if (cursor.moveToFirst()) - return cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.BUCKET_ID)) - } - return null - } - - private fun getMediasToBackupInBucket( - bucketId: String, - dateModified: Long? - ): List<MediaToBackupItem> { - var selection = "${MediaStore.Images.Media.BUCKET_ID} = $bucketId" - dateModified?.let { - selection += " AND ${MediaStore.Images.Media.DATE_MODIFIED} > $it" - } - val mediaToBackup = mutableListOf<MediaToBackupItem>() - getMediaCursor(selection)?.use { cursor -> - val mediaDataColumnId = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA) - while (cursor.moveToNext()) { - val file = File(cursor.getString(mediaDataColumnId)) - mediaToBackup.add(file.toMediaToBackupItem(context)) - } - } - return mediaToBackup - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/backup/MediaBackupDialogFragment.kt b/app/src/main/java/org/futo/circles/feature/photos/backup/MediaBackupDialogFragment.kt deleted file mode 100644 index f5d622060..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/backup/MediaBackupDialogFragment.kt +++ /dev/null @@ -1,107 +0,0 @@ -package org.futo.circles.feature.photos.backup - -import android.os.Bundle -import android.view.View -import androidx.fragment.app.Fragment -import androidx.recyclerview.widget.DividerItemDecoration -import org.futo.circles.R -import org.futo.circles.core.extensions.observeData -import org.futo.circles.core.extensions.observeResponse -import org.futo.circles.core.extensions.onBackPressed -import org.futo.circles.core.extensions.setIsVisible -import org.futo.circles.core.extensions.showSuccess -import org.futo.circles.core.fragment.BaseFullscreenDialogFragment -import org.futo.circles.core.fragment.HasLoadingState -import org.futo.circles.databinding.DialogFragmentMediaBackupBinding -import org.futo.circles.feature.photos.backup.list.MediaFoldersListAdapter -import org.koin.androidx.viewmodel.ext.android.viewModel - -class MediaBackupDialogFragment : - BaseFullscreenDialogFragment(DialogFragmentMediaBackupBinding::inflate), HasLoadingState { - - private val viewModel by viewModel<MediaBackupViewModel>() - - override val fragment: Fragment = this - private val binding by lazy { - getBinding() as DialogFragmentMediaBackupBinding - } - - private val foldersAdapter by lazy { - MediaFoldersListAdapter( - onItemCheckChanged = { id, isSelected -> - viewModel.onFolderBackupCheckChanged( - id, - isSelected, - binding.svBackup.isChecked, - binding.svWiFi.isChecked, - binding.svCompress.isChecked - ) - } - ) - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - setupViews() - setupObservers() - } - - private fun setupViews() { - with(binding) { - lBackupSwitchContainer.setOnClickListener { - svBackup.isChecked = !svBackup.isChecked - } - lWifi.setOnClickListener { - svWiFi.isChecked = !svWiFi.isChecked - } - lCompressed.setOnClickListener { - svCompress.isChecked = !svCompress.isChecked - } - svBackup.setOnCheckedChangeListener { _, isChecked -> - groupBackupFolders.setIsVisible(isChecked) - onInputDataChanged() - } - svWiFi.setOnCheckedChangeListener { _, _ -> onInputDataChanged() } - svCompress.setOnCheckedChangeListener { _, _ -> onInputDataChanged() } - rvDeviceFolders.apply { - adapter = foldersAdapter - addItemDecoration(DividerItemDecoration(context, DividerItemDecoration.VERTICAL)) - } - btnSave.setOnClickListener { - viewModel.saveBackupSettings( - svBackup.isChecked, - svWiFi.isChecked, - svCompress.isChecked - ) - startLoading(btnSave) - } - } - } - - private fun setupObservers() { - viewModel.mediaFolderLiveData.observeData(this) { - foldersAdapter.submitList(it) - } - viewModel.saveBackupSettingsResultLiveData.observeResponse(this, - success = { - showSuccess(getString(R.string.saved), true) - onBackPressed() - }) - viewModel.initialBackupSettingsLiveData.observeData(this) { - binding.svBackup.isChecked = it.isBackupEnabled - binding.svWiFi.isChecked = it.backupOverWifi - binding.svCompress.isChecked = it.compressBeforeSending - } - viewModel.isSettingsDataChangedLiveData.observeData(this) { - binding.btnSave.isEnabled = it - } - } - - private fun onInputDataChanged() { - viewModel.handleDataSettingsChanged( - binding.svBackup.isChecked, - binding.svWiFi.isChecked, - binding.svCompress.isChecked - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/backup/MediaBackupViewModel.kt b/app/src/main/java/org/futo/circles/feature/photos/backup/MediaBackupViewModel.kt deleted file mode 100644 index 62cc1e3da..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/backup/MediaBackupViewModel.kt +++ /dev/null @@ -1,83 +0,0 @@ -package org.futo.circles.feature.photos.backup - -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import org.futo.circles.core.SingleEventLiveData -import org.futo.circles.core.extensions.Response -import org.futo.circles.core.extensions.launchBg -import org.futo.circles.gallery.feature.backup.RoomAccountDataSource -import org.futo.circles.model.MediaBackupSettingsData -import org.futo.circles.model.MediaFolderListItem - -class MediaBackupViewModel( - private val roomAccountDataSource: RoomAccountDataSource, - private val mediaBackupDataSource: MediaBackupDataSource -) : ViewModel() { - - val mediaFolderLiveData = SingleEventLiveData<List<MediaFolderListItem>>() - val saveBackupSettingsResultLiveData = SingleEventLiveData<Response<Unit?>>() - val initialBackupSettingsLiveData = SingleEventLiveData<MediaBackupSettingsData>() - val isSettingsDataChangedLiveData = MutableLiveData(false) - private val selectedFoldersIds = mutableSetOf<String>() - - init { - getInitialBackupSettings() - } - - private fun getInitialBackupSettings() { - val data = roomAccountDataSource.getMediaBackupSettings() - initialBackupSettingsLiveData.value = data - selectedFoldersIds.addAll(data.folders) - launchBg { - mediaFolderLiveData.postValue( - mediaBackupDataSource.getAllMediaFolders(selectedFoldersIds.toList()) - ) - } - } - - fun onFolderBackupCheckChanged( - id: String, - isSelected: Boolean, - isBackupEnabled: Boolean, - backupOverWifi: Boolean, - compressBeforeSending: Boolean - ) { - if (isSelected) selectedFoldersIds.add(id) - else selectedFoldersIds.remove(id) - handleDataSettingsChanged(isBackupEnabled, backupOverWifi, compressBeforeSending) - } - - fun saveBackupSettings( - isBackupEnabled: Boolean, - backupOverWifi: Boolean, - compressBeforeSending: Boolean - ) { - launchBg { - val result = roomAccountDataSource.saveMediaBackupSettings( - MediaBackupSettingsData( - isBackupEnabled, - backupOverWifi, - compressBeforeSending, - selectedFoldersIds.toList() - ) - ) - saveBackupSettingsResultLiveData.postValue(result) - } - } - - fun handleDataSettingsChanged( - isBackupEnabled: Boolean, - backupOverWifi: Boolean, - compressBeforeSending: Boolean - ) { - val newSettings = - MediaBackupSettingsData( - isBackupEnabled, - backupOverWifi, - compressBeforeSending, - selectedFoldersIds.toList() - ) - isSettingsDataChangedLiveData.value = newSettings != initialBackupSettingsLiveData.value - } - -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/backup/list/MediaFolderViewHolder.kt b/app/src/main/java/org/futo/circles/feature/photos/backup/list/MediaFolderViewHolder.kt deleted file mode 100644 index 7e83874f8..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/backup/list/MediaFolderViewHolder.kt +++ /dev/null @@ -1,44 +0,0 @@ -package org.futo.circles.feature.photos.backup.list - -import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import org.futo.circles.core.extensions.onClick -import org.futo.circles.core.list.ViewBindingHolder -import org.futo.circles.databinding.ListItemMediaFolderBinding -import org.futo.circles.model.MediaFolderListItem -import kotlin.math.log10 -import kotlin.math.pow - -class MediaFolderViewHolder( - parent: ViewGroup, - private val onCheckChanged: (Int, Boolean) -> Unit -) : RecyclerView.ViewHolder(inflate(parent, ListItemMediaFolderBinding::inflate)) { - - private companion object : ViewBindingHolder - - private val binding = baseBinding as ListItemMediaFolderBinding - - init { - onClick(itemView) { binding.svFolder.isChecked = !binding.svFolder.isChecked } - binding.svFolder.setOnCheckedChangeListener { _, isSelected -> - bindingAdapterPosition.takeIf { it != -1 }?.let { onCheckChanged(it, isSelected) } - } - } - - fun bind(data: MediaFolderListItem) { - with(binding) { - tvFolderName.text = data.displayName - tvSize.text = formatFileSize(data.size) - svFolder.isChecked = data.isSelected - } - } - - private fun formatFileSize(size: Long): String { - if (size <= 0) return "0 B" - val units = arrayOf("B", "KB", "MB", "GB", "TB") - val digitGroups = (log10(size.toDouble()) / log10(1024.0)).toInt() - return String.format( - "%.1f %s", size / 1024.0.pow(digitGroups.toDouble()), units[digitGroups] - ) - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/backup/list/MediaFoldersListAdapter.kt b/app/src/main/java/org/futo/circles/feature/photos/backup/list/MediaFoldersListAdapter.kt deleted file mode 100644 index fd24d42c7..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/backup/list/MediaFoldersListAdapter.kt +++ /dev/null @@ -1,22 +0,0 @@ -package org.futo.circles.feature.photos.backup.list - -import android.view.ViewGroup -import org.futo.circles.core.list.BaseRvAdapter -import org.futo.circles.model.MediaFolderListItem - -class MediaFoldersListAdapter( - private val onItemCheckChanged: (String, Boolean) -> Unit, -) : BaseRvAdapter<MediaFolderListItem, MediaFolderViewHolder>(DefaultIdEntityCallback()) { - - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = - MediaFolderViewHolder(parent, - onCheckChanged = { position, isSelected -> - onItemCheckChanged(getItem(position).id, isSelected) - } - ) - - override fun onBindViewHolder(holder: MediaFolderViewHolder, position: Int) { - holder.bind(getItem(position)) - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/backup/service/MediaBackupService.kt b/app/src/main/java/org/futo/circles/feature/photos/backup/service/MediaBackupService.kt deleted file mode 100644 index 9c4dd5fe0..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/backup/service/MediaBackupService.kt +++ /dev/null @@ -1,81 +0,0 @@ -package org.futo.circles.feature.photos.backup.service - -import android.app.Service -import android.content.Context -import android.content.Intent -import android.content.ServiceConnection -import android.database.ContentObserver -import android.net.Uri -import android.os.Binder -import android.os.Handler -import android.os.IBinder -import android.os.Looper -import android.provider.MediaStore -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.SupervisorJob -import kotlinx.coroutines.launch -import org.futo.circles.feature.photos.backup.MediaBackupDataSource -import org.koin.android.ext.android.inject - - -class MediaBackupService : Service() { - - private val binder = MediaBackupServiceBinder() - private val job = SupervisorJob() - private val backupScope = CoroutineScope(Dispatchers.IO + job) - private val mediaBackupDataSource: MediaBackupDataSource by inject() - private var backupJob: Job? = null - - private val contentObserver = object : ContentObserver(Handler(Looper.getMainLooper())) { - override fun onChange(selfChange: Boolean, uri: Uri?) { - if (backupJob != null || selfChange) return - val path = uri?.path ?: return - backupJob = backupScope.launch { - mediaBackupDataSource.startBackupByFilePath(path) - backupJob = null - } - } - } - - override fun onCreate() { - super.onCreate() - contentResolver.registerContentObserver( - MediaStore.Images.Media.EXTERNAL_CONTENT_URI, true, contentObserver - ) - startBackup() - } - - override fun onDestroy() { - super.onDestroy() - job.cancel() - contentResolver.unregisterContentObserver(contentObserver); - } - - override fun onBind(intent: Intent?): IBinder = binder - - fun onBackupSettingsUpdated() { - backupJob?.cancel() - startBackup() - } - - private fun startBackup() { - backupJob = backupScope.launch { - mediaBackupDataSource.startMediaBackup() - backupJob = null - } - } - - inner class MediaBackupServiceBinder : Binder() { - fun getService(): MediaBackupService = this@MediaBackupService - } - - companion object { - fun bindService(context: Context, connection: ServiceConnection) { - Intent(context, MediaBackupService::class.java).also { intent -> - context.bindService(intent, connection, Context.BIND_AUTO_CREATE) - } - } - } -} diff --git a/app/src/main/java/org/futo/circles/feature/photos/backup/service/MediaBackupServiceManager.kt b/app/src/main/java/org/futo/circles/feature/photos/backup/service/MediaBackupServiceManager.kt deleted file mode 100644 index 9232e04c3..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/backup/service/MediaBackupServiceManager.kt +++ /dev/null @@ -1,78 +0,0 @@ -package org.futo.circles.feature.photos.backup.service - -import android.content.ComponentName -import android.content.Context -import android.content.ServiceConnection -import android.os.IBinder -import androidx.work.Constraints -import androidx.work.ExistingPeriodicWorkPolicy -import androidx.work.NetworkType -import androidx.work.PeriodicWorkRequestBuilder -import androidx.work.WorkManager -import org.futo.circles.BuildConfig -import org.futo.circles.model.MediaBackupSettingsData -import java.util.concurrent.TimeUnit - - -class MediaBackupServiceManager { - - private var mediaBackupService: MediaBackupService? = null - private var savedBackupSettings: MediaBackupSettingsData? = null - - private val connection = object : ServiceConnection { - override fun onServiceConnected(className: ComponentName, service: IBinder) { - val binder = service as MediaBackupService.MediaBackupServiceBinder - mediaBackupService = binder.getService() - } - - override fun onServiceDisconnected(arg0: ComponentName) { - clear() - } - } - - fun bindMediaServiceIfNeeded(context: Context, backupSettingsData: MediaBackupSettingsData) { - if (BuildConfig.MEDIA_BACKUP_ENABLED.not()) return - if (savedBackupSettings == backupSettingsData) return - savedBackupSettings = backupSettingsData - mediaBackupService?.onBackupSettingsUpdated() ?: run { - MediaBackupService.bindService(context, connection) - scheduleBackup(context) - } - } - - fun unbindMediaService(context: Context) { - try { - context.unbindService(connection) - clear() - } catch (_: Exception) { - } - } - - private fun clear() { - mediaBackupService = null - mediaBackupService = null - } - - private fun scheduleBackup(context: Context) { - val backupRequest = - PeriodicWorkRequestBuilder<MediaBackupWorker>( - REPEAT_INTERVAL_HOURS, - TimeUnit.HOURS, - FLEX_INTERVAL_MINUTES, - TimeUnit.MINUTES - ).setConstraints( - Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build() - ).build() - WorkManager.getInstance(context).enqueueUniquePeriodicWork( - MEDIA_BACKUP_SCHEDULED_WORK_KEY, - ExistingPeriodicWorkPolicy.UPDATE, - backupRequest - ) - } - - companion object { - private const val MEDIA_BACKUP_SCHEDULED_WORK_KEY = "media_backup" - private const val REPEAT_INTERVAL_HOURS = 6L - private const val FLEX_INTERVAL_MINUTES = 30L - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/backup/service/MediaBackupWorker.kt b/app/src/main/java/org/futo/circles/feature/photos/backup/service/MediaBackupWorker.kt deleted file mode 100644 index 7f7d757c9..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/backup/service/MediaBackupWorker.kt +++ /dev/null @@ -1,36 +0,0 @@ -package org.futo.circles.feature.photos.backup.service - -import android.content.Context -import androidx.work.CoroutineWorker -import androidx.work.WorkerParameters -import org.futo.circles.core.provider.MatrixSessionProvider -import org.futo.circles.feature.photos.backup.MediaBackupDataSource -import org.koin.core.component.KoinComponent -import org.koin.core.component.inject - -class MediaBackupWorker(context: Context, params: WorkerParameters) : - CoroutineWorker(context, params), KoinComponent { - - private val mediaBackupDataSource: MediaBackupDataSource by inject() - - override suspend fun doWork(): Result { - try { - val syncService = MatrixSessionProvider.currentSession?.syncService() - syncService?.startAutomaticBackgroundSync( - BACKGROUND_SYNC_TIMEOUT, - BACKGROUND_SYNC_REPEAT_DELAY - ) - mediaBackupDataSource.startMediaBackup() - syncService?.stopAnyBackgroundSync() - } catch (t: Throwable) { - Result.failure() - } - return Result.success() - } - - companion object { - private const val BACKGROUND_SYNC_TIMEOUT = 60L - private const val BACKGROUND_SYNC_REPEAT_DELAY = 5L - } - -} diff --git a/app/src/main/java/org/futo/circles/feature/photos/create/CreateGalleryDialogFragment.kt b/app/src/main/java/org/futo/circles/feature/photos/create/CreateGalleryDialogFragment.kt deleted file mode 100644 index b200e0879..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/create/CreateGalleryDialogFragment.kt +++ /dev/null @@ -1,45 +0,0 @@ -package org.futo.circles.feature.photos.create - -import android.net.Uri -import android.os.Bundle -import android.view.View -import androidx.core.widget.doAfterTextChanged -import androidx.fragment.app.Fragment -import org.futo.circles.core.extensions.getText -import org.futo.circles.core.picker.MediaPickerHelper -import org.futo.circles.databinding.DialogFragmentCreateGalleryBinding -import org.futo.circles.core.room.create.CreateRoomDialogFragment - -class CreateGalleryDialogFragment : - CreateRoomDialogFragment(DialogFragmentCreateGalleryBinding::inflate) { - - override val fragment: Fragment = this - override val inviteContainerId: Int? = null - override val mediaPickerHelper: MediaPickerHelper = MediaPickerHelper(this) - - private val binding by lazy { - getBinding() as DialogFragmentCreateGalleryBinding - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - setupViews() - } - - override fun onCoverImageSelected(uri: Uri) { - binding.ivCover.setImageURI(uri) - } - - private fun setupViews() { - with(binding) { - ivCover.setOnClickListener { changeCoverImage() } - tilName.editText?.doAfterTextChanged { - it?.let { btnCreate.isEnabled = it.isNotEmpty() } - } - btnCreate.setOnClickListener { - createRoom(CircleRoomTypeArg.Photo, tilName.getText()) - startLoading(btnCreate) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/gallery/GalleryFragment.kt b/app/src/main/java/org/futo/circles/feature/photos/gallery/GalleryFragment.kt deleted file mode 100644 index cce829be5..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/gallery/GalleryFragment.kt +++ /dev/null @@ -1,159 +0,0 @@ -package org.futo.circles.feature.photos.gallery - -import android.annotation.SuppressLint -import android.content.Context -import android.os.Bundle -import android.view.Menu -import android.view.MenuInflater -import android.view.MenuItem -import android.view.View -import androidx.appcompat.view.menu.MenuBuilder -import androidx.core.os.bundleOf -import androidx.core.view.MenuProvider -import androidx.fragment.app.Fragment -import androidx.navigation.fragment.findNavController -import androidx.navigation.fragment.navArgs -import androidx.recyclerview.widget.StaggeredGridLayoutManager -import by.kirich1409.viewbindingdelegate.viewBinding -import org.futo.circles.R -import org.futo.circles.gallery.feature.pick.PickGalleryMediaListener -import org.futo.circles.core.extensions.bindToFab -import org.futo.circles.core.extensions.observeData -import org.futo.circles.core.extensions.observeResponse -import org.futo.circles.core.extensions.onBackPressed -import org.futo.circles.core.extensions.setIsVisible -import org.futo.circles.core.extensions.setToolbarTitle -import org.futo.circles.core.extensions.withConfirmation -import org.futo.circles.core.list.BaseRvDecoration -import org.futo.circles.core.picker.MediaPickerHelper -import org.futo.circles.core.picker.MediaPickerHelper.Companion.IS_VIDEO_AVAILABLE -import org.futo.circles.core.picker.MediaType -import org.futo.circles.databinding.FragmentGalleryBinding -import org.futo.circles.extensions.* -import org.futo.circles.feature.photos.gallery.list.GalleryItemViewHolder -import org.futo.circles.feature.photos.gallery.list.GalleryItemsAdapter -import org.futo.circles.model.DeleteGallery -import org.futo.circles.model.GalleryContentListItem -import org.koin.androidx.viewmodel.ext.android.viewModel -import org.koin.core.parameter.parametersOf - -class GalleryFragment : Fragment(R.layout.fragment_gallery) { - - private val args: GalleryFragmentArgs by navArgs() - private val viewModel by viewModel<GalleryViewModel> { - parametersOf( - args.roomId, CircleRoomTypeArg.Photo, - arguments?.getBoolean(IS_VIDEO_AVAILABLE, true) ?: true - ) - } - private val binding by viewBinding(FragmentGalleryBinding::bind) - private val mediaPickerHelper = MediaPickerHelper(this, true) - private val listAdapter by lazy { - GalleryItemsAdapter( - onGalleryItemClicked = { item -> onMediaItemSelected(item) }, - onLoadMore = { viewModel.loadMore() }) - } - - private var pickMediaListener: PickGalleryMediaListener? = null - - override fun onAttach(context: Context) { - super.onAttach(context) - pickMediaListener = parentFragment as? PickGalleryMediaListener - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - setupViews() - setupObservers() - setupMenu() - } - - private fun setupViews() { - binding.rvGallery.apply { - layoutManager = - StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL).apply { - gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS - } - adapter = listAdapter - addItemDecoration(BaseRvDecoration.OffsetDecoration<GalleryItemViewHolder>(2)) - bindToFab(binding.fbUploadImage) - } - binding.fbUploadImage.setOnClickListener { showImagePicker() } - binding.fbUploadImage.setIsVisible(pickMediaListener == null) - } - - private fun setupObservers() { - viewModel.titleLiveData?.observeData(this) { title -> - setToolbarTitle(title ?: "") - } - viewModel.galleryItemsLiveData.observeData(this) { - listAdapter.submitList(it) - } - viewModel.scrollToTopLiveData.observeData(this) { - binding.rvGallery.postDelayed( - { binding.rvGallery.scrollToPosition(0) }, 500 - ) - } - viewModel.deleteGalleryLiveData.observeResponse(this, - success = { onBackPressed() } - ) - } - - private fun setupMenu() { - activity?.addMenuProvider(object : MenuProvider { - @SuppressLint("RestrictedApi") - override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) { - menu.clear() - (menu as? MenuBuilder)?.setOptionalIconsVisible(true) - menuInflater.inflate(R.menu.gallery_timeline_menu, menu) - } - - override fun onMenuItemSelected(menuItem: MenuItem): Boolean { - when (menuItem.itemId) { - R.id.configureGallery -> navigateToUpdateRoom() - R.id.deleteGallery -> withConfirmation(DeleteGallery()) { viewModel.deleteGallery() } - } - return true - } - }, viewLifecycleOwner) - } - - private fun showImagePicker() { - mediaPickerHelper.showMediaPickerDialog( - onImageSelected = { _, uri -> - viewModel.uploadMedia(uri, MediaType.Image) - }, - onVideoSelected = { uri -> - viewModel.uploadMedia(uri, MediaType.Video) - } - ) - } - - private fun navigateToUpdateRoom() { - findNavController().navigate( - GalleryFragmentDirections.toUpdateGalleryDialogFragment(args.roomId) - ) - } - - private fun onMediaItemSelected(item: GalleryContentListItem) { - pickMediaListener?.let { - viewModel.selectMediaForPicker(requireContext(), item, it) - } ?: kotlin.run { - findNavController().navigate( - GalleryFragmentDirections.toGalleryImageDialogFragment(args.roomId, item.id) - ) - } - } - - companion object { - private const val ROOM_ID = "roomId" - private const val TYPE = "type" - fun create(roomId: String, isVideoAvailable: Boolean) = GalleryFragment().apply { - arguments = bundleOf( - ROOM_ID to roomId, - TYPE to CircleRoomTypeArg.Photo, - IS_VIDEO_AVAILABLE to isVideoAvailable - ) - } - } -} diff --git a/app/src/main/java/org/futo/circles/feature/photos/gallery/GalleryViewModel.kt b/app/src/main/java/org/futo/circles/feature/photos/gallery/GalleryViewModel.kt deleted file mode 100644 index 8d3e7c24c..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/gallery/GalleryViewModel.kt +++ /dev/null @@ -1,72 +0,0 @@ -package org.futo.circles.feature.photos.gallery - -import android.content.Context -import android.net.Uri -import androidx.lifecycle.map -import org.futo.circles.gallery.feature.pick.PickGalleryMediaListener -import org.futo.circles.core.SingleEventLiveData -import org.futo.circles.core.extensions.Response -import org.futo.circles.core.extensions.launchBg -import org.futo.circles.core.extensions.onUI -import org.futo.circles.core.model.MediaFileData -import org.futo.circles.core.picker.MediaType -import org.futo.circles.core.utils.FileUtils.downloadEncryptedFileToContentUri -import org.futo.circles.core.room.leave.LeaveRoomDataSource -import org.futo.circles.core.timeline.BaseTimelineViewModel -import org.futo.circles.core.timeline.SendMessageDataSource -import org.futo.circles.core.timeline.TimelineDataSource -import org.futo.circles.model.GalleryContentListItem -import org.futo.circles.core.model.MediaContent -import org.futo.circles.core.model.PostContentType - -class GalleryViewModel( - private val roomId: String, - private val isVideoAvailable: Boolean, - timelineDataSource: TimelineDataSource, - private val leaveRoomDataSource: LeaveRoomDataSource, - private val sendMessageDataSource: SendMessageDataSource -) : BaseTimelineViewModel(timelineDataSource) { - - val scrollToTopLiveData = SingleEventLiveData<Unit>() - val deleteGalleryLiveData = SingleEventLiveData<Response<Unit?>>() - val galleryItemsLiveData = timelineDataSource.timelineEventsLiveData.map { list -> - list.mapNotNull { post -> - (post.content as? MediaContent)?.let { - if (it.type == PostContentType.VIDEO_CONTENT && !isVideoAvailable) null - else GalleryContentListItem(post.id, post.postInfo, it) - } - } - } - - fun uploadMedia(uri: Uri, mediaType: MediaType) { - launchBg { - sendMessageDataSource.sendMedia(roomId, uri, null, null, mediaType) - scrollToTopLiveData.postValue(Unit) - } - } - - fun deleteGallery() { - launchBg { deleteGalleryLiveData.postValue(leaveRoomDataSource.deleteGallery()) } - } - - fun selectMediaForPicker( - context: Context, - item: GalleryContentListItem, - listener: PickGalleryMediaListener - ) = launchBg { - onMediaSelected( - context, item.mediaContent.mediaFileData, listener, item.mediaContent.getMediaType() - ) - } - - private suspend fun onMediaSelected( - context: Context, - mediaFileData: MediaFileData?, - listener: PickGalleryMediaListener, - mediaType: MediaType - ) { - val content = mediaFileData ?: return - val uri = downloadEncryptedFileToContentUri(context, content) ?: return - onUI { listener.onMediaSelected(uri, mediaType) } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/gallery/list/GalleryItemViewHolder.kt b/app/src/main/java/org/futo/circles/feature/photos/gallery/list/GalleryItemViewHolder.kt deleted file mode 100644 index 7aea50f18..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/gallery/list/GalleryItemViewHolder.kt +++ /dev/null @@ -1,43 +0,0 @@ -package org.futo.circles.feature.photos.gallery.list - -import android.view.ViewGroup -import androidx.core.view.updateLayoutParams -import androidx.recyclerview.widget.RecyclerView -import org.futo.circles.core.extensions.loadEncryptedIntoWithAspect -import org.futo.circles.core.extensions.onClick -import org.futo.circles.core.extensions.setIsVisible -import org.futo.circles.core.list.ViewBindingHolder -import org.futo.circles.databinding.ListItemGalleryMediaBinding -import org.futo.circles.model.GalleryContentListItem -import org.futo.circles.core.model.PostContentType - -class GalleryItemViewHolder( - parent: ViewGroup, - onItemClicked: (Int) -> Unit -) : RecyclerView.ViewHolder((inflate(parent, ListItemGalleryMediaBinding::inflate))) { - - private companion object : ViewBindingHolder - - private val binding = baseBinding as ListItemGalleryMediaBinding - - init { - onClick(itemView) { position -> onItemClicked(position) } - } - - fun bind(data: GalleryContentListItem) { - binding.ivCover.post { - val size = data.mediaContent.calculateSize(binding.ivCover.width) - binding.ivCover.updateLayoutParams { - width = size.width - height = size.height - } - } - data.mediaContent.mediaFileData.loadEncryptedIntoWithAspect( - binding.ivCover, - data.mediaContent.aspectRatio, - data.mediaContent.mediaContentInfo.thumbHash - ) - binding.videoGroup.setIsVisible(data.mediaContent.type == PostContentType.VIDEO_CONTENT) - binding.tvDuration.text = data.mediaContent.mediaContentInfo.duration - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/gallery/list/GalleryItemsAdapter.kt b/app/src/main/java/org/futo/circles/feature/photos/gallery/list/GalleryItemsAdapter.kt deleted file mode 100644 index 4140022a4..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/gallery/list/GalleryItemsAdapter.kt +++ /dev/null @@ -1,25 +0,0 @@ -package org.futo.circles.feature.photos.gallery.list - -import android.view.ViewGroup -import org.futo.circles.core.list.BaseRvAdapter -import org.futo.circles.model.GalleryContentListItem - -class GalleryItemsAdapter( - private val onGalleryItemClicked: (item: GalleryContentListItem) -> Unit, - private val onLoadMore: () -> Unit -) : BaseRvAdapter<GalleryContentListItem, GalleryItemViewHolder>(DefaultIdEntityCallback()) { - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = GalleryItemViewHolder( - parent, - onItemClicked = { position -> onGalleryItemClicked(getItem(position)) } - ) - - override fun onBindViewHolder(holder: GalleryItemViewHolder, position: Int) { - holder.bind(getItem(position)) - if (position >= itemCount - LOAD_MORE_THRESHOLD) onLoadMore() - } - - companion object { - private const val LOAD_MORE_THRESHOLD = 10 - } -} diff --git a/app/src/main/java/org/futo/circles/feature/photos/list/GalleryViewHolder.kt b/app/src/main/java/org/futo/circles/feature/photos/list/GalleryViewHolder.kt deleted file mode 100644 index 440a6ce87..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/list/GalleryViewHolder.kt +++ /dev/null @@ -1,30 +0,0 @@ -package org.futo.circles.feature.photos.list - -import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import org.futo.circles.core.extensions.loadProfileIcon -import org.futo.circles.core.extensions.onClick -import org.futo.circles.core.list.ViewBindingHolder -import org.futo.circles.databinding.ListItemGalleryBinding -import org.futo.circles.model.GalleryListItem - -class GalleryViewHolder( - parent: ViewGroup, - onGalleryClicked: (Int) -> Unit -) : RecyclerView.ViewHolder(inflate(parent, ListItemGalleryBinding::inflate)) { - - private companion object : ViewBindingHolder - - private val binding = baseBinding as ListItemGalleryBinding - - init { - onClick(itemView) { position -> onGalleryClicked(position) } - } - - fun bind(data: GalleryListItem) { - with(binding) { - ivGalleryImage.loadProfileIcon(data.info.avatarUrl, "") - tvGalleryName.text = data.info.title - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/list/PhotosListAdapter.kt b/app/src/main/java/org/futo/circles/feature/photos/list/PhotosListAdapter.kt deleted file mode 100644 index 60834d229..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/list/PhotosListAdapter.kt +++ /dev/null @@ -1,23 +0,0 @@ -package org.futo.circles.feature.photos.list - -import android.view.ViewGroup -import org.futo.circles.core.list.BaseRvAdapter -import org.futo.circles.model.GalleryListItem - -class PhotosListAdapter( - private val onRoomClicked: (GalleryListItem) -> Unit -) : BaseRvAdapter<GalleryListItem, GalleryViewHolder>(DefaultIdEntityCallback()) { - - override fun onCreateViewHolder( - parent: ViewGroup, - viewType: Int - ) = GalleryViewHolder( - parent = parent, - onGalleryClicked = { position -> onRoomClicked(getItem(position)) } - ) - - override fun onBindViewHolder(holder: GalleryViewHolder, position: Int) { - holder.bind(getItem(position)) - } - -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/preview/MediaPreviewDataSource.kt b/app/src/main/java/org/futo/circles/feature/photos/preview/MediaPreviewDataSource.kt deleted file mode 100644 index 5e4ae540d..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/preview/MediaPreviewDataSource.kt +++ /dev/null @@ -1,34 +0,0 @@ -package org.futo.circles.feature.photos.preview - -import org.futo.circles.core.provider.MatrixSessionProvider -import org.futo.circles.core.mapping.toPost -import org.futo.circles.core.model.PostContent -import org.futo.circles.core.model.PostContentType -import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.api.session.getRoom -import org.matrix.android.sdk.api.session.room.getTimelineEvent -import org.matrix.android.sdk.api.session.room.model.message.MessageContent -import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent - -class MediaPreviewDataSource( - private val roomId: String, - private val eventId: String -) { - - private val session = MatrixSessionProvider.currentSession - - fun getPostContent(): PostContent? { - val roomForMessage = session?.getRoom(roomId) - val timelineEvent = roomForMessage?.getTimelineEvent(eventId) ?: return null - val post = getPostContentTypeFor(timelineEvent)?.let { timelineEvent.toPost(it) } - ?: return null - return post.content - } - - private fun getPostContentTypeFor(event: TimelineEvent): PostContentType? { - val messageType = event.root.getClearContent()?.toModel<MessageContent>()?.msgType - return PostContentType.values().firstOrNull { it.typeKey == messageType } - } - - -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/preview/MediaPreviewDialogFragment.kt b/app/src/main/java/org/futo/circles/feature/photos/preview/MediaPreviewDialogFragment.kt deleted file mode 100644 index f8fea9ce5..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/preview/MediaPreviewDialogFragment.kt +++ /dev/null @@ -1,179 +0,0 @@ -package org.futo.circles.feature.photos.preview - -import android.annotation.SuppressLint -import android.graphics.Color -import android.os.Bundle -import android.os.Handler -import android.os.Looper -import android.view.MotionEvent -import android.view.View -import android.view.WindowManager -import androidx.appcompat.view.menu.MenuBuilder -import androidx.core.view.isVisible -import androidx.navigation.fragment.navArgs -import com.google.android.exoplayer2.ExoPlayer -import com.google.android.exoplayer2.MediaItem -import com.google.android.exoplayer2.Player -import org.futo.circles.R -import org.futo.circles.core.extensions.gone -import org.futo.circles.core.extensions.loadEncryptedIntoWithAspect -import org.futo.circles.core.extensions.observeData -import org.futo.circles.core.extensions.onBackPressed -import org.futo.circles.core.extensions.setIsVisible -import org.futo.circles.core.extensions.showSuccess -import org.futo.circles.core.extensions.visible -import org.futo.circles.core.extensions.withConfirmation -import org.futo.circles.core.fragment.BaseFullscreenDialogFragment -import org.futo.circles.databinding.DialogFragmentMediaPreviewBinding -import org.futo.circles.extensions.* -import org.futo.circles.feature.share.ShareProvider -import org.futo.circles.model.RemoveImage -import org.koin.androidx.viewmodel.ext.android.viewModel -import org.koin.core.parameter.parametersOf - - -class MediaPreviewDialogFragment : - BaseFullscreenDialogFragment(DialogFragmentMediaPreviewBinding::inflate) { - - private val args: MediaPreviewDialogFragmentArgs by navArgs() - private val viewModel by viewModel<MediaPreviewViewModel> { - parametersOf(args.roomId, args.eventId) - } - - private val binding by lazy { getBinding() as DialogFragmentMediaPreviewBinding } - - private val hideHandler = Handler(Looper.getMainLooper()) - private val hideRunnable = Runnable { hide() } - - private val videoPlayer by lazy { - ExoPlayer.Builder(requireContext()).build().apply { - repeatMode = Player.REPEAT_MODE_ONE - addListener(object : Player.Listener { - override fun onIsLoadingChanged(isLoading: Boolean) { - super.onIsLoadingChanged(isLoading) - binding.vLoading.setIsVisible(isLoading) - } - }) - } - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - dialog?.window?.let { - it.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) - it.statusBarColor = Color.BLACK - } - viewModel.loadData(requireContext()) - setupViews() - setupToolbar() - setupObservers() - } - - override fun onPause() { - super.onPause() - videoPlayer.pause() - } - - override fun onResume() { - super.onResume() - videoPlayer.play() - } - - override fun onDestroy() { - videoPlayer.stop() - videoPlayer.release() - super.onDestroy() - } - - @SuppressLint("ClickableViewAccessibility") - private fun setupViews() { - with(binding) { - lParent.setOnClickListener { toggle() } - ivImage.setOnTouchListener { _, event -> - if (event.action == MotionEvent.ACTION_DOWN) toggle() - false - } - videoView.setOnClickListener { toggle() } - videoView.player = videoPlayer - videoView.controllerShowTimeoutMs = AUTO_HIDE_DELAY_MILLIS.toInt() - } - delayedHide() - } - - @SuppressLint("RestrictedApi") - private fun setupToolbar() { - with(binding.toolbar) { - setNavigationOnClickListener { onBackPressed() } - (menu as? MenuBuilder)?.setOptionalIconsVisible(true) - setOnMenuItemClickListener { item -> - return@setOnMenuItemClickListener when (item.itemId) { - R.id.save -> { - viewModel.save() - true - } - - R.id.share -> { - viewModel.share() - true - } - - R.id.delete -> { - withConfirmation(RemoveImage()) { - viewModel.removeImage() - onBackPressed() - } - true - } - - else -> false - } - } - } - } - - private fun setupObservers() { - viewModel.imageLiveData.observeData(this) { - binding.videoView.gone() - it.mediaFileData.loadEncryptedIntoWithAspect( - binding.ivImage, - it.aspectRatio, - it.mediaContentInfo.thumbHash - ) - } - viewModel.videoLiveData.observeData(this) { - binding.ivImage.gone() - videoPlayer.setMediaItem(MediaItem.fromUri(it.second)) - videoPlayer.prepare() - videoPlayer.play() - } - viewModel.shareLiveData.observeData(this) { content -> - context?.let { ShareProvider.share(it, content) } - } - viewModel.downloadLiveData.observeData(this) { - context?.let { showSuccess(it.getString(R.string.saved), false) } - } - } - - private fun toggle() { - if (binding.toolbar.isVisible) hide() else show() - } - - private fun hide() { - binding.toolbar.gone() - } - - private fun show() { - binding.toolbar.visible() - binding.videoView.showController() - delayedHide() - } - - private fun delayedHide() { - hideHandler.removeCallbacks(hideRunnable) - hideHandler.postDelayed(hideRunnable, AUTO_HIDE_DELAY_MILLIS) - } - - companion object { - private const val AUTO_HIDE_DELAY_MILLIS = 3000L - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/preview/MediaPreviewViewModel.kt b/app/src/main/java/org/futo/circles/feature/photos/preview/MediaPreviewViewModel.kt deleted file mode 100644 index 2ccb91705..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/preview/MediaPreviewViewModel.kt +++ /dev/null @@ -1,59 +0,0 @@ -package org.futo.circles.feature.photos.preview - -import android.content.Context -import android.net.Uri -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import org.futo.circles.core.SingleEventLiveData -import org.futo.circles.core.extensions.launchBg -import org.futo.circles.core.utils.FileUtils -import org.futo.circles.feature.share.ShareableContent -import org.futo.circles.feature.timeline.post.PostOptionsDataSource -import org.futo.circles.core.model.MediaContent -import org.futo.circles.core.model.PostContentType - -class MediaPreviewViewModel( - private val roomId: String, - private val eventId: String, - private val mediaPreviewDataSource: MediaPreviewDataSource, - private val postOptionsDataSource: PostOptionsDataSource -) : ViewModel() { - - val imageLiveData = MutableLiveData<MediaContent>() - val videoLiveData = MutableLiveData<Pair<MediaContent, Uri>>() - val shareLiveData = SingleEventLiveData<ShareableContent>() - val downloadLiveData = SingleEventLiveData<Unit>() - - - fun loadData(context: Context) { - val content = (mediaPreviewDataSource.getPostContent() as? MediaContent) ?: return - when (content.type) { - PostContentType.IMAGE_CONTENT -> imageLiveData.postValue(content) - PostContentType.VIDEO_CONTENT -> launchBg { - FileUtils.downloadEncryptedFileToContentUri(context, content.mediaFileData) - ?.let { videoLiveData.postValue(content to it) } - } - - else -> return - } - } - - fun share() { - val content = mediaPreviewDataSource.getPostContent() ?: return - launchBg { - shareLiveData.postValue(postOptionsDataSource.getShareableContent(content)) - } - } - - fun removeImage() { - postOptionsDataSource.removeMessage(roomId, eventId) - } - - fun save() { - val content = mediaPreviewDataSource.getPostContent() ?: return - launchBg { - postOptionsDataSource.saveMediaToDevice(content) - downloadLiveData.postValue(Unit) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/save/SavePostToGalleryDataSource.kt b/app/src/main/java/org/futo/circles/feature/photos/save/SavePostToGalleryDataSource.kt deleted file mode 100644 index 77107ade7..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/save/SavePostToGalleryDataSource.kt +++ /dev/null @@ -1,33 +0,0 @@ -package org.futo.circles.feature.photos.save - -import android.content.Context -import org.futo.circles.core.extensions.onBG -import org.futo.circles.core.utils.FileUtils -import org.futo.circles.core.timeline.SendMessageDataSource -import org.futo.circles.core.model.MediaContent -import org.futo.circles.core.model.PostContent -import org.futo.circles.model.SelectableRoomListItem - -class SavePostToGalleryDataSource( - private val context: Context, - private val sendMessageDataSource: SendMessageDataSource -) { - - suspend fun saveMediaToGalleries( - content: PostContent, - selectedGalleries: List<SelectableRoomListItem> - ) { - val mediaContent = content as? MediaContent ?: return - onBG { - val uri = - FileUtils.downloadEncryptedFileToContentUri(context, mediaContent.mediaFileData) - uri?.let { - selectedGalleries.forEach { - sendMessageDataSource.sendMedia( - it.id, uri, null, null, mediaContent.getMediaType() - ) - } - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/save/SavePostToGalleryViewModel.kt b/app/src/main/java/org/futo/circles/feature/photos/save/SavePostToGalleryViewModel.kt deleted file mode 100644 index dab0cc8fd..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/save/SavePostToGalleryViewModel.kt +++ /dev/null @@ -1,27 +0,0 @@ -package org.futo.circles.feature.photos.save - -import androidx.lifecycle.ViewModel -import org.futo.circles.core.SingleEventLiveData -import org.futo.circles.core.extensions.Response -import org.futo.circles.core.extensions.launchBg -import org.futo.circles.feature.photos.preview.MediaPreviewDataSource -import org.futo.circles.model.SelectableRoomListItem - -class SavePostToGalleryViewModel( - private val mediaPreviewDataSource: MediaPreviewDataSource, - private val savePostToGalleryDataSource: SavePostToGalleryDataSource -) : ViewModel() { - - - val saveResultLiveData = SingleEventLiveData<Response<Unit>>() - - fun saveToGallery(selectedGalleries: List<SelectableRoomListItem>) { - launchBg { - mediaPreviewDataSource.getPostContent()?.let { content -> - savePostToGalleryDataSource.saveMediaToGalleries(content, selectedGalleries) - } - saveResultLiveData.postValue(Response.Success(Unit)) - } - } - -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/save/SavePostToGalleyDialogFragment.kt b/app/src/main/java/org/futo/circles/feature/photos/save/SavePostToGalleyDialogFragment.kt deleted file mode 100644 index 904e550cd..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/save/SavePostToGalleyDialogFragment.kt +++ /dev/null @@ -1,69 +0,0 @@ -package org.futo.circles.feature.photos.save - -import android.os.Bundle -import android.view.View -import androidx.fragment.app.Fragment -import androidx.navigation.fragment.navArgs -import org.futo.circles.R -import org.futo.circles.base.SelectRoomsListener -import org.futo.circles.core.extensions.observeResponse -import org.futo.circles.core.extensions.onBackPressed -import org.futo.circles.core.extensions.showSuccess -import org.futo.circles.core.fragment.BaseFullscreenDialogFragment -import org.futo.circles.core.fragment.HasLoadingState -import org.futo.circles.databinding.DialogFragmentSavePostToGalleryBinding -import org.futo.circles.feature.photos.select.SelectGalleriesFragment -import org.futo.circles.model.SelectableRoomListItem -import org.koin.androidx.viewmodel.ext.android.viewModel -import org.koin.core.parameter.parametersOf - -class SavePostToGalleyDialogFragment : - BaseFullscreenDialogFragment(DialogFragmentSavePostToGalleryBinding::inflate), - HasLoadingState, SelectRoomsListener { - - override val fragment: Fragment = this - private val args: SavePostToGalleyDialogFragmentArgs by navArgs() - private val viewModel by viewModel<SavePostToGalleryViewModel> { - parametersOf(args.roomId, args.eventId) - } - private val binding by lazy { - getBinding() as DialogFragmentSavePostToGalleryBinding - } - - private val selectedGalleriesFragment by lazy { SelectGalleriesFragment() } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - addSelectGalleriesFragment() - setupViews() - setupObservers() - } - - private fun addSelectGalleriesFragment() { - childFragmentManager.beginTransaction() - .replace(R.id.lContainer, selectedGalleriesFragment) - .commitAllowingStateLoss() - } - - private fun setupViews() { - with(binding) { - btnSave.setOnClickListener { - viewModel.saveToGallery(selectedGalleriesFragment.getSelectedRooms()) - startLoading(btnSave) - } - } - } - - private fun setupObservers() { - viewModel.saveResultLiveData.observeResponse(this, - success = { - showSuccess(getString(R.string.saved), true) - onBackPressed() - } - ) - } - - override fun onRoomsSelected(rooms: List<SelectableRoomListItem>) { - binding.btnSave.isEnabled = rooms.isNotEmpty() - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/select/SelectGalleriesDataSource.kt b/app/src/main/java/org/futo/circles/feature/photos/select/SelectGalleriesDataSource.kt deleted file mode 100644 index 089c6cfdb..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/select/SelectGalleriesDataSource.kt +++ /dev/null @@ -1,33 +0,0 @@ -package org.futo.circles.feature.photos.select - -import androidx.lifecycle.MutableLiveData -import org.futo.circles.core.model.GALLERY_TYPE -import org.futo.circles.core.provider.MatrixSessionProvider -import org.futo.circles.mapping.toSelectableRoomListItem -import org.futo.circles.model.SelectableRoomListItem -import org.matrix.android.sdk.api.session.room.model.Membership -import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams - -class SelectGalleriesDataSource { - - private val session by lazy { MatrixSessionProvider.currentSession } - - val galleriesLiveData = MutableLiveData(getInitialGalleriesList()) - - private fun getInitialGalleriesList(): List<SelectableRoomListItem> = - session?.roomService()?.getRoomSummaries(roomSummaryQueryParams { - excludeType = null - })?.mapNotNull { summary -> - if (summary.roomType == GALLERY_TYPE && summary.membership == Membership.JOIN) - summary.toSelectableRoomListItem() - else null - } ?: emptyList() - - - fun toggleGallerySelect(gallery: SelectableRoomListItem) { - val newList = galleriesLiveData.value?.toMutableList()?.map { - if (it.id == gallery.id) it.copy(isSelected = !it.isSelected) else it - } - galleriesLiveData.postValue(newList) - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/select/SelectGalleriesFragment.kt b/app/src/main/java/org/futo/circles/feature/photos/select/SelectGalleriesFragment.kt deleted file mode 100644 index 5d5f23c87..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/select/SelectGalleriesFragment.kt +++ /dev/null @@ -1,65 +0,0 @@ -package org.futo.circles.feature.photos.select - -import android.content.Context -import android.os.Bundle -import android.view.View -import androidx.fragment.app.Fragment -import by.kirich1409.viewbindingdelegate.viewBinding -import org.futo.circles.R -import org.futo.circles.base.SelectRoomsListener -import org.futo.circles.core.extensions.observeData -import org.futo.circles.databinding.FragmentSelectGalleriesBinding -import org.futo.circles.feature.photos.select.list.SelectGalleryAdapter -import org.futo.circles.model.SelectableRoomListItem -import org.koin.androidx.viewmodel.ext.android.viewModel - -interface RoomsPicker { - var selectRoomsListener: SelectRoomsListener? - fun getSelectedRooms(): List<SelectableRoomListItem> -} - -class SelectGalleriesFragment : Fragment(R.layout.fragment_select_galleries), RoomsPicker { - - private val viewModel by viewModel<SelectGalleriesViewModel>() - private val binding by viewBinding(FragmentSelectGalleriesBinding::bind) - - private val listAdapter by lazy { - SelectGalleryAdapter( - onGalleryClicked = { galleryListItem -> onGallerySelected(galleryListItem) }, - ) - } - - override var selectRoomsListener: SelectRoomsListener? = null - - override fun onAttach(context: Context) { - super.onAttach(context) - selectRoomsListener = (parentFragment as? SelectRoomsListener) - if (selectRoomsListener == null) - selectRoomsListener = activity as? SelectRoomsListener - } - - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - super.onViewCreated(view, savedInstanceState) - setupViews() - setupObservers() - } - - override fun getSelectedRooms(): List<SelectableRoomListItem> = - viewModel.galleriesLiveData.value?.filter { it.isSelected } ?: emptyList() - - private fun setupViews() { - binding.rvGalleries.adapter = listAdapter - } - - private fun setupObservers() { - viewModel.galleriesLiveData.observeData(this) { - listAdapter.submitList(it) - selectRoomsListener?.onRoomsSelected(it.filter { it.isSelected }) - } - } - - private fun onGallerySelected(gallery: SelectableRoomListItem) { - viewModel.toggleGallerySelect(gallery) - } - -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/select/SelectGalleriesViewModel.kt b/app/src/main/java/org/futo/circles/feature/photos/select/SelectGalleriesViewModel.kt deleted file mode 100644 index 225f0ae18..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/select/SelectGalleriesViewModel.kt +++ /dev/null @@ -1,16 +0,0 @@ -package org.futo.circles.feature.photos.select - -import androidx.lifecycle.ViewModel -import org.futo.circles.model.SelectableRoomListItem - -class SelectGalleriesViewModel( - private val selectGalleriesDataSource: SelectGalleriesDataSource -) : ViewModel() { - - val galleriesLiveData = selectGalleriesDataSource.galleriesLiveData - - fun toggleGallerySelect(selectableRoomListItem: SelectableRoomListItem) { - selectGalleriesDataSource.toggleGallerySelect(selectableRoomListItem) - } - -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/select/list/SelectGalleryAdapter.kt b/app/src/main/java/org/futo/circles/feature/photos/select/list/SelectGalleryAdapter.kt deleted file mode 100644 index 26150b046..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/select/list/SelectGalleryAdapter.kt +++ /dev/null @@ -1,23 +0,0 @@ -package org.futo.circles.feature.photos.select.list - -import android.view.ViewGroup -import org.futo.circles.core.list.BaseRvAdapter -import org.futo.circles.gallery.feature.select.list.SelectGalleryViewHolder -import org.futo.circles.model.SelectableRoomListItem - -class SelectGalleryAdapter( - private val onGalleryClicked: (SelectableRoomListItem) -> Unit, -) : BaseRvAdapter<SelectableRoomListItem, SelectGalleryViewHolder>(DefaultIdEntityCallback()) { - - override fun onCreateViewHolder( - parent: ViewGroup, - viewType: Int - ): SelectGalleryViewHolder = SelectGalleryViewHolder( - parent = parent, - onGalleryClicked = { position -> onGalleryClicked(getItem(position)) } - ) - - override fun onBindViewHolder(holder: SelectGalleryViewHolder, position: Int) { - holder.bind(getItem(position)) - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/photos/select/list/SelectGalleryViewHolder.kt b/app/src/main/java/org/futo/circles/feature/photos/select/list/SelectGalleryViewHolder.kt deleted file mode 100644 index 32af89c25..000000000 --- a/app/src/main/java/org/futo/circles/feature/photos/select/list/SelectGalleryViewHolder.kt +++ /dev/null @@ -1,34 +0,0 @@ -package org.futo.circles.feature.photos.select.list - -import android.view.ViewGroup -import androidx.recyclerview.widget.RecyclerView -import org.futo.circles.R -import org.futo.circles.core.extensions.loadProfileIcon -import org.futo.circles.core.extensions.onClick -import org.futo.circles.core.extensions.setIsVisible -import org.futo.circles.core.list.ViewBindingHolder -import org.futo.circles.databinding.ListItemSelectGalleryBinding -import org.futo.circles.model.SelectableRoomListItem - -class SelectGalleryViewHolder( - parent: ViewGroup, - onGalleryClicked: (Int) -> Unit -) : RecyclerView.ViewHolder(inflate(parent, ListItemSelectGalleryBinding::inflate)) { - - private companion object : ViewBindingHolder - - private val binding = baseBinding as ListItemSelectGalleryBinding - - init { - onClick(binding.baseGalleryItem.root) { position -> onGalleryClicked(position) } - } - - fun bind(data: SelectableRoomListItem) { - with(binding) { - baseGalleryItem.ivGalleryImage.loadProfileIcon(data.info.avatarUrl, "") - baseGalleryItem.tvGalleryName.text = data.info.title - ivSelect.setImageResource(if (data.isSelected) R.drawable.ic_check_circle else R.drawable.ic_unselected) - vSelectBackground.setIsVisible(data.isSelected) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/room/select/SelectRoomsDataSource.kt b/app/src/main/java/org/futo/circles/feature/room/select/SelectRoomsDataSource.kt index 782e00450..803d50412 100644 --- a/app/src/main/java/org/futo/circles/feature/room/select/SelectRoomsDataSource.kt +++ b/app/src/main/java/org/futo/circles/feature/room/select/SelectRoomsDataSource.kt @@ -14,7 +14,7 @@ import org.futo.circles.core.model.GALLERY_TYPE import org.futo.circles.core.model.GROUP_TYPE import org.futo.circles.core.provider.MatrixSessionProvider import org.futo.circles.mapping.toSelectableRoomListItem -import org.futo.circles.model.SelectableRoomListItem +import org.futo.circles.core.model.SelectableRoomListItem import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams diff --git a/app/src/main/java/org/futo/circles/feature/room/select/SelectRoomsFragment.kt b/app/src/main/java/org/futo/circles/feature/room/select/SelectRoomsFragment.kt index cd55a8a79..4c04a9c94 100644 --- a/app/src/main/java/org/futo/circles/feature/room/select/SelectRoomsFragment.kt +++ b/app/src/main/java/org/futo/circles/feature/room/select/SelectRoomsFragment.kt @@ -9,11 +9,11 @@ import androidx.recyclerview.widget.DividerItemDecoration import by.kirich1409.viewbindingdelegate.viewBinding import org.futo.circles.R import org.futo.circles.base.RoomsListener -import org.futo.circles.base.SelectRoomsListener +import org.futo.circles.core.room.select.SelectRoomsListener import org.futo.circles.core.extensions.observeData import org.futo.circles.core.extensions.setIsVisible import org.futo.circles.databinding.FragmentSelectRoomsBinding -import org.futo.circles.feature.photos.select.RoomsPicker +import org.futo.circles.gallery.feature.select.RoomsPicker import org.futo.circles.feature.room.select.list.SelectRoomsAdapter import org.futo.circles.feature.room.select.list.SelectedChipsRoomsAdapter import org.koin.androidx.viewmodel.ext.android.viewModel diff --git a/app/src/main/java/org/futo/circles/feature/room/select/SelectRoomsViewModel.kt b/app/src/main/java/org/futo/circles/feature/room/select/SelectRoomsViewModel.kt index bbad40964..866967dc4 100644 --- a/app/src/main/java/org/futo/circles/feature/room/select/SelectRoomsViewModel.kt +++ b/app/src/main/java/org/futo/circles/feature/room/select/SelectRoomsViewModel.kt @@ -2,7 +2,7 @@ package org.futo.circles.feature.room.select import androidx.lifecycle.ViewModel import androidx.lifecycle.asLiveData -import org.futo.circles.model.SelectableRoomListItem +import org.futo.circles.core.model.SelectableRoomListItem class SelectRoomsViewModel( private val dataSource: SelectRoomsDataSource diff --git a/app/src/main/java/org/futo/circles/feature/room/select/list/SelectRoomsAdapter.kt b/app/src/main/java/org/futo/circles/feature/room/select/list/SelectRoomsAdapter.kt index f927f9f51..9e20a4e19 100644 --- a/app/src/main/java/org/futo/circles/feature/room/select/list/SelectRoomsAdapter.kt +++ b/app/src/main/java/org/futo/circles/feature/room/select/list/SelectRoomsAdapter.kt @@ -2,7 +2,7 @@ package org.futo.circles.feature.room.select.list import android.view.ViewGroup import org.futo.circles.core.list.BaseRvAdapter -import org.futo.circles.model.SelectableRoomListItem +import org.futo.circles.core.model.SelectableRoomListItem class SelectRoomsAdapter( private val onRoomSelected: (SelectableRoomListItem) -> Unit diff --git a/app/src/main/java/org/futo/circles/feature/room/select/list/SelectRoomsViewHolder.kt b/app/src/main/java/org/futo/circles/feature/room/select/list/SelectRoomsViewHolder.kt index 1bea4bbe0..ffe8a3243 100644 --- a/app/src/main/java/org/futo/circles/feature/room/select/list/SelectRoomsViewHolder.kt +++ b/app/src/main/java/org/futo/circles/feature/room/select/list/SelectRoomsViewHolder.kt @@ -9,7 +9,7 @@ import org.futo.circles.core.extensions.setSelectableItemBackground import org.futo.circles.core.list.ViewBindingHolder import org.futo.circles.core.list.context import org.futo.circles.databinding.ListItemSelectRoomBinding -import org.futo.circles.model.SelectableRoomListItem +import org.futo.circles.core.model.SelectableRoomListItem class SelectRoomsViewHolder( parent: ViewGroup, diff --git a/app/src/main/java/org/futo/circles/feature/room/select/list/SelectedChipsRoomsAdapter.kt b/app/src/main/java/org/futo/circles/feature/room/select/list/SelectedChipsRoomsAdapter.kt index 4e3c0c8ea..9985c39e1 100644 --- a/app/src/main/java/org/futo/circles/feature/room/select/list/SelectedChipsRoomsAdapter.kt +++ b/app/src/main/java/org/futo/circles/feature/room/select/list/SelectedChipsRoomsAdapter.kt @@ -2,7 +2,7 @@ package org.futo.circles.feature.room.select.list import android.view.ViewGroup import org.futo.circles.core.list.BaseRvAdapter -import org.futo.circles.model.SelectableRoomListItem +import org.futo.circles.core.model.SelectableRoomListItem class SelectedChipsRoomsAdapter( private val onCircleDeselected: (SelectableRoomListItem) -> Unit diff --git a/app/src/main/java/org/futo/circles/feature/settings/active_sessions/verify/qr/QrScannerActivity.kt b/app/src/main/java/org/futo/circles/feature/settings/active_sessions/verify/qr/QrScannerActivity.kt index 8c3a529db..30b013999 100644 --- a/app/src/main/java/org/futo/circles/feature/settings/active_sessions/verify/qr/QrScannerActivity.kt +++ b/app/src/main/java/org/futo/circles/feature/settings/active_sessions/verify/qr/QrScannerActivity.kt @@ -13,7 +13,7 @@ import com.google.zxing.BarcodeFormat import com.google.zxing.Result import com.google.zxing.ResultMetadataType import org.futo.circles.R -import org.futo.circles.base.BaseActivity +import org.futo.circles.core.BaseActivity import org.futo.circles.databinding.ActivityQrScannerBinding class QrScannerActivity : BaseActivity(R.layout.activity_qr_scanner) { diff --git a/app/src/main/java/org/futo/circles/feature/share/circle/ShareWithCircleActivity.kt b/app/src/main/java/org/futo/circles/feature/share/circle/ShareWithCircleActivity.kt index 735eba838..80bb87bf5 100644 --- a/app/src/main/java/org/futo/circles/feature/share/circle/ShareWithCircleActivity.kt +++ b/app/src/main/java/org/futo/circles/feature/share/circle/ShareWithCircleActivity.kt @@ -3,13 +3,14 @@ package org.futo.circles.feature.share.circle import org.futo.circles.R import org.futo.circles.core.utils.getTimelineRoomFor import org.futo.circles.feature.room.select.SelectRoomsFragment -import org.futo.circles.feature.share.BaseShareActivity +import org.futo.circles.core.share.BaseShareActivity +import org.futo.circles.gallery.feature.select.RoomsPicker class ShareWithCircleActivity : BaseShareActivity() { override val titleResId: Int = R.string.share_with_circle - override val roomsPicker: org.futo.circles.feature.photos.select.RoomsPicker = + override val roomsPicker: RoomsPicker = SelectRoomsFragment.create(CircleRoomTypeArg.Circle) override fun getShareRoomsIds(): List<String> = diff --git a/app/src/main/java/org/futo/circles/feature/share/group/ShareWithGroupActivity.kt b/app/src/main/java/org/futo/circles/feature/share/group/ShareWithGroupActivity.kt index 0be56d16d..a91a4b663 100644 --- a/app/src/main/java/org/futo/circles/feature/share/group/ShareWithGroupActivity.kt +++ b/app/src/main/java/org/futo/circles/feature/share/group/ShareWithGroupActivity.kt @@ -1,9 +1,9 @@ package org.futo.circles.feature.share.group import org.futo.circles.R -import org.futo.circles.feature.photos.select.RoomsPicker +import org.futo.circles.gallery.feature.select.RoomsPicker import org.futo.circles.feature.room.select.SelectRoomsFragment -import org.futo.circles.feature.share.BaseShareActivity +import org.futo.circles.core.share.BaseShareActivity class ShareWithGroupActivity : BaseShareActivity() { diff --git a/app/src/main/java/org/futo/circles/feature/timeline/TimelineFragment.kt b/app/src/main/java/org/futo/circles/feature/timeline/TimelineFragment.kt index cbf090bbe..146143361 100644 --- a/app/src/main/java/org/futo/circles/feature/timeline/TimelineFragment.kt +++ b/app/src/main/java/org/futo/circles/feature/timeline/TimelineFragment.kt @@ -33,7 +33,7 @@ import org.futo.circles.core.provider.PreferencesProvider import org.futo.circles.core.utils.getTimelineRoomFor import org.futo.circles.databinding.FragmentTimelineBinding import org.futo.circles.extensions.* -import org.futo.circles.feature.share.ShareProvider +import org.futo.circles.core.share.ShareProvider import org.futo.circles.feature.timeline.list.TimelineAdapter import org.futo.circles.feature.timeline.poll.CreatePollListener import org.futo.circles.feature.timeline.post.create.CreatePostListener diff --git a/app/src/main/java/org/futo/circles/feature/timeline/TimelineViewModel.kt b/app/src/main/java/org/futo/circles/feature/timeline/TimelineViewModel.kt index 840e158df..28ad652f2 100644 --- a/app/src/main/java/org/futo/circles/feature/timeline/TimelineViewModel.kt +++ b/app/src/main/java/org/futo/circles/feature/timeline/TimelineViewModel.kt @@ -7,12 +7,12 @@ import org.futo.circles.core.extensions.launchBg import org.futo.circles.feature.people.UserOptionsDataSource import org.futo.circles.core.room.leave.LeaveRoomDataSource import org.futo.circles.feature.room.RoomNotificationsDataSource -import org.futo.circles.feature.share.ShareableContent +import org.futo.circles.core.model.ShareableContent import org.futo.circles.feature.timeline.data_source.AccessLevelDataSource import org.futo.circles.feature.timeline.data_source.ReadMessageDataSource -import org.futo.circles.core.timeline.SendMessageDataSource +import org.futo.circles.core.timeline.post.SendMessageDataSource import org.futo.circles.core.timeline.TimelineDataSource -import org.futo.circles.feature.timeline.post.PostOptionsDataSource +import org.futo.circles.core.timeline.post.PostOptionsDataSource import org.futo.circles.core.model.CreatePollContent import org.futo.circles.core.timeline.BaseTimelineViewModel import org.futo.circles.model.CreatePostContent diff --git a/app/src/main/java/org/futo/circles/mapping/RoomListItemMapping.kt b/app/src/main/java/org/futo/circles/mapping/RoomSummaryMapping.kt similarity index 92% rename from app/src/main/java/org/futo/circles/mapping/RoomListItemMapping.kt rename to app/src/main/java/org/futo/circles/mapping/RoomSummaryMapping.kt index d6edfa184..843961929 100644 --- a/app/src/main/java/org/futo/circles/mapping/RoomListItemMapping.kt +++ b/app/src/main/java/org/futo/circles/mapping/RoomSummaryMapping.kt @@ -9,7 +9,6 @@ import org.futo.circles.model.InvitedCircleListItem import org.futo.circles.model.InvitedGroupListItem import org.futo.circles.model.JoinedCircleListItem import org.futo.circles.model.JoinedGroupListItem -import org.futo.circles.model.SelectableRoomListItem import org.futo.circles.model.TimelineRoomListItem import org.matrix.android.sdk.api.session.getRoomSummary import org.matrix.android.sdk.api.session.getUserOrDefault @@ -50,12 +49,6 @@ fun RoomSummary.toInviteCircleListItem() = InvitedCircleListItem( inviterName = getInviterName() ) -fun RoomSummary.toSelectableRoomListItem(selected: Boolean = false) = SelectableRoomListItem( - id = roomId, - info = toRoomInfo(), - isSelected = selected -) - private fun RoomSummary.getFollowersCount(): Int = getTimelineRoomFor(roomId)?.roomSummary()?.otherMemberIds?.size ?: 0 diff --git a/app/src/main/java/org/futo/circles/model/ConfirmationType.kt b/app/src/main/java/org/futo/circles/model/ConfirmationType.kt index aec4b5cbe..559d1fbb9 100644 --- a/app/src/main/java/org/futo/circles/model/ConfirmationType.kt +++ b/app/src/main/java/org/futo/circles/model/ConfirmationType.kt @@ -40,11 +40,6 @@ data class UnfollowTimeline( override val positiveButtonRes: Int = R.string.unfollow ) : ConfirmationType(titleRes, messageRes, positiveButtonRes) -data class RemoveImage( - override val titleRes: Int = R.string.remove_image, - override val messageRes: Int = R.string.remove_image_message, - override val positiveButtonRes: Int = R.string.remove -) : ConfirmationType(titleRes, messageRes, positiveButtonRes) data class RemovePost( override val titleRes: Int = R.string.remove_post, diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f20aef32a..6a5ee5b82 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -96,9 +96,7 @@ <string name="saved">Saved</string> <string name="you_can_not_post_to_this_room">You can not post to this room</string> <string name="remove_post">Remove post</string> - <string name="remove_image">Remove image</string> <string name="remove_post_message">Are you sure you want to remove this post?</string> - <string name="remove_image_message">Are you sure you want to remove this image?</string> <string name="ignore_user_message">Ignoring this user will remove their messages from rooms you share.</string> <string name="unfollow_user_message">Are you sure you want to unfollow this user?</string> <string name="unfollow_user_timeline">Are you sure you want to unfollow this timeline?</string> @@ -129,12 +127,10 @@ <string name="configure_gallery">Configure gallery</string> <string name="delete_circle">Delete circle</string> <string name="delete_group">Delete group</string> - <string name="delete_gallery">Delete gallery</string> <string name="my_followers">My followers</string> <string name="people_i_m_following">People I\'m following</string> <string name="delete_circle_message">Are you sure you want to remove this circle?</string> <string name="delete_group_message">Are you sure you want to remove this group?</string> - <string name="delete_gallery_message">Are you sure you want to remove this gallery?</string> <string name="timeline_not_found">Timeline not found</string> <string name="remove_from_this_circle_but_do_not_unfollow">Remove from this circle, but do not unfollow</string> <string name="unfollow_completely_remove_from_all_circles">Unfollow completely (remove from all circles)</string> @@ -330,8 +326,6 @@ <string name="notification_media_backup">Media backup</string> <string name="thread_format">%s (thread)</string> <string name="unexpected_error">Something went wrong</string> - <string name="choose_gallery">Choose gallery</string> - <string name="pick_media">Pick media</string> <string name="configuring_workspace">Configuring workspace</string> <string name="shared_circles">Shared Circles</string> <string name="remove_user">Remove user</string> diff --git a/core/build.gradle b/core/build.gradle index 8d346d85f..596b97785 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -89,6 +89,9 @@ dependencies { implementation "com.github.bumptech.glide:glide:$glide_version" kapt "com.github.bumptech.glide:compiler:$glide_version" + //Shake detection + implementation 'com.squareup:seismic:1.0.3' + testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' diff --git a/app/src/main/java/org/futo/circles/base/BaseActivity.kt b/core/src/main/java/org/futo/circles/core/BaseActivity.kt similarity index 69% rename from app/src/main/java/org/futo/circles/base/BaseActivity.kt rename to core/src/main/java/org/futo/circles/core/BaseActivity.kt index c4f1e0c17..866b753eb 100644 --- a/app/src/main/java/org/futo/circles/base/BaseActivity.kt +++ b/core/src/main/java/org/futo/circles/core/BaseActivity.kt @@ -1,12 +1,11 @@ -package org.futo.circles.base +package org.futo.circles.core import android.content.Context import android.content.ContextWrapper import androidx.appcompat.app.AppCompatActivity -import org.futo.circles.BuildConfig -import org.futo.circles.extensions.disableScreenScale -import org.futo.circles.feature.rageshake.BugReportDataCollector -import org.futo.circles.feature.rageshake.RageShake +import org.futo.circles.core.extensions.disableScreenScale +import org.futo.circles.core.rageshake.BugReportDataCollector +import org.futo.circles.core.rageshake.RageShake import org.koin.android.ext.android.inject abstract class BaseActivity(contentLayoutId: Int) : AppCompatActivity(contentLayoutId) { @@ -19,7 +18,7 @@ abstract class BaseActivity(contentLayoutId: Int) : AppCompatActivity(contentLay override fun onResume() { super.onResume() - if (BuildConfig.RAGESHAKE_ENABLED) rageShake.start() + if (CirclesAppConfig.isRageshakeEnabled) rageShake.start() } override fun onPause() { diff --git a/core/src/main/java/org/futo/circles/core/CirclesAppConfig.kt b/core/src/main/java/org/futo/circles/core/CirclesAppConfig.kt index 89494d6e8..6835aa89f 100644 --- a/core/src/main/java/org/futo/circles/core/CirclesAppConfig.kt +++ b/core/src/main/java/org/futo/circles/core/CirclesAppConfig.kt @@ -19,6 +19,8 @@ object CirclesAppConfig { var isMediaBackupEnabled = false private set + var isRageshakeEnabled = false + private set data class Initializer( private var appId: String? = null, @@ -28,7 +30,8 @@ object CirclesAppConfig { private var debugEuDomain: String? = null, private var releaseEuDomain: String? = null, private var subscriptionEnabled: Boolean = false, - private var mediaBackupEnabled: Boolean = false + private var mediaBackupEnabled: Boolean = false, + private var rageshakeEnabled: Boolean = false ) { fun appId(appId: String) = apply { this.appId = appId } @@ -50,6 +53,8 @@ object CirclesAppConfig { fun isMediaBackupEnabled(isEnabled: Boolean) = apply { this.mediaBackupEnabled = isEnabled } + fun isRageshakeEnabled(isEnabled: Boolean) = apply { this.rageshakeEnabled = isEnabled } + fun init() { CirclesAppConfig.appId = appId?.takeIf { it.isNotEmpty() } ?: throw IllegalArgumentException("Illegal appId $appId") @@ -73,6 +78,7 @@ object CirclesAppConfig { isSubscriptionsEnabled = subscriptionEnabled isMediaBackupEnabled = mediaBackupEnabled + isRageshakeEnabled = rageshakeEnabled } } diff --git a/core/src/main/java/org/futo/circles/core/extensions/ContextExtensions.kt b/core/src/main/java/org/futo/circles/core/extensions/ContextExtensions.kt new file mode 100644 index 000000000..f018be3ff --- /dev/null +++ b/core/src/main/java/org/futo/circles/core/extensions/ContextExtensions.kt @@ -0,0 +1,11 @@ +package org.futo.circles.core.extensions + +import android.content.Context + +fun Context.disableScreenScale(): Context { + val overrideConfiguration = resources.configuration.apply { + fontScale = 1f + densityDpi = resources.displayMetrics.xdpi.toInt() + } + return createConfigurationContext(overrideConfiguration) +} \ No newline at end of file diff --git a/core/src/main/java/org/futo/circles/core/mapping/RoomSummaryMapping.kt b/core/src/main/java/org/futo/circles/core/mapping/RoomSummaryMapping.kt index ca53aa9cd..d57dbb8d3 100644 --- a/core/src/main/java/org/futo/circles/core/mapping/RoomSummaryMapping.kt +++ b/core/src/main/java/org/futo/circles/core/mapping/RoomSummaryMapping.kt @@ -1,6 +1,7 @@ package org.futo.circles.core.mapping import org.futo.circles.core.model.RoomInfo +import org.futo.circles.core.model.SelectableRoomListItem import org.matrix.android.sdk.api.session.room.model.RoomSummary fun RoomSummary.nameOrId() = displayName.takeIf { it.isNotEmpty() } ?: roomId @@ -8,4 +9,10 @@ fun RoomSummary.nameOrId() = displayName.takeIf { it.isNotEmpty() } ?: roomId fun RoomSummary.toRoomInfo() = RoomInfo( title = nameOrId(), avatarUrl = avatarUrl +) + +fun RoomSummary.toSelectableRoomListItem(selected: Boolean = false) = SelectableRoomListItem( + id = roomId, + info = toRoomInfo(), + isSelected = selected ) \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/model/SelectableRoomListItem.kt b/core/src/main/java/org/futo/circles/core/model/SelectableRoomListItem.kt similarity index 83% rename from app/src/main/java/org/futo/circles/model/SelectableRoomListItem.kt rename to core/src/main/java/org/futo/circles/core/model/SelectableRoomListItem.kt index 2e5fd3718..0c2a967f4 100644 --- a/app/src/main/java/org/futo/circles/model/SelectableRoomListItem.kt +++ b/core/src/main/java/org/futo/circles/core/model/SelectableRoomListItem.kt @@ -1,4 +1,4 @@ -package org.futo.circles.model +package org.futo.circles.core.model import org.futo.circles.core.list.IdEntity diff --git a/app/src/main/java/org/futo/circles/feature/share/SharableContent.kt b/core/src/main/java/org/futo/circles/core/model/SharableContent.kt similarity index 71% rename from app/src/main/java/org/futo/circles/feature/share/SharableContent.kt rename to core/src/main/java/org/futo/circles/core/model/SharableContent.kt index b0d21c728..e644cc9c7 100644 --- a/app/src/main/java/org/futo/circles/feature/share/SharableContent.kt +++ b/core/src/main/java/org/futo/circles/core/model/SharableContent.kt @@ -1,8 +1,8 @@ -package org.futo.circles.feature.share +package org.futo.circles.core.model import android.net.Uri -sealed class ShareableContent() +sealed class ShareableContent data class TextShareable(val text: String) : ShareableContent() data class MediaShareable(val uriToFile: Uri, val mimeType: String) : ShareableContent() diff --git a/app/src/main/java/org/futo/circles/feature/rageshake/BugReportDataCollector.kt b/core/src/main/java/org/futo/circles/core/rageshake/BugReportDataCollector.kt similarity index 98% rename from app/src/main/java/org/futo/circles/feature/rageshake/BugReportDataCollector.kt rename to core/src/main/java/org/futo/circles/core/rageshake/BugReportDataCollector.kt index 48040f4df..a77e322f6 100644 --- a/app/src/main/java/org/futo/circles/feature/rageshake/BugReportDataCollector.kt +++ b/core/src/main/java/org/futo/circles/core/rageshake/BugReportDataCollector.kt @@ -1,4 +1,4 @@ -package org.futo.circles.feature.rageshake +package org.futo.circles.core.rageshake import android.content.Context import android.graphics.Bitmap @@ -11,8 +11,8 @@ import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.RequestBody import okhttp3.RequestBody.Companion.asRequestBody import okhttp3.RequestBody.Companion.toRequestBody -import org.futo.circles.BuildConfig -import org.futo.circles.R +import org.futo.circles.core.BuildConfig +import org.futo.circles.core.R import org.futo.circles.core.extensions.getAllChildFragments import org.futo.circles.core.provider.MatrixInstanceProvider import org.futo.circles.core.provider.MatrixSessionProvider diff --git a/app/src/main/java/org/futo/circles/feature/rageshake/BugReportDataSource.kt b/core/src/main/java/org/futo/circles/core/rageshake/BugReportDataSource.kt similarity index 95% rename from app/src/main/java/org/futo/circles/feature/rageshake/BugReportDataSource.kt rename to core/src/main/java/org/futo/circles/core/rageshake/BugReportDataSource.kt index 8014fdc1c..27856b2f9 100644 --- a/app/src/main/java/org/futo/circles/feature/rageshake/BugReportDataSource.kt +++ b/core/src/main/java/org/futo/circles/core/rageshake/BugReportDataSource.kt @@ -1,4 +1,4 @@ -package org.futo.circles.feature.rageshake +package org.futo.circles.core.rageshake import okhttp3.ResponseBody import org.futo.circles.core.extensions.Response diff --git a/app/src/main/java/org/futo/circles/feature/rageshake/BugReportDialogFragment.kt b/core/src/main/java/org/futo/circles/core/rageshake/BugReportDialogFragment.kt similarity index 98% rename from app/src/main/java/org/futo/circles/feature/rageshake/BugReportDialogFragment.kt rename to core/src/main/java/org/futo/circles/core/rageshake/BugReportDialogFragment.kt index a596cb534..f74c58705 100644 --- a/app/src/main/java/org/futo/circles/feature/rageshake/BugReportDialogFragment.kt +++ b/core/src/main/java/org/futo/circles/core/rageshake/BugReportDialogFragment.kt @@ -1,4 +1,4 @@ -package org.futo.circles.feature.rageshake +package org.futo.circles.core.rageshake import android.os.Bundle import android.view.View diff --git a/app/src/main/java/org/futo/circles/feature/rageshake/BugReportViewModel.kt b/core/src/main/java/org/futo/circles/core/rageshake/BugReportViewModel.kt similarity index 95% rename from app/src/main/java/org/futo/circles/feature/rageshake/BugReportViewModel.kt rename to core/src/main/java/org/futo/circles/core/rageshake/BugReportViewModel.kt index 16f4d1e9a..1c78dddf4 100644 --- a/app/src/main/java/org/futo/circles/feature/rageshake/BugReportViewModel.kt +++ b/core/src/main/java/org/futo/circles/core/rageshake/BugReportViewModel.kt @@ -1,4 +1,4 @@ -package org.futo.circles.feature.rageshake +package org.futo.circles.core.rageshake import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel diff --git a/app/src/main/java/org/futo/circles/feature/rageshake/RageShake.kt b/core/src/main/java/org/futo/circles/core/rageshake/RageShake.kt similarity index 96% rename from app/src/main/java/org/futo/circles/feature/rageshake/RageShake.kt rename to core/src/main/java/org/futo/circles/core/rageshake/RageShake.kt index c0ae10748..d71edd910 100644 --- a/app/src/main/java/org/futo/circles/feature/rageshake/RageShake.kt +++ b/core/src/main/java/org/futo/circles/core/rageshake/RageShake.kt @@ -1,4 +1,4 @@ -package org.futo.circles.feature.rageshake +package org.futo.circles.core.rageshake import android.hardware.SensorManager import android.os.Build @@ -9,6 +9,7 @@ import androidx.core.content.getSystemService import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.squareup.seismic.ShakeDetector import org.futo.circles.R +import org.futo.circles.core.R class RageShake( private val activity: AppCompatActivity, diff --git a/core/src/main/java/org/futo/circles/core/room/select/RoomsPicker.kt b/core/src/main/java/org/futo/circles/core/room/select/RoomsPicker.kt new file mode 100644 index 000000000..c3226eda6 --- /dev/null +++ b/core/src/main/java/org/futo/circles/core/room/select/RoomsPicker.kt @@ -0,0 +1,8 @@ +package org.futo.circles.core.room.select + +import org.futo.circles.core.model.SelectableRoomListItem + +interface RoomsPicker { + var selectRoomsListener: SelectRoomsListener? + fun getSelectedRooms(): List<SelectableRoomListItem> +} \ No newline at end of file diff --git a/core/src/main/java/org/futo/circles/core/room/select/SelectRoomsListener.kt b/core/src/main/java/org/futo/circles/core/room/select/SelectRoomsListener.kt new file mode 100644 index 000000000..c700172f4 --- /dev/null +++ b/core/src/main/java/org/futo/circles/core/room/select/SelectRoomsListener.kt @@ -0,0 +1,7 @@ +package org.futo.circles.core.room.select + +import org.futo.circles.core.model.SelectableRoomListItem + +interface SelectRoomsListener { + fun onRoomsSelected(rooms: List<SelectableRoomListItem>) +} \ No newline at end of file diff --git a/app/src/main/java/org/futo/circles/feature/share/BaseShareActivity.kt b/core/src/main/java/org/futo/circles/core/share/BaseShareActivity.kt similarity index 81% rename from app/src/main/java/org/futo/circles/feature/share/BaseShareActivity.kt rename to core/src/main/java/org/futo/circles/core/share/BaseShareActivity.kt index 47a4e9e92..7dc41ba78 100644 --- a/app/src/main/java/org/futo/circles/feature/share/BaseShareActivity.kt +++ b/core/src/main/java/org/futo/circles/core/share/BaseShareActivity.kt @@ -1,19 +1,19 @@ -package org.futo.circles.feature.share +package org.futo.circles.core.share import android.content.Intent import android.net.Uri import android.os.Bundle import androidx.fragment.app.Fragment import by.kirich1409.viewbindingdelegate.viewBinding -import org.futo.circles.MainActivity -import org.futo.circles.R -import org.futo.circles.base.BaseActivity -import org.futo.circles.base.SelectRoomsListener +import org.futo.circles.core.BaseActivity +import org.futo.circles.core.CirclesAppConfig +import org.futo.circles.core.R +import org.futo.circles.core.databinding.ActivityBaseShareBinding +import org.futo.circles.core.model.SelectableRoomListItem import org.futo.circles.core.picker.MediaType import org.futo.circles.core.provider.MatrixSessionProvider -import org.futo.circles.databinding.ActivityBaseShareBinding -import org.futo.circles.feature.photos.select.RoomsPicker -import org.futo.circles.model.SelectableRoomListItem +import org.futo.circles.core.room.select.RoomsPicker +import org.futo.circles.core.room.select.SelectRoomsListener import org.koin.androidx.viewmodel.ext.android.viewModel abstract class BaseShareActivity : BaseActivity(R.layout.activity_base_share), SelectRoomsListener { @@ -36,7 +36,7 @@ abstract class BaseShareActivity : BaseActivity(R.layout.activity_base_share), S setupViews() setupObservers() } ?: run { - startActivity(Intent(this, MainActivity::class.java)) + startActivity(packageManager.getLaunchIntentForPackage(CirclesAppConfig.appId)) finish() } } diff --git a/app/src/main/java/org/futo/circles/feature/share/BaseShareViewModel.kt b/core/src/main/java/org/futo/circles/core/share/BaseShareViewModel.kt similarity index 88% rename from app/src/main/java/org/futo/circles/feature/share/BaseShareViewModel.kt rename to core/src/main/java/org/futo/circles/core/share/BaseShareViewModel.kt index 6b69d19d1..54ada5ad1 100644 --- a/app/src/main/java/org/futo/circles/feature/share/BaseShareViewModel.kt +++ b/core/src/main/java/org/futo/circles/core/share/BaseShareViewModel.kt @@ -1,4 +1,4 @@ -package org.futo.circles.feature.share +package org.futo.circles.core.share import android.net.Uri import androidx.lifecycle.ViewModel @@ -6,7 +6,7 @@ import org.futo.circles.core.SingleEventLiveData import org.futo.circles.core.extensions.Response import org.futo.circles.core.extensions.launchBg import org.futo.circles.core.picker.MediaType -import org.futo.circles.core.timeline.SendMessageDataSource +import org.futo.circles.core.timeline.post.SendMessageDataSource class BaseShareViewModel( private val sendMessageDataSource: SendMessageDataSource diff --git a/app/src/main/java/org/futo/circles/feature/share/ShareProvider.kt b/core/src/main/java/org/futo/circles/core/share/ShareProvider.kt similarity index 82% rename from app/src/main/java/org/futo/circles/feature/share/ShareProvider.kt rename to core/src/main/java/org/futo/circles/core/share/ShareProvider.kt index d5f170f15..dcfe7eca0 100644 --- a/app/src/main/java/org/futo/circles/feature/share/ShareProvider.kt +++ b/core/src/main/java/org/futo/circles/core/share/ShareProvider.kt @@ -1,8 +1,11 @@ -package org.futo.circles.feature.share +package org.futo.circles.core.share import android.content.Context import android.content.Intent -import org.futo.circles.R +import org.futo.circles.core.R +import org.futo.circles.core.model.MediaShareable +import org.futo.circles.core.model.ShareableContent +import org.futo.circles.core.model.TextShareable object ShareProvider { diff --git a/app/src/main/java/org/futo/circles/feature/timeline/post/PostOptionsDataSource.kt b/core/src/main/java/org/futo/circles/core/timeline/post/PostOptionsDataSource.kt similarity index 92% rename from app/src/main/java/org/futo/circles/feature/timeline/post/PostOptionsDataSource.kt rename to core/src/main/java/org/futo/circles/core/timeline/post/PostOptionsDataSource.kt index 77d71f620..3c73bc1d2 100644 --- a/app/src/main/java/org/futo/circles/feature/timeline/post/PostOptionsDataSource.kt +++ b/core/src/main/java/org/futo/circles/core/timeline/post/PostOptionsDataSource.kt @@ -1,18 +1,18 @@ -package org.futo.circles.feature.timeline.post +package org.futo.circles.core.timeline.post import android.content.Context import org.futo.circles.core.extensions.createResult import org.futo.circles.core.extensions.onBG +import org.futo.circles.core.model.MediaContent import org.futo.circles.core.model.MediaFileData +import org.futo.circles.core.model.MediaShareable +import org.futo.circles.core.model.PostContent +import org.futo.circles.core.model.ShareableContent +import org.futo.circles.core.model.TextContent +import org.futo.circles.core.model.TextShareable import org.futo.circles.core.provider.MatrixSessionProvider import org.futo.circles.core.utils.FileUtils.downloadEncryptedFileToContentUri import org.futo.circles.core.utils.FileUtils.saveMediaFileToDevice -import org.futo.circles.feature.share.MediaShareable -import org.futo.circles.feature.share.ShareableContent -import org.futo.circles.feature.share.TextShareable -import org.futo.circles.core.model.MediaContent -import org.futo.circles.core.model.PostContent -import org.futo.circles.core.model.TextContent import org.matrix.android.sdk.api.session.getRoom import org.matrix.android.sdk.api.session.room.getTimelineEvent diff --git a/core/src/main/java/org/futo/circles/core/timeline/SendMessageDataSource.kt b/core/src/main/java/org/futo/circles/core/timeline/post/SendMessageDataSource.kt similarity index 99% rename from core/src/main/java/org/futo/circles/core/timeline/SendMessageDataSource.kt rename to core/src/main/java/org/futo/circles/core/timeline/post/SendMessageDataSource.kt index 56b24712d..5e4379ca5 100644 --- a/core/src/main/java/org/futo/circles/core/timeline/SendMessageDataSource.kt +++ b/core/src/main/java/org/futo/circles/core/timeline/post/SendMessageDataSource.kt @@ -1,4 +1,4 @@ -package org.futo.circles.core.timeline +package org.futo.circles.core.timeline.post import android.content.Context import android.net.Uri diff --git a/app/src/main/res/layout/activity_base_share.xml b/core/src/main/res/layout/activity_base_share.xml similarity index 95% rename from app/src/main/res/layout/activity_base_share.xml rename to core/src/main/res/layout/activity_base_share.xml index 84b0a1e15..6579cf21a 100644 --- a/app/src/main/res/layout/activity_base_share.xml +++ b/core/src/main/res/layout/activity_base_share.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" android:id="@+id/mainContainer" android:layout_width="match_parent" android:layout_height="match_parent"> @@ -13,7 +14,7 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" - app:title="@string/upload_to_gallery" + tools:title="upload to gallery" app:titleCentered="true" app:titleMarginEnd="72dp"> diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index dab48e7c7..76eed11d1 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -34,4 +34,5 @@ <string name="suggestions">Suggestions</string> <string name="no_results">No results</string> <string name="enter_name_or_id">Enter name or userId</string> + <string name="share">Share</string> </resources> \ No newline at end of file diff --git a/gallery/src/main/java/org/futo/circles/gallery/feature/backup/MediaBackupDataSource.kt b/gallery/src/main/java/org/futo/circles/gallery/feature/backup/MediaBackupDataSource.kt index 51154fb87..59bfff247 100644 --- a/gallery/src/main/java/org/futo/circles/gallery/feature/backup/MediaBackupDataSource.kt +++ b/gallery/src/main/java/org/futo/circles/gallery/feature/backup/MediaBackupDataSource.kt @@ -6,7 +6,7 @@ import android.provider.MediaStore import org.futo.circles.core.model.Gallery import org.futo.circles.core.picker.MediaType import org.futo.circles.core.room.CreateRoomDataSource -import org.futo.circles.core.timeline.SendMessageDataSource +import org.futo.circles.core.timeline.post.SendMessageDataSource import org.futo.circles.core.utils.getJoinedRoomIdByTag import org.futo.circles.gallery.model.MediaFolderListItem import org.futo.circles.gallery.model.MediaToBackupItem diff --git a/gallery/src/main/java/org/futo/circles/gallery/feature/gallery/GalleryViewModel.kt b/gallery/src/main/java/org/futo/circles/gallery/feature/gallery/GalleryViewModel.kt index 56922ec43..b32d08add 100644 --- a/gallery/src/main/java/org/futo/circles/gallery/feature/gallery/GalleryViewModel.kt +++ b/gallery/src/main/java/org/futo/circles/gallery/feature/gallery/GalleryViewModel.kt @@ -13,7 +13,7 @@ import org.futo.circles.core.model.PostContentType import org.futo.circles.core.picker.MediaType import org.futo.circles.core.room.leave.LeaveRoomDataSource import org.futo.circles.core.timeline.BaseTimelineViewModel -import org.futo.circles.core.timeline.SendMessageDataSource +import org.futo.circles.core.timeline.post.SendMessageDataSource import org.futo.circles.core.timeline.TimelineDataSource import org.futo.circles.core.utils.FileUtils.downloadEncryptedFileToContentUri import org.futo.circles.gallery.feature.pick.PickGalleryMediaListener diff --git a/gallery/src/main/java/org/futo/circles/gallery/feature/gallery/list/GalleryItemViewHolder.kt b/gallery/src/main/java/org/futo/circles/gallery/feature/gallery/list/GalleryItemViewHolder.kt index 63b30e11d..ce19eb91b 100644 --- a/gallery/src/main/java/org/futo/circles/gallery/feature/gallery/list/GalleryItemViewHolder.kt +++ b/gallery/src/main/java/org/futo/circles/gallery/feature/gallery/list/GalleryItemViewHolder.kt @@ -3,6 +3,7 @@ package org.futo.circles.gallery.feature.gallery.list import android.view.ViewGroup import androidx.core.view.updateLayoutParams import androidx.recyclerview.widget.RecyclerView +import org.futo.circles.core.extensions.loadEncryptedIntoWithAspect import org.futo.circles.core.extensions.onClick import org.futo.circles.core.extensions.setIsVisible import org.futo.circles.core.list.ViewBindingHolder diff --git a/gallery/src/main/java/org/futo/circles/gallery/feature/preview/MediaPreviewDialogFragment.kt b/gallery/src/main/java/org/futo/circles/gallery/feature/preview/MediaPreviewDialogFragment.kt index 065b58265..9ed719a09 100644 --- a/gallery/src/main/java/org/futo/circles/gallery/feature/preview/MediaPreviewDialogFragment.kt +++ b/gallery/src/main/java/org/futo/circles/gallery/feature/preview/MediaPreviewDialogFragment.kt @@ -15,6 +15,7 @@ import com.google.android.exoplayer2.ExoPlayer import com.google.android.exoplayer2.MediaItem import com.google.android.exoplayer2.Player import org.futo.circles.core.extensions.gone +import org.futo.circles.core.extensions.loadEncryptedIntoWithAspect import org.futo.circles.core.extensions.observeData import org.futo.circles.core.extensions.onBackPressed import org.futo.circles.core.extensions.setIsVisible @@ -22,12 +23,11 @@ import org.futo.circles.core.extensions.showSuccess import org.futo.circles.core.extensions.visible import org.futo.circles.core.extensions.withConfirmation import org.futo.circles.core.fragment.BaseFullscreenDialogFragment -import org.futo.circles.extensions.* +import org.futo.circles.core.share.ShareProvider import org.futo.circles.feature.photos.preview.MediaPreviewDialogFragmentArgs -import org.futo.circles.feature.share.ShareProvider import org.futo.circles.gallery.R import org.futo.circles.gallery.databinding.DialogFragmentMediaPreviewBinding -import org.futo.circles.model.ConfirmationType +import org.futo.circles.gallery.model.RemoveImage import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.core.parameter.parametersOf @@ -118,7 +118,7 @@ class MediaPreviewDialogFragment : } R.id.delete -> { - withConfirmation(ConfirmationType.REMOVE_IMAGE) { + withConfirmation(RemoveImage()) { viewModel.removeImage() onBackPressed() } diff --git a/gallery/src/main/java/org/futo/circles/gallery/feature/preview/MediaPreviewViewModel.kt b/gallery/src/main/java/org/futo/circles/gallery/feature/preview/MediaPreviewViewModel.kt index fdd001721..c4855f347 100644 --- a/gallery/src/main/java/org/futo/circles/gallery/feature/preview/MediaPreviewViewModel.kt +++ b/gallery/src/main/java/org/futo/circles/gallery/feature/preview/MediaPreviewViewModel.kt @@ -8,9 +8,9 @@ import org.futo.circles.core.SingleEventLiveData import org.futo.circles.core.extensions.launchBg import org.futo.circles.core.model.MediaContent import org.futo.circles.core.model.PostContentType +import org.futo.circles.core.model.ShareableContent +import org.futo.circles.core.timeline.post.PostOptionsDataSource import org.futo.circles.core.utils.FileUtils -import org.futo.circles.feature.share.ShareableContent -import org.futo.circles.feature.timeline.post.PostOptionsDataSource class MediaPreviewViewModel( private val roomId: String, diff --git a/gallery/src/main/java/org/futo/circles/gallery/feature/save/SavePostToGalleryDataSource.kt b/gallery/src/main/java/org/futo/circles/gallery/feature/save/SavePostToGalleryDataSource.kt index f14f83df4..8ca17c3f1 100644 --- a/gallery/src/main/java/org/futo/circles/gallery/feature/save/SavePostToGalleryDataSource.kt +++ b/gallery/src/main/java/org/futo/circles/gallery/feature/save/SavePostToGalleryDataSource.kt @@ -4,9 +4,9 @@ import android.content.Context import org.futo.circles.core.extensions.onBG import org.futo.circles.core.model.MediaContent import org.futo.circles.core.model.PostContent -import org.futo.circles.core.timeline.SendMessageDataSource +import org.futo.circles.core.model.SelectableRoomListItem +import org.futo.circles.core.timeline.post.SendMessageDataSource import org.futo.circles.core.utils.FileUtils -import org.futo.circles.gallery.model.SelectableRoomListItem class SavePostToGalleryDataSource( private val context: Context, diff --git a/gallery/src/main/java/org/futo/circles/gallery/feature/save/SavePostToGalleryViewModel.kt b/gallery/src/main/java/org/futo/circles/gallery/feature/save/SavePostToGalleryViewModel.kt index 4d034a168..5a486fa9d 100644 --- a/gallery/src/main/java/org/futo/circles/gallery/feature/save/SavePostToGalleryViewModel.kt +++ b/gallery/src/main/java/org/futo/circles/gallery/feature/save/SavePostToGalleryViewModel.kt @@ -4,8 +4,8 @@ import androidx.lifecycle.ViewModel import org.futo.circles.core.SingleEventLiveData import org.futo.circles.core.extensions.Response import org.futo.circles.core.extensions.launchBg +import org.futo.circles.core.model.SelectableRoomListItem import org.futo.circles.gallery.feature.preview.MediaPreviewDataSource -import org.futo.circles.gallery.model.SelectableRoomListItem class SavePostToGalleryViewModel( private val mediaPreviewDataSource: MediaPreviewDataSource, diff --git a/gallery/src/main/java/org/futo/circles/gallery/feature/save/SavePostToGalleyDialogFragment.kt b/gallery/src/main/java/org/futo/circles/gallery/feature/save/SavePostToGalleyDialogFragment.kt index 43a13c822..677e1df62 100644 --- a/gallery/src/main/java/org/futo/circles/gallery/feature/save/SavePostToGalleyDialogFragment.kt +++ b/gallery/src/main/java/org/futo/circles/gallery/feature/save/SavePostToGalleyDialogFragment.kt @@ -4,16 +4,16 @@ import android.os.Bundle import android.view.View import androidx.fragment.app.Fragment import androidx.navigation.fragment.navArgs -import org.futo.circles.core.SelectRoomsListener import org.futo.circles.core.extensions.observeResponse import org.futo.circles.core.extensions.onBackPressed import org.futo.circles.core.extensions.showSuccess import org.futo.circles.core.fragment.BaseFullscreenDialogFragment import org.futo.circles.core.fragment.HasLoadingState -import org.futo.circles.feature.photos.select.SelectGalleriesFragment +import org.futo.circles.core.model.SelectableRoomListItem +import org.futo.circles.core.room.select.SelectRoomsListener +import org.futo.circles.gallery.feature.select.SelectGalleriesFragment import org.futo.circles.gallery.R import org.futo.circles.gallery.databinding.DialogFragmentSavePostToGalleryBinding -import org.futo.circles.gallery.model.SelectableRoomListItem import org.koin.androidx.viewmodel.ext.android.viewModel import org.koin.core.parameter.parametersOf diff --git a/gallery/src/main/java/org/futo/circles/gallery/feature/select/SelectGalleriesDataSource.kt b/gallery/src/main/java/org/futo/circles/gallery/feature/select/SelectGalleriesDataSource.kt index fd7a0f50b..567bd2b71 100644 --- a/gallery/src/main/java/org/futo/circles/gallery/feature/select/SelectGalleriesDataSource.kt +++ b/gallery/src/main/java/org/futo/circles/gallery/feature/select/SelectGalleriesDataSource.kt @@ -1,10 +1,10 @@ package org.futo.circles.gallery.feature.select import androidx.lifecycle.MutableLiveData +import org.futo.circles.core.mapping.toSelectableRoomListItem import org.futo.circles.core.model.GALLERY_TYPE +import org.futo.circles.core.model.SelectableRoomListItem import org.futo.circles.core.provider.MatrixSessionProvider -import org.futo.circles.gallery.model.SelectableRoomListItem -import org.futo.circles.mapping.toSelectableRoomListItem import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams diff --git a/gallery/src/main/java/org/futo/circles/gallery/feature/select/SelectGalleriesFragment.kt b/gallery/src/main/java/org/futo/circles/gallery/feature/select/SelectGalleriesFragment.kt index a626d1126..8d3038449 100644 --- a/gallery/src/main/java/org/futo/circles/gallery/feature/select/SelectGalleriesFragment.kt +++ b/gallery/src/main/java/org/futo/circles/gallery/feature/select/SelectGalleriesFragment.kt @@ -1,24 +1,18 @@ -package org.futo.circles.feature.photos.select +package org.futo.circles.gallery.feature.select import android.content.Context import android.os.Bundle import android.view.View import androidx.fragment.app.Fragment import by.kirich1409.viewbindingdelegate.viewBinding -import org.futo.circles.core.SelectRoomsListener import org.futo.circles.core.extensions.observeData -import org.futo.circles.databinding.FragmentSelectGalleriesBinding +import org.futo.circles.core.model.SelectableRoomListItem +import org.futo.circles.core.room.select.SelectRoomsListener import org.futo.circles.gallery.R -import org.futo.circles.gallery.feature.select.SelectGalleriesViewModel +import org.futo.circles.gallery.databinding.FragmentSelectGalleriesBinding import org.futo.circles.gallery.feature.select.list.SelectGalleryAdapter -import org.futo.circles.gallery.model.SelectableRoomListItem import org.koin.androidx.viewmodel.ext.android.viewModel -interface RoomsPicker { - var selectRoomsListener: SelectRoomsListener? - fun getSelectedRooms(): List<SelectableRoomListItem> -} - class SelectGalleriesFragment : Fragment(R.layout.fragment_select_galleries), RoomsPicker { private val viewModel by viewModel<SelectGalleriesViewModel>() diff --git a/gallery/src/main/java/org/futo/circles/gallery/feature/select/SelectGalleriesViewModel.kt b/gallery/src/main/java/org/futo/circles/gallery/feature/select/SelectGalleriesViewModel.kt index d99bc3bac..f5b408963 100644 --- a/gallery/src/main/java/org/futo/circles/gallery/feature/select/SelectGalleriesViewModel.kt +++ b/gallery/src/main/java/org/futo/circles/gallery/feature/select/SelectGalleriesViewModel.kt @@ -1,7 +1,7 @@ package org.futo.circles.gallery.feature.select import androidx.lifecycle.ViewModel -import org.futo.circles.gallery.model.SelectableRoomListItem +import org.futo.circles.core.model.SelectableRoomListItem class SelectGalleriesViewModel( private val selectGalleriesDataSource: SelectGalleriesDataSource diff --git a/gallery/src/main/java/org/futo/circles/gallery/feature/select/list/SelectGalleryAdapter.kt b/gallery/src/main/java/org/futo/circles/gallery/feature/select/list/SelectGalleryAdapter.kt index 14d5aada0..9440b40d7 100644 --- a/gallery/src/main/java/org/futo/circles/gallery/feature/select/list/SelectGalleryAdapter.kt +++ b/gallery/src/main/java/org/futo/circles/gallery/feature/select/list/SelectGalleryAdapter.kt @@ -2,7 +2,7 @@ package org.futo.circles.gallery.feature.select.list import android.view.ViewGroup import org.futo.circles.core.list.BaseRvAdapter -import org.futo.circles.gallery.model.SelectableRoomListItem +import org.futo.circles.core.model.SelectableRoomListItem class SelectGalleryAdapter( private val onGalleryClicked: (SelectableRoomListItem) -> Unit, diff --git a/gallery/src/main/java/org/futo/circles/gallery/feature/select/list/SelectGalleryViewHolder.kt b/gallery/src/main/java/org/futo/circles/gallery/feature/select/list/SelectGalleryViewHolder.kt index b979265a2..ca27f7b0e 100644 --- a/gallery/src/main/java/org/futo/circles/gallery/feature/select/list/SelectGalleryViewHolder.kt +++ b/gallery/src/main/java/org/futo/circles/gallery/feature/select/list/SelectGalleryViewHolder.kt @@ -3,9 +3,11 @@ package org.futo.circles.gallery.feature.select.list import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import org.futo.circles.core.extensions.onClick +import org.futo.circles.core.extensions.setIsVisible import org.futo.circles.core.list.ViewBindingHolder -import org.futo.circles.databinding.ListItemSelectGalleryBinding -import org.futo.circles.gallery.model.SelectableRoomListItem +import org.futo.circles.core.model.SelectableRoomListItem +import org.futo.circles.gallery.R +import org.futo.circles.gallery.databinding.ListItemSelectGalleryBinding class SelectGalleryViewHolder( parent: ViewGroup, diff --git a/app/src/main/java/org/futo/circles/feature/share/gallery/UploadToGalleryActivity.kt b/gallery/src/main/java/org/futo/circles/gallery/feature/share/UploadToGalleryActivity.kt similarity index 52% rename from app/src/main/java/org/futo/circles/feature/share/gallery/UploadToGalleryActivity.kt rename to gallery/src/main/java/org/futo/circles/gallery/feature/share/UploadToGalleryActivity.kt index 657e10e82..78afa3039 100644 --- a/app/src/main/java/org/futo/circles/feature/share/gallery/UploadToGalleryActivity.kt +++ b/gallery/src/main/java/org/futo/circles/gallery/feature/share/UploadToGalleryActivity.kt @@ -1,9 +1,9 @@ -package org.futo.circles.feature.share.gallery +package org.futo.circles.gallery.feature.share -import org.futo.circles.R -import org.futo.circles.feature.photos.select.RoomsPicker -import org.futo.circles.feature.photos.select.SelectGalleriesFragment -import org.futo.circles.feature.share.BaseShareActivity +import org.futo.circles.core.share.BaseShareActivity +import org.futo.circles.gallery.R +import org.futo.circles.gallery.feature.select.RoomsPicker +import org.futo.circles.gallery.feature.select.SelectGalleriesFragment class UploadToGalleryActivity : BaseShareActivity() { diff --git a/gallery/src/main/java/org/futo/circles/gallery/model/ConfirmationType.kt b/gallery/src/main/java/org/futo/circles/gallery/model/ConfirmationType.kt index 7cde94189..0512e3a5d 100644 --- a/gallery/src/main/java/org/futo/circles/gallery/model/ConfirmationType.kt +++ b/gallery/src/main/java/org/futo/circles/gallery/model/ConfirmationType.kt @@ -7,4 +7,10 @@ data class DeleteGallery( override val titleRes: Int = R.string.delete_gallery, override val messageRes: Int = R.string.delete_gallery_message, override val positiveButtonRes: Int = R.string.delete +) : ConfirmationType(titleRes, messageRes, positiveButtonRes) + +data class RemoveImage( + override val titleRes: Int = R.string.remove_image, + override val messageRes: Int = R.string.remove_image_message, + override val positiveButtonRes: Int = R.string.remove ) : ConfirmationType(titleRes, messageRes, positiveButtonRes) \ No newline at end of file diff --git a/gallery/src/main/java/org/futo/circles/gallery/model/SelectableRoomListItem.kt b/gallery/src/main/java/org/futo/circles/gallery/model/SelectableRoomListItem.kt deleted file mode 100644 index b732a9235..000000000 --- a/gallery/src/main/java/org/futo/circles/gallery/model/SelectableRoomListItem.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.futo.circles.gallery.model - -import org.futo.circles.core.list.IdEntity -import org.futo.circles.core.model.RoomInfo - -data class SelectableRoomListItem( - override val id: String, - val info: RoomInfo, - val isSelected: Boolean -) : IdEntity<String> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_select_galleries.xml b/gallery/src/main/res/layout/fragment_select_galleries.xml similarity index 100% rename from app/src/main/res/layout/fragment_select_galleries.xml rename to gallery/src/main/res/layout/fragment_select_galleries.xml diff --git a/app/src/main/res/layout/list_item_select_gallery.xml b/gallery/src/main/res/layout/list_item_select_gallery.xml similarity index 100% rename from app/src/main/res/layout/list_item_select_gallery.xml rename to gallery/src/main/res/layout/list_item_select_gallery.xml diff --git a/gallery/src/main/res/values/strings.xml b/gallery/src/main/res/values/strings.xml index 3c442e19e..cfe707fb5 100644 --- a/gallery/src/main/res/values/strings.xml +++ b/gallery/src/main/res/values/strings.xml @@ -1,4 +1,14 @@ <?xml version="1.0" encoding="utf-8"?> <resources> <string name="gallery_updated">Gallery updated</string> + <string name="saved">Saved</string> + <string name="choose_gallery">Choose gallery</string> + <string name="pick_media">Pick media</string> + <string name="delete_gallery">Delete gallery</string> + <string name="delete_gallery_message">Are you sure you want to remove this gallery?</string> + <string name="delete">Delete</string> + <string name="remove_image">Remove image</string> + <string name="remove_image_message">Are you sure you want to remove this image?</string> + <string name="remove">Remove</string> + <string name="upload_to_gallery">Upload to gallery</string> </resources> \ No newline at end of file -- GitLab