From 9a9cb3d1fc1a6ebaaa808cc7f4990983bfd47df6 Mon Sep 17 00:00:00 2001 From: Artem Umerov Date: Mon, 20 Mar 2023 15:29:02 +0300 Subject: [PATCH] 16 16 --- app_fenrir/build.gradle | 1 + app_fenrir/src/main/AndroidManifest.xml | 8 + .../kotlin/dev/ragnarok/fenrir/Constants.kt | 4 +- .../main/kotlin/dev/ragnarok/fenrir/Extra.kt | 1 + .../kotlin/dev/ragnarok/fenrir/Includes.kt | 2 +- .../ragnarok/fenrir/activity/ChatActivity.kt | 6 + .../fenrir/activity/ChatActivityBubbles.kt | 6 + .../activity/LocalJsonToChatActivity.kt | 6 + .../ragnarok/fenrir/activity/LoginActivity.kt | 4 + .../ragnarok/fenrir/activity/MainActivity.kt | 74 ++- .../activity/NotReadMessagesActivity.kt | 6 + .../fenrir/activity/SinglePhotoActivity.kt | 3 +- .../fenrir/activity/ValidateActivity.kt | 4 + .../fenrir/activity/crash/CrashUtils.kt | 3 +- .../activity/photopager/PhotoPagerActivity.kt | 3 +- .../fenrir/activity/qr/CameraScanActivity.kt | 3 +- .../fenrir/activity/qr/CustomQRCodeWriter.kt | 2 +- .../selectprofiles/SelectedProfilesAdapter.kt | 3 +- .../shortvideopager/IShortVideoPagerView.kt | 33 + .../ShortVideoPagerActivity.kt | 589 ++++++++++++++++++ .../ShortVideoPagerPresenter.kt | 393 ++++++++++++ .../activity/storypager/StoryPagerActivity.kt | 4 +- .../ragnarok/fenrir/api/CaptchaProvider.kt | 2 +- .../dev/ragnarok/fenrir/api/VKRestProvider.kt | 2 +- .../ragnarok/fenrir/api/ValidateProvider.kt | 5 +- .../api/adapters/CommunityDtoAdapter.kt | 2 +- .../api/adapters/LongpollUpdateAdapter.kt | 2 +- .../fenrir/api/adapters/ViewersListAdapter.kt | 5 +- .../dev/ragnarok/fenrir/api/impl/AbsApi.kt | 4 +- .../dev/ragnarok/fenrir/api/impl/LikesApi.kt | 17 - .../fenrir/api/impl/StoriesShortVideosApi.kt | 154 +++++ .../dev/ragnarok/fenrir/api/impl/UploadApi.kt | 3 +- .../dev/ragnarok/fenrir/api/impl/UsersApi.kt | 77 --- .../dev/ragnarok/fenrir/api/impl/VKApies.kt | 6 + .../fenrir/api/interfaces/IAccountApis.kt | 1 + .../fenrir/api/interfaces/ILikesApi.kt | 9 - .../api/interfaces/IStoriesShortVideosApi.kt | 72 +++ .../fenrir/api/interfaces/IUploadApi.kt | 3 +- .../fenrir/api/interfaces/IUsersApi.kt | 37 -- .../fenrir/api/model/VKApiCommunity.kt | 1 + .../ragnarok/fenrir/api/model/VKApiUser.kt | 1 + .../api/model/response/CustomResponse.kt | 12 + .../api/model/response/ShortVideosResponse.kt | 20 + .../api/model/response/ViewersListResponse.kt | 2 +- .../fenrir/api/services/ILikesService.kt | 21 - .../services/IStoriesShortVideosService.kt | 178 ++++++ .../fenrir/api/services/IUploadService.kt | 9 +- .../fenrir/api/services/IUsersService.kt | 89 --- .../fenrir/crypt/KeyExchangeService.kt | 4 +- .../kotlin/dev/ragnarok/fenrir/db/DBHelper.kt | 57 +- .../db/model/entity/CommunityDetailsEntity.kt | 7 + .../db/model/entity/UserDetailsEntity.kt | 7 + .../feedbacklink/FeedbackLinkAdapter.kt | 3 +- .../dialog/feedbacklink/FeedbackLinkDialog.kt | 3 +- .../dialog/privacyview/PrivacyAdapter.kt | 3 +- .../dialog/selectchairs/SelectChairsDialog.kt | 3 +- .../dialog/selectcity/SelectCityDialog.kt | 3 +- .../selectfaculty/SelectFacultyDialog.kt | 3 +- .../SelectSchoolClassesDialog.kt | 3 +- .../selectschools/SelectSchoolsDialog.kt | 3 +- .../SelectUniversityDialog.kt | 3 +- .../fenrir/domain/ILikesInteractor.kt | 8 - .../fenrir/domain/IOwnersRepository.kt | 12 - .../domain/IStoriesShortVideosInteractor.kt | 37 ++ .../fenrir/domain/InteractorFactory.kt | 6 +- .../fenrir/domain/impl/FeedInteractor.kt | 2 +- .../fenrir/domain/impl/LikesInteractor.kt | 25 - .../fenrir/domain/impl/MessagesRepository.kt | 2 +- .../fenrir/domain/impl/OwnersRepository.kt | 141 ----- .../impl/StoriesShortVideosInteractor.kt | 223 +++++++ .../fenrir/domain/mappers/Dto2Entity.kt | 2 + .../fenrir/domain/mappers/Entity2Model.kt | 2 + .../fenrir/fragment/BrowserFragment.kt | 4 + .../fragment/abswall/AbsWallFragment.kt | 184 +++++- .../fragment/abswall/AbsWallPresenter.kt | 277 +++++++- .../fenrir/fragment/abswall/IWallView.kt | 13 + .../fragment/accounts/AccountsFragment.kt | 3 +- .../AbsAttachmentsEditFragment.kt | 2 +- .../commentcreate/CommentCreatePresenter.kt | 2 +- .../commentedit/CommentEditPresenter.kt | 2 +- .../postcreate/PostCreatePresenter.kt | 2 +- .../attachments/postedit/PostEditPresenter.kt | 2 +- .../local/audioslocal/AudiosLocalPresenter.kt | 2 +- .../fragment/base/AttachmentsViewBinder.kt | 3 +- .../fragment/comments/CommentsPresenter.kt | 16 +- .../fenrir/fragment/docs/DocsAdapter.kt | 3 +- .../fragment/docs/DocsAsImagesAdapter.kt | 3 +- .../fenrir/fragment/docs/DocsListPresenter.kt | 2 +- .../fragment/feedback/FeedbackAdapter.kt | 3 +- .../FileManagerSelectFragment.kt | 3 +- .../FriendsByPhonesPresenter.kt | 2 +- .../fragment/groupchats/GroupChatsAdapter.kt | 3 +- .../fragment/groupwall/GroupWallFragment.kt | 11 +- .../fragment/groupwall/GroupWallPresenter.kt | 8 +- .../fragment/groupwall/IGroupWallView.kt | 3 +- .../fenrir/fragment/likes/LikesFragment.kt | 6 +- .../fragment/likes/LikesListPresenter.kt | 49 +- .../likes/storiesview/IStoriesViewView.kt | 16 + .../likes/storiesview/StoriesViewAdapter.kt | 180 ++++++ .../likes/storiesview/StoriesViewFragment.kt | 160 +++++ .../likes/storiesview/StoriesViewPresenter.kt | 118 ++++ .../FileManagerRemoteFragment.kt | 3 +- .../fenrir/fragment/logs/LogsAdapter.kt | 3 +- .../fragment/messages/chat/ChatFragment.kt | 9 +- .../fragment/messages/chat/ChatPresenter.kt | 18 +- .../messages/dialogs/DialogsAdapter.kt | 4 +- .../narratives/NarrativesPresenter.kt | 11 +- .../requestexecute/RequestExecutePresenter.kt | 2 +- .../dialogssearch/DialogPreviewAdapter.kt | 3 +- .../search/filteredit/FilterEditFragment.kt | 6 +- .../sheet/AttachmentsBottomSheetAdapter.kt | 3 +- .../sheet/MessageAttachmentsPresenter.kt | 2 +- .../fenrir/fragment/topics/TopicsAdapter.kt | 3 +- .../fenrir/fragment/userwall/IUserWallView.kt | 7 +- .../fragment/userwall/UserWallFragment.kt | 80 +-- .../fragment/userwall/UserWallPresenter.kt | 150 +---- .../fragment/videos/VideosListPresenter.kt | 2 +- .../fragment/vkphotos/VKPhotosPresenter.kt | 2 +- .../walllinksattachments/LinksAdapter.kt | 3 +- .../WallPostQueryAttachmentsPresenter.kt | 2 +- .../dev/ragnarok/fenrir/link/LinkParser.kt | 3 +- .../dev/ragnarok/fenrir/link/VKLinkParser.kt | 2 +- .../media/music/MusicPlaybackController.kt | 2 +- .../media/music/MusicPlaybackService.kt | 14 +- .../ragnarok/fenrir/model/AttachmentEntry.kt | 4 +- .../ragnarok/fenrir/model/CommunityDetails.kt | 28 +- .../ragnarok/fenrir/model/EditedMessage.kt | 6 +- .../dev/ragnarok/fenrir/model/LocalVideo.kt | 4 +- .../dev/ragnarok/fenrir/model/Privacy.kt | 2 +- .../dev/ragnarok/fenrir/model/UserDetails.kt | 20 +- .../kotlin/dev/ragnarok/fenrir/model/Video.kt | 11 + .../catalog_v2_audio/CatalogV2ArtistItem.kt | 3 +- .../kotlin/dev/ragnarok/fenrir/place/Place.kt | 2 + .../dev/ragnarok/fenrir/place/PlaceFactory.kt | 16 + .../realtime/RealtimeMessagesProcessor.kt | 2 +- .../fenrir/service/ChatDownloadWorker.kt | 2 +- .../ragnarok/fenrir/service/FaveSyncWorker.kt | 1 - .../fenrir/settings/AccountsSettings.kt | 2 +- .../ragnarok/fenrir/settings/OtherSettings.kt | 2 +- .../ragnarok/fenrir/upload/IUploadManager.kt | 3 +- .../dev/ragnarok/fenrir/upload/Upload.kt | 4 +- .../fenrir/upload/UploadDestination.kt | 57 +- .../fenrir/upload/UploadManagerImpl.kt | 18 +- .../fenrir/upload/impl/StoryUploadable.kt | 12 +- .../ragnarok/fenrir/util/DownloadWorkUtils.kt | 3 +- .../dev/ragnarok/fenrir/util/FileUtil.kt | 11 +- .../dev/ragnarok/fenrir/util/HelperSimple.kt | 1 + .../fenrir/util/OkHttp3LoggingInterceptor.kt | 2 +- .../kotlin/dev/ragnarok/fenrir/util/Utils.kt | 32 +- .../fenrir/util/existfile/FileExistJVM.kt | 3 +- .../fenrir/util/existfile/FileExistNative.kt | 2 +- .../fenrir/util/refresh/TokenModKate.kt | 4 +- .../fenrir/util/refresh/TokenModOfficialVK.kt | 6 +- .../dev/ragnarok/fenrir/view/CustomSeekBar.kt | 24 +- .../ragnarok/fenrir/view/PhotosViewHelper.kt | 3 +- .../fenrir/view/snowfall/Randomizer.kt | 32 +- .../fenrir/view/snowfall/Snowflake.kt | 6 +- .../view/steppers/base/BaseHolderListener.kt | 4 +- .../fenrir/view/zoomhelper/PlaceHolderView.kt | 2 +- .../src/main/res/drawable/clip_outline.xml | 25 + .../src/main/res/drawable/story_outline.xml | 13 + .../res/layout/activity_shortvideo_pager.xml | 133 ++++ ...ory_pager.xml => activity_story_pager.xml} | 0 .../res/layout/content_shortvideo_page.xml | 22 + .../src/main/res/layout/fragment_wall.xml | 14 + .../src/main/res/layout/header_group.xml | 27 + .../main/res/layout/header_user_profile.xml | 26 + .../main/res/layout/item_group_with_like.xml | 93 +++ .../main/res/layout/item_people_with_like.xml | 97 +++ app_fenrir/src/main/res/values-be/strings.xml | 4 + app_fenrir/src/main/res/values-ru/strings.xml | 4 + app_fenrir/src/main/res/values/strings.xml | 4 + app_filegallery/build.gradle | 1 + .../dev/ragnarok/filegallery/Constants.kt | 2 +- .../filegallery/activity/crash/CrashUtils.kt | 3 +- .../activity/photopager/PhotoPagerActivity.kt | 3 +- .../photopager/PhotoPagerPresenter.kt | 4 +- .../activity/qr/CameraScanActivity.kt | 3 +- .../db/impl/SearchRequestHelperStorage.kt | 3 +- .../filemanager/FileManagerFragment.kt | 3 +- .../FileManagerSelectFragment.kt | 3 +- .../FileManagerRemoteFragment.kt | 3 +- .../media/music/MusicPlaybackController.kt | 10 +- .../media/music/MusicPlaybackService.kt | 14 +- .../filegallery/upload/IUploadManager.kt | 2 +- .../dev/ragnarok/filegallery/upload/Upload.kt | 4 +- .../filegallery/upload/UploadManagerImpl.kt | 2 +- .../filegallery/util/DownloadWorkUtils.kt | 4 +- .../util/OkHttp3LoggingInterceptor.kt | 2 +- .../dev/ragnarok/filegallery/util/Utils.kt | 2 +- .../filegallery/view/CustomSeekBar.kt | 24 +- .../filegallery/view/VideoControllerView.kt | 2 +- build.gradle | 30 +- camera2/build.gradle | 4 +- .../installations/FirebaseInstallations.java | 2 +- .../com/github/luben/zstd/EndDirective.java | 2 +- .../github/luben/zstd/ZstdCompressCtx.java | 114 ++-- .../github/luben/zstd/ZstdDecompressCtx.java | 57 +- ...ectBufferCompressingStreamNoFinalizer.java | 4 +- .../zstd/ZstdOutputStreamNoFinalizer.java | 20 +- .../libyuv/include/libyuv/rotate_row.h | 4 - .../animation/libyuv/include/libyuv/version.h | 2 +- .../jni/animation/libyuv/source/convert.cc | 5 +- .../animation/libyuv/source/rotate_neon.cc | 40 ++ .../jni/animation/libyuv/source/row_common.cc | 25 +- .../jni/animation/libyuv/source/row_neon.cc | 86 ++- .../jni/animation/libyuv/source/row_neon64.cc | 68 +- .../main/jni/compress/zstd/jni_fast_zstd.c | 156 ++--- .../src/main/jni/compress/zstd/jni_zstd.c | 2 +- .../src/lib/sw_engine/tvgSwRasterTexmap.h | 4 +- .../module/animation/AnimatedFileFrame.kt | 5 +- material/build.gradle | 2 +- .../android/material/appbar/AppBarLayout.java | 10 +- .../material/badge/res/values-af/strings.xml | 2 +- .../material/badge/res/values-am/strings.xml | 2 +- .../material/badge/res/values-ar/strings.xml | 2 +- .../material/badge/res/values-as/strings.xml | 2 +- .../material/badge/res/values-az/strings.xml | 2 +- .../badge/res/values-b+es+419/strings.xml | 2 +- .../badge/res/values-b+sr+Latn/strings.xml | 2 +- .../material/badge/res/values-be/strings.xml | 2 +- .../material/badge/res/values-bg/strings.xml | 2 +- .../material/badge/res/values-bn/strings.xml | 2 +- .../material/badge/res/values-bs/strings.xml | 2 +- .../material/badge/res/values-ca/strings.xml | 2 +- .../material/badge/res/values-cs/strings.xml | 2 +- .../material/badge/res/values-da/strings.xml | 2 +- .../material/badge/res/values-de/strings.xml | 2 +- .../material/badge/res/values-el/strings.xml | 2 +- .../badge/res/values-en-rGB/strings.xml | 2 +- .../badge/res/values-es-rUS/strings.xml | 2 +- .../material/badge/res/values-es/strings.xml | 2 +- .../material/badge/res/values-et/strings.xml | 2 +- .../material/badge/res/values-eu/strings.xml | 2 +- .../material/badge/res/values-fa/strings.xml | 2 +- .../material/badge/res/values-fi/strings.xml | 2 +- .../badge/res/values-fr-rCA/strings.xml | 2 +- .../material/badge/res/values-fr/strings.xml | 2 +- .../material/badge/res/values-gl/strings.xml | 2 +- .../material/badge/res/values-gu/strings.xml | 2 +- .../material/badge/res/values-hi/strings.xml | 2 +- .../material/badge/res/values-hr/strings.xml | 2 +- .../material/badge/res/values-hu/strings.xml | 2 +- .../material/badge/res/values-hy/strings.xml | 2 +- .../material/badge/res/values-in/strings.xml | 2 +- .../material/badge/res/values-is/strings.xml | 2 +- .../material/badge/res/values-it/strings.xml | 2 +- .../material/badge/res/values-iw/strings.xml | 5 +- .../material/badge/res/values-ja/strings.xml | 2 +- .../material/badge/res/values-ka/strings.xml | 2 +- .../material/badge/res/values-kk/strings.xml | 2 +- .../material/badge/res/values-km/strings.xml | 2 +- .../material/badge/res/values-kn/strings.xml | 2 +- .../material/badge/res/values-ko/strings.xml | 2 +- .../material/badge/res/values-ky/strings.xml | 2 +- .../material/badge/res/values-lo/strings.xml | 2 +- .../material/badge/res/values-lt/strings.xml | 2 +- .../material/badge/res/values-lv/strings.xml | 2 +- .../material/badge/res/values-mk/strings.xml | 2 +- .../material/badge/res/values-ml/strings.xml | 2 +- .../material/badge/res/values-mn/strings.xml | 2 +- .../material/badge/res/values-mr/strings.xml | 2 +- .../material/badge/res/values-ms/strings.xml | 2 +- .../material/badge/res/values-my/strings.xml | 2 +- .../material/badge/res/values-nb/strings.xml | 2 +- .../material/badge/res/values-ne/strings.xml | 2 +- .../material/badge/res/values-nl/strings.xml | 2 +- .../material/badge/res/values-or/strings.xml | 2 +- .../material/badge/res/values-pa/strings.xml | 2 +- .../material/badge/res/values-pl/strings.xml | 2 +- .../badge/res/values-pt-rBR/strings.xml | 2 +- .../badge/res/values-pt-rPT/strings.xml | 2 +- .../material/badge/res/values-ro/strings.xml | 2 +- .../material/badge/res/values-ru/strings.xml | 2 +- .../material/badge/res/values-si/strings.xml | 2 +- .../material/badge/res/values-sk/strings.xml | 2 +- .../material/badge/res/values-sl/strings.xml | 2 +- .../material/badge/res/values-sq/strings.xml | 2 +- .../material/badge/res/values-sr/strings.xml | 2 +- .../material/badge/res/values-sv/strings.xml | 2 +- .../material/badge/res/values-sw/strings.xml | 2 +- .../material/badge/res/values-ta/strings.xml | 2 +- .../material/badge/res/values-te/strings.xml | 2 +- .../material/badge/res/values-th/strings.xml | 2 +- .../material/badge/res/values-tl/strings.xml | 2 +- .../material/badge/res/values-tr/strings.xml | 2 +- .../material/badge/res/values-uk/strings.xml | 2 +- .../material/badge/res/values-ur/strings.xml | 2 +- .../material/badge/res/values-uz/strings.xml | 2 +- .../material/badge/res/values-vi/strings.xml | 2 +- .../badge/res/values-zh-rCN/strings.xml | 2 +- .../badge/res/values-zh-rHK/strings.xml | 2 +- .../badge/res/values-zh-rTW/strings.xml | 2 +- .../material/badge/res/values-zu/strings.xml | 2 +- .../bottomsheet/BottomSheetBehavior.java | 6 +- .../bottomsheet/res/values-af/strings.xml | 2 +- .../bottomsheet/res/values-am/strings.xml | 2 +- .../bottomsheet/res/values-ar/strings.xml | 2 +- .../bottomsheet/res/values-as/strings.xml | 2 +- .../bottomsheet/res/values-az/strings.xml | 2 +- .../res/values-b+es+419/strings.xml | 2 +- .../res/values-b+sr+Latn/strings.xml | 2 +- .../bottomsheet/res/values-be/strings.xml | 2 +- .../bottomsheet/res/values-bg/strings.xml | 2 +- .../bottomsheet/res/values-bn/strings.xml | 2 +- .../bottomsheet/res/values-bs/strings.xml | 2 +- .../bottomsheet/res/values-ca/strings.xml | 2 +- .../bottomsheet/res/values-cs/strings.xml | 2 +- .../bottomsheet/res/values-da/strings.xml | 2 +- .../bottomsheet/res/values-de/strings.xml | 2 +- .../bottomsheet/res/values-el/strings.xml | 2 +- .../bottomsheet/res/values-en-rGB/strings.xml | 2 +- .../bottomsheet/res/values-es-rUS/strings.xml | 2 +- .../bottomsheet/res/values-es/strings.xml | 2 +- .../bottomsheet/res/values-et/strings.xml | 2 +- .../bottomsheet/res/values-eu/strings.xml | 2 +- .../bottomsheet/res/values-fa/strings.xml | 2 +- .../bottomsheet/res/values-fi/strings.xml | 2 +- .../bottomsheet/res/values-fr-rCA/strings.xml | 2 +- .../bottomsheet/res/values-fr/strings.xml | 2 +- .../bottomsheet/res/values-gl/strings.xml | 2 +- .../bottomsheet/res/values-gu/strings.xml | 2 +- .../bottomsheet/res/values-hi/strings.xml | 2 +- .../bottomsheet/res/values-hr/strings.xml | 2 +- .../bottomsheet/res/values-hu/strings.xml | 2 +- .../bottomsheet/res/values-hy/strings.xml | 2 +- .../bottomsheet/res/values-in/strings.xml | 2 +- .../bottomsheet/res/values-is/strings.xml | 2 +- .../bottomsheet/res/values-it/strings.xml | 2 +- .../bottomsheet/res/values-iw/strings.xml | 2 +- .../bottomsheet/res/values-ja/strings.xml | 2 +- .../bottomsheet/res/values-ka/strings.xml | 2 +- .../bottomsheet/res/values-kk/strings.xml | 2 +- .../bottomsheet/res/values-km/strings.xml | 2 +- .../bottomsheet/res/values-kn/strings.xml | 2 +- .../bottomsheet/res/values-ko/strings.xml | 2 +- .../bottomsheet/res/values-ky/strings.xml | 2 +- .../bottomsheet/res/values-lo/strings.xml | 2 +- .../bottomsheet/res/values-lt/strings.xml | 2 +- .../bottomsheet/res/values-lv/strings.xml | 2 +- .../bottomsheet/res/values-mk/strings.xml | 2 +- .../bottomsheet/res/values-ml/strings.xml | 2 +- .../bottomsheet/res/values-mn/strings.xml | 2 +- .../bottomsheet/res/values-mr/strings.xml | 2 +- .../bottomsheet/res/values-ms/strings.xml | 2 +- .../bottomsheet/res/values-my/strings.xml | 2 +- .../bottomsheet/res/values-nb/strings.xml | 2 +- .../bottomsheet/res/values-ne/strings.xml | 2 +- .../bottomsheet/res/values-nl/strings.xml | 2 +- .../bottomsheet/res/values-or/strings.xml | 2 +- .../bottomsheet/res/values-pa/strings.xml | 2 +- .../bottomsheet/res/values-pl/strings.xml | 2 +- .../bottomsheet/res/values-pt-rBR/strings.xml | 2 +- .../bottomsheet/res/values-pt-rPT/strings.xml | 2 +- .../bottomsheet/res/values-ro/strings.xml | 2 +- .../bottomsheet/res/values-ru/strings.xml | 2 +- .../bottomsheet/res/values-si/strings.xml | 2 +- .../bottomsheet/res/values-sk/strings.xml | 2 +- .../bottomsheet/res/values-sl/strings.xml | 2 +- .../bottomsheet/res/values-sq/strings.xml | 2 +- .../bottomsheet/res/values-sr/strings.xml | 2 +- .../bottomsheet/res/values-sv/strings.xml | 2 +- .../bottomsheet/res/values-sw/strings.xml | 2 +- .../bottomsheet/res/values-ta/strings.xml | 2 +- .../bottomsheet/res/values-te/strings.xml | 2 +- .../bottomsheet/res/values-th/strings.xml | 2 +- .../bottomsheet/res/values-tl/strings.xml | 2 +- .../bottomsheet/res/values-tr/strings.xml | 2 +- .../bottomsheet/res/values-uk/strings.xml | 2 +- .../bottomsheet/res/values-ur/strings.xml | 2 +- .../bottomsheet/res/values-uz/strings.xml | 2 +- .../bottomsheet/res/values-vi/strings.xml | 2 +- .../bottomsheet/res/values-zh-rCN/strings.xml | 2 +- .../bottomsheet/res/values-zh-rHK/strings.xml | 2 +- .../bottomsheet/res/values-zh-rTW/strings.xml | 2 +- .../bottomsheet/res/values-zu/strings.xml | 2 +- .../android/material/canvas/CanvasCompat.java | 8 + .../android/material/carousel/Maskable.java | 17 +- .../carousel/MaskableFrameLayout.java | 317 ++++++++-- .../google/android/material/chip/Chip.java | 2 +- .../material/chip/res/values-af/strings.xml | 2 +- .../material/chip/res/values-am/strings.xml | 2 +- .../material/chip/res/values-ar/strings.xml | 2 +- .../material/chip/res/values-as/strings.xml | 2 +- .../material/chip/res/values-az/strings.xml | 2 +- .../chip/res/values-b+es+419/strings.xml | 2 +- .../chip/res/values-b+sr+Latn/strings.xml | 2 +- .../material/chip/res/values-be/strings.xml | 2 +- .../material/chip/res/values-bg/strings.xml | 2 +- .../material/chip/res/values-bn/strings.xml | 2 +- .../material/chip/res/values-bs/strings.xml | 2 +- .../material/chip/res/values-ca/strings.xml | 2 +- .../material/chip/res/values-cs/strings.xml | 2 +- .../material/chip/res/values-da/strings.xml | 2 +- .../material/chip/res/values-de/strings.xml | 2 +- .../material/chip/res/values-el/strings.xml | 2 +- .../chip/res/values-en-rGB/strings.xml | 2 +- .../chip/res/values-es-rUS/strings.xml | 2 +- .../material/chip/res/values-es/strings.xml | 2 +- .../material/chip/res/values-et/strings.xml | 2 +- .../material/chip/res/values-eu/strings.xml | 2 +- .../material/chip/res/values-fa/strings.xml | 2 +- .../material/chip/res/values-fi/strings.xml | 2 +- .../chip/res/values-fr-rCA/strings.xml | 2 +- .../material/chip/res/values-fr/strings.xml | 2 +- .../material/chip/res/values-gl/strings.xml | 2 +- .../material/chip/res/values-gu/strings.xml | 2 +- .../material/chip/res/values-hi/strings.xml | 2 +- .../material/chip/res/values-hr/strings.xml | 2 +- .../material/chip/res/values-hu/strings.xml | 2 +- .../material/chip/res/values-hy/strings.xml | 2 +- .../material/chip/res/values-in/strings.xml | 2 +- .../material/chip/res/values-is/strings.xml | 2 +- .../material/chip/res/values-it/strings.xml | 2 +- .../material/chip/res/values-iw/strings.xml | 2 +- .../material/chip/res/values-ja/strings.xml | 2 +- .../material/chip/res/values-ka/strings.xml | 2 +- .../material/chip/res/values-kk/strings.xml | 4 +- .../material/chip/res/values-km/strings.xml | 2 +- .../material/chip/res/values-kn/strings.xml | 2 +- .../material/chip/res/values-ko/strings.xml | 2 +- .../material/chip/res/values-ky/strings.xml | 2 +- .../material/chip/res/values-lo/strings.xml | 2 +- .../material/chip/res/values-lt/strings.xml | 2 +- .../material/chip/res/values-lv/strings.xml | 2 +- .../material/chip/res/values-mk/strings.xml | 2 +- .../material/chip/res/values-ml/strings.xml | 2 +- .../material/chip/res/values-mn/strings.xml | 2 +- .../material/chip/res/values-mr/strings.xml | 2 +- .../material/chip/res/values-ms/strings.xml | 2 +- .../material/chip/res/values-my/strings.xml | 2 +- .../material/chip/res/values-nb/strings.xml | 2 +- .../material/chip/res/values-ne/strings.xml | 2 +- .../material/chip/res/values-nl/strings.xml | 2 +- .../material/chip/res/values-or/strings.xml | 2 +- .../material/chip/res/values-pa/strings.xml | 2 +- .../material/chip/res/values-pl/strings.xml | 2 +- .../chip/res/values-pt-rBR/strings.xml | 2 +- .../chip/res/values-pt-rPT/strings.xml | 2 +- .../material/chip/res/values-ro/strings.xml | 2 +- .../material/chip/res/values-ru/strings.xml | 2 +- .../material/chip/res/values-si/strings.xml | 2 +- .../material/chip/res/values-sk/strings.xml | 2 +- .../material/chip/res/values-sl/strings.xml | 2 +- .../material/chip/res/values-sq/strings.xml | 2 +- .../material/chip/res/values-sr/strings.xml | 2 +- .../material/chip/res/values-sv/strings.xml | 2 +- .../material/chip/res/values-sw/strings.xml | 2 +- .../material/chip/res/values-ta/strings.xml | 2 +- .../material/chip/res/values-te/strings.xml | 2 +- .../material/chip/res/values-th/strings.xml | 2 +- .../material/chip/res/values-tl/strings.xml | 2 +- .../material/chip/res/values-tr/strings.xml | 2 +- .../material/chip/res/values-uk/strings.xml | 2 +- .../material/chip/res/values-ur/strings.xml | 2 +- .../material/chip/res/values-uz/strings.xml | 2 +- .../material/chip/res/values-v23/styles.xml | 28 - .../material/chip/res/values-vi/strings.xml | 2 +- .../chip/res/values-zh-rCN/strings.xml | 2 +- .../chip/res/values-zh-rHK/strings.xml | 2 +- .../chip/res/values-zh-rTW/strings.xml | 2 +- .../material/chip/res/values-zu/strings.xml | 2 +- .../material/chip/res/values/styles.xml | 4 +- .../material/color/DynamicColorsOptions.java | 31 +- .../android/material/color/ThemeUtils.java | 16 +- .../color/utilities/DynamicColor.java | 8 +- .../material/datepicker/DateSelector.java | 8 +- .../datepicker/res/values-af/strings.xml | 14 +- .../datepicker/res/values-am/strings.xml | 14 +- .../datepicker/res/values-ar/strings.xml | 14 +- .../datepicker/res/values-as/strings.xml | 14 +- .../datepicker/res/values-az/strings.xml | 14 +- .../res/values-b+es+419/strings.xml | 14 +- .../res/values-b+sr+Latn/strings.xml | 14 +- .../datepicker/res/values-be/strings.xml | 14 +- .../datepicker/res/values-bg/strings.xml | 14 +- .../datepicker/res/values-bn/strings.xml | 14 +- .../datepicker/res/values-bs/strings.xml | 14 +- .../datepicker/res/values-ca/strings.xml | 14 +- .../datepicker/res/values-cs/strings.xml | 14 +- .../datepicker/res/values-da/strings.xml | 14 +- .../datepicker/res/values-de/strings.xml | 14 +- .../datepicker/res/values-el/strings.xml | 14 +- .../datepicker/res/values-en-rGB/strings.xml | 14 +- .../datepicker/res/values-es-rUS/strings.xml | 14 +- .../datepicker/res/values-es/strings.xml | 14 +- .../datepicker/res/values-et/strings.xml | 14 +- .../datepicker/res/values-eu/strings.xml | 14 +- .../datepicker/res/values-fa/strings.xml | 14 +- .../datepicker/res/values-fi/strings.xml | 14 +- .../datepicker/res/values-fr-rCA/strings.xml | 14 +- .../datepicker/res/values-fr/strings.xml | 14 +- .../datepicker/res/values-gl/strings.xml | 14 +- .../datepicker/res/values-gu/strings.xml | 14 +- .../datepicker/res/values-hi/strings.xml | 16 +- .../datepicker/res/values-hr/strings.xml | 14 +- .../datepicker/res/values-hu/strings.xml | 14 +- .../datepicker/res/values-hy/strings.xml | 16 +- .../datepicker/res/values-in/strings.xml | 14 +- .../datepicker/res/values-is/strings.xml | 14 +- .../datepicker/res/values-it/strings.xml | 14 +- .../datepicker/res/values-iw/strings.xml | 14 +- .../datepicker/res/values-ja/strings.xml | 14 +- .../datepicker/res/values-ka/strings.xml | 14 +- .../datepicker/res/values-kk/strings.xml | 14 +- .../datepicker/res/values-km/strings.xml | 16 +- .../datepicker/res/values-kn/strings.xml | 14 +- .../datepicker/res/values-ko/strings.xml | 16 +- .../datepicker/res/values-ky/strings.xml | 18 +- .../datepicker/res/values-lo/strings.xml | 14 +- .../datepicker/res/values-lt/strings.xml | 14 +- .../datepicker/res/values-lv/strings.xml | 14 +- .../datepicker/res/values-mk/strings.xml | 14 +- .../datepicker/res/values-ml/strings.xml | 14 +- .../datepicker/res/values-mn/strings.xml | 14 +- .../datepicker/res/values-mr/strings.xml | 14 +- .../datepicker/res/values-ms/strings.xml | 14 +- .../datepicker/res/values-my/strings.xml | 14 +- .../datepicker/res/values-nb/strings.xml | 14 +- .../datepicker/res/values-ne/strings.xml | 14 +- .../datepicker/res/values-nl/strings.xml | 14 +- .../datepicker/res/values-or/strings.xml | 14 +- .../datepicker/res/values-pa/strings.xml | 14 +- .../datepicker/res/values-pl/strings.xml | 14 +- .../datepicker/res/values-pt-rBR/strings.xml | 14 +- .../datepicker/res/values-pt-rPT/strings.xml | 14 +- .../datepicker/res/values-ro/strings.xml | 14 +- .../datepicker/res/values-ru/strings.xml | 14 +- .../datepicker/res/values-si/strings.xml | 14 +- .../datepicker/res/values-sk/strings.xml | 14 +- .../datepicker/res/values-sl/strings.xml | 14 +- .../datepicker/res/values-sq/strings.xml | 14 +- .../datepicker/res/values-sr/strings.xml | 14 +- .../datepicker/res/values-sv/strings.xml | 14 +- .../datepicker/res/values-sw/strings.xml | 14 +- .../datepicker/res/values-ta/strings.xml | 14 +- .../datepicker/res/values-te/strings.xml | 18 +- .../datepicker/res/values-th/strings.xml | 14 +- .../datepicker/res/values-tl/strings.xml | 14 +- .../datepicker/res/values-tr/strings.xml | 14 +- .../datepicker/res/values-uk/strings.xml | 14 +- .../datepicker/res/values-ur/strings.xml | 14 +- .../datepicker/res/values-uz/strings.xml | 14 +- .../datepicker/res/values-vi/strings.xml | 14 +- .../datepicker/res/values-zh-rCN/strings.xml | 14 +- .../datepicker/res/values-zh-rHK/strings.xml | 16 +- .../datepicker/res/values-zh-rTW/strings.xml | 14 +- .../datepicker/res/values-zu/strings.xml | 14 +- .../material/dialog/res/values-af/strings.xml | 2 +- .../material/dialog/res/values-am/strings.xml | 2 +- .../material/dialog/res/values-ar/strings.xml | 2 +- .../material/dialog/res/values-as/strings.xml | 2 +- .../material/dialog/res/values-az/strings.xml | 2 +- .../dialog/res/values-b+es+419/strings.xml | 2 +- .../dialog/res/values-b+sr+Latn/strings.xml | 2 +- .../material/dialog/res/values-be/strings.xml | 2 +- .../material/dialog/res/values-bg/strings.xml | 2 +- .../material/dialog/res/values-bn/strings.xml | 2 +- .../material/dialog/res/values-bs/strings.xml | 2 +- .../material/dialog/res/values-ca/strings.xml | 2 +- .../material/dialog/res/values-cs/strings.xml | 2 +- .../material/dialog/res/values-da/strings.xml | 2 +- .../material/dialog/res/values-de/strings.xml | 2 +- .../material/dialog/res/values-el/strings.xml | 2 +- .../dialog/res/values-en-rGB/strings.xml | 2 +- .../dialog/res/values-es-rUS/strings.xml | 2 +- .../material/dialog/res/values-es/strings.xml | 2 +- .../material/dialog/res/values-et/strings.xml | 2 +- .../material/dialog/res/values-eu/strings.xml | 2 +- .../material/dialog/res/values-fa/strings.xml | 2 +- .../material/dialog/res/values-fi/strings.xml | 2 +- .../dialog/res/values-fr-rCA/strings.xml | 2 +- .../material/dialog/res/values-fr/strings.xml | 2 +- .../material/dialog/res/values-gl/strings.xml | 2 +- .../material/dialog/res/values-gu/strings.xml | 2 +- .../material/dialog/res/values-hi/strings.xml | 2 +- .../material/dialog/res/values-hr/strings.xml | 2 +- .../material/dialog/res/values-hu/strings.xml | 2 +- .../material/dialog/res/values-hy/strings.xml | 2 +- .../material/dialog/res/values-in/strings.xml | 2 +- .../material/dialog/res/values-is/strings.xml | 2 +- .../material/dialog/res/values-it/strings.xml | 2 +- .../material/dialog/res/values-iw/strings.xml | 2 +- .../material/dialog/res/values-ja/strings.xml | 2 +- .../material/dialog/res/values-ka/strings.xml | 2 +- .../material/dialog/res/values-kk/strings.xml | 2 +- .../material/dialog/res/values-km/strings.xml | 2 +- .../material/dialog/res/values-kn/strings.xml | 2 +- .../material/dialog/res/values-ko/strings.xml | 2 +- .../material/dialog/res/values-ky/strings.xml | 2 +- .../material/dialog/res/values-lo/strings.xml | 2 +- .../material/dialog/res/values-lt/strings.xml | 2 +- .../material/dialog/res/values-lv/strings.xml | 2 +- .../material/dialog/res/values-mk/strings.xml | 2 +- .../material/dialog/res/values-ml/strings.xml | 2 +- .../material/dialog/res/values-mn/strings.xml | 2 +- .../material/dialog/res/values-mr/strings.xml | 2 +- .../material/dialog/res/values-ms/strings.xml | 2 +- .../material/dialog/res/values-my/strings.xml | 2 +- .../material/dialog/res/values-nb/strings.xml | 2 +- .../material/dialog/res/values-ne/strings.xml | 2 +- .../material/dialog/res/values-nl/strings.xml | 2 +- .../material/dialog/res/values-or/strings.xml | 2 +- .../material/dialog/res/values-pa/strings.xml | 2 +- .../material/dialog/res/values-pl/strings.xml | 2 +- .../dialog/res/values-pt-rBR/strings.xml | 2 +- .../dialog/res/values-pt-rPT/strings.xml | 2 +- .../material/dialog/res/values-ro/strings.xml | 2 +- .../material/dialog/res/values-ru/strings.xml | 2 +- .../material/dialog/res/values-si/strings.xml | 2 +- .../material/dialog/res/values-sk/strings.xml | 2 +- .../material/dialog/res/values-sl/strings.xml | 2 +- .../material/dialog/res/values-sq/strings.xml | 2 +- .../material/dialog/res/values-sr/strings.xml | 2 +- .../material/dialog/res/values-sv/strings.xml | 2 +- .../material/dialog/res/values-sw/strings.xml | 2 +- .../material/dialog/res/values-ta/strings.xml | 2 +- .../material/dialog/res/values-te/strings.xml | 2 +- .../material/dialog/res/values-th/strings.xml | 2 +- .../material/dialog/res/values-tl/strings.xml | 2 +- .../material/dialog/res/values-tr/strings.xml | 2 +- .../material/dialog/res/values-uk/strings.xml | 2 +- .../material/dialog/res/values-ur/strings.xml | 2 +- .../material/dialog/res/values-uz/strings.xml | 2 +- .../material/dialog/res/values-vi/strings.xml | 2 +- .../dialog/res/values-zh-rCN/strings.xml | 2 +- .../dialog/res/values-zh-rHK/strings.xml | 2 +- .../dialog/res/values-zh-rTW/strings.xml | 2 +- .../material/dialog/res/values-zu/strings.xml | 2 +- .../FloatingActionButtonImpl.java | 3 - .../android/material/internal/ViewUtils.java | 24 +- .../material/navigation/NavigationView.java | 121 ++-- .../navigation/res-public/values/public.xml | 1 - .../material/navigation/res/values/attrs.xml | 3 - .../resources/res/values-af/strings.xml | 2 +- .../resources/res/values-am/strings.xml | 2 +- .../resources/res/values-ar/strings.xml | 2 +- .../resources/res/values-as/strings.xml | 2 +- .../resources/res/values-az/strings.xml | 2 +- .../resources/res/values-b+es+419/strings.xml | 2 +- .../res/values-b+sr+Latn/strings.xml | 2 +- .../resources/res/values-be/strings.xml | 2 +- .../resources/res/values-bg/strings.xml | 2 +- .../resources/res/values-bn/strings.xml | 2 +- .../resources/res/values-bs/strings.xml | 2 +- .../resources/res/values-ca/strings.xml | 2 +- .../resources/res/values-cs/strings.xml | 2 +- .../resources/res/values-da/strings.xml | 2 +- .../resources/res/values-de/strings.xml | 2 +- .../resources/res/values-el/strings.xml | 2 +- .../resources/res/values-en-rGB/strings.xml | 2 +- .../resources/res/values-es-rUS/strings.xml | 2 +- .../resources/res/values-es/strings.xml | 2 +- .../resources/res/values-et/strings.xml | 2 +- .../resources/res/values-eu/strings.xml | 2 +- .../resources/res/values-fa/strings.xml | 2 +- .../resources/res/values-fi/strings.xml | 2 +- .../resources/res/values-fr-rCA/strings.xml | 2 +- .../resources/res/values-fr/strings.xml | 2 +- .../resources/res/values-gl/strings.xml | 2 +- .../resources/res/values-gu/strings.xml | 2 +- .../resources/res/values-hi/strings.xml | 2 +- .../resources/res/values-hr/strings.xml | 2 +- .../resources/res/values-hu/strings.xml | 2 +- .../resources/res/values-hy/strings.xml | 2 +- .../resources/res/values-in/strings.xml | 2 +- .../resources/res/values-is/strings.xml | 2 +- .../resources/res/values-it/strings.xml | 2 +- .../resources/res/values-iw/strings.xml | 2 +- .../resources/res/values-ja/strings.xml | 2 +- .../resources/res/values-ka/strings.xml | 2 +- .../resources/res/values-kk/strings.xml | 2 +- .../resources/res/values-km/strings.xml | 2 +- .../resources/res/values-kn/strings.xml | 2 +- .../resources/res/values-ko/strings.xml | 2 +- .../resources/res/values-ky/strings.xml | 2 +- .../resources/res/values-lo/strings.xml | 2 +- .../resources/res/values-lt/strings.xml | 2 +- .../resources/res/values-lv/strings.xml | 2 +- .../resources/res/values-mk/strings.xml | 2 +- .../resources/res/values-ml/strings.xml | 2 +- .../resources/res/values-mn/strings.xml | 2 +- .../resources/res/values-mr/strings.xml | 2 +- .../resources/res/values-ms/strings.xml | 2 +- .../resources/res/values-my/strings.xml | 2 +- .../resources/res/values-nb/strings.xml | 2 +- .../resources/res/values-ne/strings.xml | 2 +- .../resources/res/values-nl/strings.xml | 2 +- .../resources/res/values-or/strings.xml | 2 +- .../resources/res/values-pa/strings.xml | 2 +- .../resources/res/values-pl/strings.xml | 2 +- .../resources/res/values-pt-rBR/strings.xml | 2 +- .../resources/res/values-pt-rPT/strings.xml | 2 +- .../resources/res/values-ro/strings.xml | 2 +- .../resources/res/values-ru/strings.xml | 2 +- .../resources/res/values-si/strings.xml | 2 +- .../resources/res/values-sk/strings.xml | 2 +- .../resources/res/values-sl/strings.xml | 2 +- .../resources/res/values-sq/strings.xml | 2 +- .../resources/res/values-sr/strings.xml | 2 +- .../resources/res/values-sv/strings.xml | 2 +- .../resources/res/values-sw/strings.xml | 2 +- .../resources/res/values-ta/strings.xml | 2 +- .../resources/res/values-te/strings.xml | 2 +- .../resources/res/values-th/strings.xml | 2 +- .../resources/res/values-tl/strings.xml | 2 +- .../resources/res/values-tr/strings.xml | 2 +- .../resources/res/values-uk/strings.xml | 2 +- .../resources/res/values-ur/strings.xml | 2 +- .../resources/res/values-uz/strings.xml | 2 +- .../resources/res/values-vi/strings.xml | 2 +- .../resources/res/values-zh-rCN/strings.xml | 2 +- .../resources/res/values-zh-rHK/strings.xml | 2 +- .../resources/res/values-zh-rTW/strings.xml | 2 +- .../resources/res/values-zu/strings.xml | 2 +- .../material/shape/ClampedCornerSize.java | 80 +++ .../material/textfield/EndCompoundLayout.java | 15 - .../textfield/StartCompoundLayout.java | 15 - .../material/textfield/TextInputLayout.java | 34 +- .../textfield/res/values-af/strings.xml | 2 +- .../textfield/res/values-am/strings.xml | 2 +- .../textfield/res/values-ar/strings.xml | 2 +- .../textfield/res/values-as/strings.xml | 2 +- .../textfield/res/values-az/strings.xml | 2 +- .../textfield/res/values-b+es+419/strings.xml | 2 +- .../res/values-b+sr+Latn/strings.xml | 2 +- .../textfield/res/values-be/strings.xml | 2 +- .../textfield/res/values-bg/strings.xml | 2 +- .../textfield/res/values-bn/strings.xml | 2 +- .../textfield/res/values-bs/strings.xml | 2 +- .../textfield/res/values-ca/strings.xml | 2 +- .../textfield/res/values-cs/strings.xml | 2 +- .../textfield/res/values-da/strings.xml | 2 +- .../textfield/res/values-de/strings.xml | 2 +- .../textfield/res/values-el/strings.xml | 2 +- .../textfield/res/values-en-rGB/strings.xml | 2 +- .../textfield/res/values-es-rUS/strings.xml | 2 +- .../textfield/res/values-es/strings.xml | 2 +- .../textfield/res/values-et/strings.xml | 2 +- .../textfield/res/values-eu/strings.xml | 2 +- .../textfield/res/values-fa/strings.xml | 2 +- .../textfield/res/values-fi/strings.xml | 2 +- .../textfield/res/values-fr-rCA/strings.xml | 2 +- .../textfield/res/values-fr/strings.xml | 2 +- .../textfield/res/values-gl/strings.xml | 2 +- .../textfield/res/values-gu/strings.xml | 2 +- .../textfield/res/values-hi/strings.xml | 2 +- .../textfield/res/values-hr/strings.xml | 2 +- .../textfield/res/values-hu/strings.xml | 2 +- .../textfield/res/values-hy/strings.xml | 2 +- .../textfield/res/values-in/strings.xml | 2 +- .../textfield/res/values-is/strings.xml | 2 +- .../textfield/res/values-it/strings.xml | 2 +- .../textfield/res/values-iw/strings.xml | 2 +- .../textfield/res/values-ja/strings.xml | 2 +- .../textfield/res/values-ka/strings.xml | 2 +- .../textfield/res/values-kk/strings.xml | 2 +- .../textfield/res/values-km/strings.xml | 2 +- .../textfield/res/values-kn/strings.xml | 2 +- .../textfield/res/values-ko/strings.xml | 2 +- .../textfield/res/values-ky/strings.xml | 2 +- .../textfield/res/values-lo/strings.xml | 2 +- .../textfield/res/values-lt/strings.xml | 2 +- .../textfield/res/values-lv/strings.xml | 2 +- .../textfield/res/values-mk/strings.xml | 2 +- .../textfield/res/values-ml/strings.xml | 2 +- .../textfield/res/values-mn/strings.xml | 2 +- .../textfield/res/values-mr/strings.xml | 2 +- .../textfield/res/values-ms/strings.xml | 2 +- .../textfield/res/values-my/strings.xml | 2 +- .../textfield/res/values-nb/strings.xml | 2 +- .../textfield/res/values-ne/strings.xml | 2 +- .../textfield/res/values-nl/strings.xml | 2 +- .../textfield/res/values-or/strings.xml | 2 +- .../textfield/res/values-pa/strings.xml | 2 +- .../textfield/res/values-pl/strings.xml | 2 +- .../textfield/res/values-pt-rBR/strings.xml | 2 +- .../textfield/res/values-pt-rPT/strings.xml | 2 +- .../textfield/res/values-ro/strings.xml | 2 +- .../textfield/res/values-ru/strings.xml | 2 +- .../textfield/res/values-si/strings.xml | 2 +- .../textfield/res/values-sk/strings.xml | 2 +- .../textfield/res/values-sl/strings.xml | 2 +- .../textfield/res/values-sq/strings.xml | 2 +- .../textfield/res/values-sr/strings.xml | 2 +- .../textfield/res/values-sv/strings.xml | 2 +- .../textfield/res/values-sw/strings.xml | 2 +- .../textfield/res/values-ta/strings.xml | 2 +- .../textfield/res/values-te/strings.xml | 2 +- .../textfield/res/values-th/strings.xml | 2 +- .../textfield/res/values-tl/strings.xml | 2 +- .../textfield/res/values-tr/strings.xml | 2 +- .../textfield/res/values-uk/strings.xml | 2 +- .../textfield/res/values-ur/strings.xml | 2 +- .../textfield/res/values-uz/strings.xml | 2 +- .../textfield/res/values-vi/strings.xml | 2 +- .../textfield/res/values-zh-rCN/strings.xml | 2 +- .../textfield/res/values-zh-rHK/strings.xml | 2 +- .../textfield/res/values-zh-rTW/strings.xml | 2 +- .../textfield/res/values-zu/strings.xml | 2 +- .../timepicker/ChipTextInputComboView.java | 2 +- .../timepicker/res/values-af/strings.xml | 2 +- .../timepicker/res/values-am/strings.xml | 2 +- .../timepicker/res/values-ar/strings.xml | 2 +- .../timepicker/res/values-as/strings.xml | 2 +- .../timepicker/res/values-az/strings.xml | 2 +- .../res/values-b+es+419/strings.xml | 2 +- .../res/values-b+sr+Latn/strings.xml | 2 +- .../timepicker/res/values-be/strings.xml | 2 +- .../timepicker/res/values-bg/strings.xml | 2 +- .../timepicker/res/values-bn/strings.xml | 2 +- .../timepicker/res/values-bs/strings.xml | 2 +- .../timepicker/res/values-ca/strings.xml | 2 +- .../timepicker/res/values-cs/strings.xml | 2 +- .../timepicker/res/values-da/strings.xml | 2 +- .../timepicker/res/values-de/strings.xml | 2 +- .../timepicker/res/values-el/strings.xml | 2 +- .../timepicker/res/values-en-rGB/strings.xml | 2 +- .../timepicker/res/values-es-rUS/strings.xml | 2 +- .../timepicker/res/values-es/strings.xml | 2 +- .../timepicker/res/values-et/strings.xml | 2 +- .../timepicker/res/values-eu/strings.xml | 2 +- .../timepicker/res/values-fa/strings.xml | 2 +- .../timepicker/res/values-fi/strings.xml | 2 +- .../timepicker/res/values-fr-rCA/strings.xml | 2 +- .../timepicker/res/values-fr/strings.xml | 2 +- .../timepicker/res/values-gl/strings.xml | 2 +- .../timepicker/res/values-gu/strings.xml | 2 +- .../timepicker/res/values-hi/strings.xml | 2 +- .../timepicker/res/values-hr/strings.xml | 2 +- .../timepicker/res/values-hu/strings.xml | 2 +- .../timepicker/res/values-hy/strings.xml | 2 +- .../timepicker/res/values-in/strings.xml | 2 +- .../timepicker/res/values-is/strings.xml | 2 +- .../timepicker/res/values-it/strings.xml | 2 +- .../timepicker/res/values-iw/strings.xml | 2 +- .../timepicker/res/values-ja/strings.xml | 2 +- .../timepicker/res/values-ka/strings.xml | 2 +- .../timepicker/res/values-kk/strings.xml | 2 +- .../timepicker/res/values-km/strings.xml | 2 +- .../timepicker/res/values-kn/strings.xml | 2 +- .../timepicker/res/values-ko/strings.xml | 2 +- .../timepicker/res/values-ky/strings.xml | 2 +- .../timepicker/res/values-lo/strings.xml | 2 +- .../timepicker/res/values-lt/strings.xml | 2 +- .../timepicker/res/values-lv/strings.xml | 2 +- .../timepicker/res/values-mk/strings.xml | 2 +- .../timepicker/res/values-ml/strings.xml | 2 +- .../timepicker/res/values-mn/strings.xml | 2 +- .../timepicker/res/values-mr/strings.xml | 2 +- .../timepicker/res/values-ms/strings.xml | 2 +- .../timepicker/res/values-my/strings.xml | 2 +- .../timepicker/res/values-nb/strings.xml | 2 +- .../timepicker/res/values-ne/strings.xml | 2 +- .../timepicker/res/values-nl/strings.xml | 2 +- .../timepicker/res/values-or/strings.xml | 2 +- .../timepicker/res/values-pa/strings.xml | 2 +- .../timepicker/res/values-pl/strings.xml | 2 +- .../timepicker/res/values-pt-rBR/strings.xml | 2 +- .../timepicker/res/values-pt-rPT/strings.xml | 2 +- .../timepicker/res/values-ro/strings.xml | 2 +- .../timepicker/res/values-ru/strings.xml | 2 +- .../timepicker/res/values-si/strings.xml | 2 +- .../timepicker/res/values-sk/strings.xml | 2 +- .../timepicker/res/values-sl/strings.xml | 2 +- .../timepicker/res/values-sq/strings.xml | 2 +- .../timepicker/res/values-sr/strings.xml | 2 +- .../timepicker/res/values-sv/strings.xml | 2 +- .../timepicker/res/values-sw/strings.xml | 2 +- .../timepicker/res/values-ta/strings.xml | 2 +- .../timepicker/res/values-te/strings.xml | 2 +- .../timepicker/res/values-th/strings.xml | 2 +- .../timepicker/res/values-tl/strings.xml | 2 +- .../timepicker/res/values-tr/strings.xml | 2 +- .../timepicker/res/values-uk/strings.xml | 2 +- .../timepicker/res/values-ur/strings.xml | 2 +- .../timepicker/res/values-uz/strings.xml | 2 +- .../timepicker/res/values-vi/strings.xml | 2 +- .../timepicker/res/values-zh-rCN/strings.xml | 2 +- .../timepicker/res/values-zh-rHK/strings.xml | 2 +- .../timepicker/res/values-zh-rTW/strings.xml | 2 +- .../timepicker/res/values-zu/strings.xml | 2 +- .../MaterialContainerTransform.java | 2 +- .../material/transition/TransitionUtils.java | 5 +- .../platform/MaterialContainerTransform.java | 2 +- .../transition/platform/TransitionUtils.java | 5 +- .../com/squareup/picasso3/Dispatcher.kt | 2 +- .../kotlin/com/squareup/picasso3/Picasso.kt | 2 +- .../widget/LinearLayoutManager_SavedState.kt | 1 - .../StaggeredGridLayoutManager_SavedState.kt | 3 +- viewpager2/src/main/res/values/attrs.xml | 5 +- viewpager2/src/main/res/values/dimens.xml | 3 +- viewpager2/src/main/res/values/ids.xml | 5 +- 893 files changed, 5451 insertions(+), 3020 deletions(-) create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/shortvideopager/IShortVideoPagerView.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/shortvideopager/ShortVideoPagerActivity.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/shortvideopager/ShortVideoPagerPresenter.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/impl/StoriesShortVideosApi.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/interfaces/IStoriesShortVideosApi.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/model/response/CustomResponse.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/model/response/ShortVideosResponse.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/services/IStoriesShortVideosService.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/IStoriesShortVideosInteractor.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/domain/impl/StoriesShortVideosInteractor.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/likes/storiesview/IStoriesViewView.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/likes/storiesview/StoriesViewAdapter.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/likes/storiesview/StoriesViewFragment.kt create mode 100644 app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/likes/storiesview/StoriesViewPresenter.kt create mode 100644 app_fenrir/src/main/res/drawable/clip_outline.xml create mode 100644 app_fenrir/src/main/res/drawable/story_outline.xml create mode 100644 app_fenrir/src/main/res/layout/activity_shortvideo_pager.xml rename app_fenrir/src/main/res/layout/{fragment_story_pager.xml => activity_story_pager.xml} (100%) create mode 100644 app_fenrir/src/main/res/layout/content_shortvideo_page.xml create mode 100644 app_fenrir/src/main/res/layout/item_group_with_like.xml create mode 100644 app_fenrir/src/main/res/layout/item_people_with_like.xml delete mode 100644 material/java/com/google/android/material/chip/res/values-v23/styles.xml create mode 100644 material/java/com/google/android/material/shape/ClampedCornerSize.java diff --git a/app_fenrir/build.gradle b/app_fenrir/build.gradle index 21884db4a..a0c9d77d8 100644 --- a/app_fenrir/build.gradle +++ b/app_fenrir/build.gradle @@ -18,6 +18,7 @@ android { exclude("META-INF/LICENSE") exclude("META-INF/NOTICE") exclude("META-INF/*.version") + exclude("META-INF/versions/**") } dependenciesInfo { diff --git a/app_fenrir/src/main/AndroidManifest.xml b/app_fenrir/src/main/AndroidManifest.xml index e36b34188..4e7c2faba 100644 --- a/app_fenrir/src/main/AndroidManifest.xml +++ b/app_fenrir/src/main/AndroidManifest.xml @@ -401,6 +401,14 @@ android:theme="@style/App.DayNight.Swipes" android:windowSoftInputMode="adjustResize|stateHidden" /> + + place.launchActivityForResult( + this, + ShortVideoPagerActivity.newInstance(this, args) + ) + Place.SINGLE_PHOTO -> place.launchActivityForResult( this, SinglePhotoActivity.newInstance(this, args) diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/ChatActivityBubbles.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/ChatActivityBubbles.kt index c25c2b008..7960699b7 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/ChatActivityBubbles.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/ChatActivityBubbles.kt @@ -14,6 +14,7 @@ import dev.ragnarok.fenrir.Extra import dev.ragnarok.fenrir.R import dev.ragnarok.fenrir.activity.gifpager.GifPagerActivity import dev.ragnarok.fenrir.activity.photopager.PhotoPagerActivity.Companion.newInstance +import dev.ragnarok.fenrir.activity.shortvideopager.ShortVideoPagerActivity import dev.ragnarok.fenrir.activity.slidr.Slidr.attach import dev.ragnarok.fenrir.activity.slidr.model.SlidrConfig import dev.ragnarok.fenrir.activity.slidr.model.SlidrListener @@ -115,6 +116,11 @@ class ChatActivityBubbles : NoMainActivity(), PlaceProvider, AppStyleable { StoryPagerActivity.newInstance(this, args) ) + Place.SHORT_VIDEOS -> place.launchActivityForResult( + this, + ShortVideoPagerActivity.newInstance(this, args) + ) + Place.GIF_PAGER -> place.launchActivityForResult( this, GifPagerActivity.newInstance(this, args) diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/LocalJsonToChatActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/LocalJsonToChatActivity.kt index 26d9d831e..537f87457 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/LocalJsonToChatActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/LocalJsonToChatActivity.kt @@ -13,6 +13,7 @@ import dev.ragnarok.fenrir.Extra import dev.ragnarok.fenrir.R import dev.ragnarok.fenrir.activity.gifpager.GifPagerActivity import dev.ragnarok.fenrir.activity.photopager.PhotoPagerActivity.Companion.newInstance +import dev.ragnarok.fenrir.activity.shortvideopager.ShortVideoPagerActivity import dev.ragnarok.fenrir.activity.storypager.StoryPagerActivity import dev.ragnarok.fenrir.fragment.audio.AudioPlayerFragment import dev.ragnarok.fenrir.fragment.audio.AudioPlayerFragment.Companion.newInstance @@ -100,6 +101,11 @@ class LocalJsonToChatActivity : NoMainActivity(), PlaceProvider, AppStyleable { StoryPagerActivity.newInstance(this, args) ) + Place.SHORT_VIDEOS -> place.launchActivityForResult( + this, + ShortVideoPagerActivity.newInstance(this, args) + ) + Place.SINGLE_PHOTO -> place.launchActivityForResult( this, SinglePhotoActivity.newInstance(this, args) diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/LoginActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/LoginActivity.kt index d6d53d0c7..18e795387 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/LoginActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/LoginActivity.kt @@ -35,6 +35,10 @@ class LoginActivity : AppCompatActivity() { setContentView(R.layout.activity_login) val webview = findViewById(R.id.vkontakteview) webview.settings.javaScriptEnabled = true + webview.settings.domStorageEnabled = true + webview.settings.blockNetworkLoads = false + webview.settings.blockNetworkImage = false + webview.settings.databaseEnabled = true webview.clearCache(true) webview.settings.userAgentString = getUserAgentByType(Constants.DEFAULT_ACCOUNT_TYPE) diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/MainActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/MainActivity.kt index 10503a50a..53d403873 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/MainActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/MainActivity.kt @@ -40,6 +40,7 @@ import dev.ragnarok.fenrir.activity.EnterPinActivity.Companion.getClass import dev.ragnarok.fenrir.activity.gifpager.GifPagerActivity import dev.ragnarok.fenrir.activity.photopager.PhotoPagerActivity.Companion.newInstance import dev.ragnarok.fenrir.activity.qr.CameraScanActivity +import dev.ragnarok.fenrir.activity.shortvideopager.ShortVideoPagerActivity import dev.ragnarok.fenrir.activity.storypager.StoryPagerActivity import dev.ragnarok.fenrir.db.Stores import dev.ragnarok.fenrir.dialog.ResolveDomainDialog @@ -86,6 +87,7 @@ import dev.ragnarok.fenrir.fragment.friends.friendstabs.FriendsTabsFragment import dev.ragnarok.fenrir.fragment.gifts.GiftsFragment import dev.ragnarok.fenrir.fragment.groupchats.GroupChatsFragment import dev.ragnarok.fenrir.fragment.likes.LikesFragment +import dev.ragnarok.fenrir.fragment.likes.storiesview.StoriesViewFragment import dev.ragnarok.fenrir.fragment.localserver.filemanagerremote.FileManagerRemoteFragment import dev.ragnarok.fenrir.fragment.localserver.photoslocalserver.PhotosLocalServerFragment import dev.ragnarok.fenrir.fragment.logs.LogsFragment @@ -615,7 +617,7 @@ open class MainActivity : AppCompatActivity(), NavigationDrawerCallbacks, OnSect val menus = ModalBottomSheetDialogFragment.Builder() menus.add( OptionRequest( - R.id.button_ok, + 0, getString(R.string.set_offline), R.drawable.offline, true @@ -623,7 +625,7 @@ open class MainActivity : AppCompatActivity(), NavigationDrawerCallbacks, OnSect ) menus.add( OptionRequest( - R.id.button_cancel, + 1, getString(R.string.open_clipboard_url), R.drawable.web, false @@ -631,7 +633,25 @@ open class MainActivity : AppCompatActivity(), NavigationDrawerCallbacks, OnSect ) menus.add( OptionRequest( - R.id.action_preferences, + 2, + getString(R.string.stories), + R.drawable.story_outline, + true + ) + ) + if (Utils.isOfficialVKCurrent) { + menus.add( + OptionRequest( + 3, + getString(R.string.clips), + R.drawable.clip_outline, + true + ) + ) + } + menus.add( + OptionRequest( + 4, getString(R.string.settings), R.drawable.preferences, true @@ -639,7 +659,7 @@ open class MainActivity : AppCompatActivity(), NavigationDrawerCallbacks, OnSect ) menus.add( OptionRequest( - R.id.button_camera, + 5, getString(R.string.scan_qr), R.drawable.qr_code, false @@ -650,8 +670,8 @@ open class MainActivity : AppCompatActivity(), NavigationDrawerCallbacks, OnSect "left_options", object : ModalBottomSheetDialogFragment.Listener { override fun onModalOptionSelected(option: Option) { - when { - option.id == R.id.button_ok -> { + when (option.id) { + 0 -> { mCompositeDisposable.add(InteractorFactory.createAccountInteractor() .setOffline( Settings.get().accounts().current @@ -664,7 +684,7 @@ open class MainActivity : AppCompatActivity(), NavigationDrawerCallbacks, OnSect }) } - option.id == R.id.button_cancel -> { + 1 -> { val clipBoard = getSystemService(CLIPBOARD_SERVICE) as ClipboardManager? if (clipBoard != null && clipBoard.primaryClip != null && (clipBoard.primaryClip?.itemCount @@ -682,12 +702,42 @@ open class MainActivity : AppCompatActivity(), NavigationDrawerCallbacks, OnSect } } - option.id == R.id.action_preferences -> { + 2 -> { + mCompositeDisposable.add(InteractorFactory.createStoriesInteractor() + .getStory( + Settings.get().accounts().current, + null + ) + .fromIOToMain() + .subscribe({ + if (it.isEmpty()) { + createCustomToast(this@MainActivity).showToastError( + R.string.list_is_empty + ) + } + PlaceFactory.getHistoryVideoPreviewPlace( + mAccountId, + ArrayList(it), + 0 + ).tryOpenWith(this@MainActivity) + }) { + createCustomToast(this@MainActivity).showToastThrowable( + it + ) + }) + } + + 3 -> { + PlaceFactory.getShortVideoPlace(mAccountId, null) + .tryOpenWith(this@MainActivity) + } + + 4 -> { PlaceFactory.getPreferencesPlace(mAccountId) .tryOpenWith(this@MainActivity) } - option.id == R.id.button_camera && FenrirNative.isNativeLoaded -> { + 5 -> { val intent = Intent( this@MainActivity, @@ -1284,6 +1334,11 @@ open class MainActivity : AppCompatActivity(), NavigationDrawerCallbacks, OnSect StoryPagerActivity.newInstance(this, args) ) + Place.SHORT_VIDEOS -> place.launchActivityForResult( + this, + ShortVideoPagerActivity.newInstance(this, args) + ) + Place.FRIENDS_AND_FOLLOWERS -> attachToFront(FriendsTabsFragment.newInstance(args)) Place.EXTERNAL_LINK -> attachToFront(BrowserFragment.newInstance(args)) Place.DOC_PREVIEW -> { @@ -1480,6 +1535,7 @@ open class MainActivity : AppCompatActivity(), NavigationDrawerCallbacks, OnSect Place.NOTIFICATION_SETTINGS -> attachToFront(NotificationPreferencesFragment()) Place.LIKES_AND_COPIES -> attachToFront(LikesFragment.newInstance(args)) + Place.STORIES_VIEWS -> attachToFront(StoriesViewFragment.newInstance(args)) Place.CREATE_PHOTO_ALBUM, Place.EDIT_PHOTO_ALBUM -> { val createPhotoAlbumFragment = CreatePhotoAlbumFragment.newInstance(args) attachToFront(createPhotoAlbumFragment) diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/NotReadMessagesActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/NotReadMessagesActivity.kt index cf3a2e291..5e057e4d7 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/NotReadMessagesActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/NotReadMessagesActivity.kt @@ -13,6 +13,7 @@ import dev.ragnarok.fenrir.Extra import dev.ragnarok.fenrir.R import dev.ragnarok.fenrir.activity.gifpager.GifPagerActivity import dev.ragnarok.fenrir.activity.photopager.PhotoPagerActivity.Companion.newInstance +import dev.ragnarok.fenrir.activity.shortvideopager.ShortVideoPagerActivity import dev.ragnarok.fenrir.activity.slidr.Slidr.attach import dev.ragnarok.fenrir.activity.slidr.model.SlidrConfig import dev.ragnarok.fenrir.activity.slidr.model.SlidrListener @@ -115,6 +116,11 @@ class NotReadMessagesActivity : NoMainActivity(), PlaceProvider, AppStyleable { StoryPagerActivity.newInstance(this, args) ) + Place.SHORT_VIDEOS -> place.launchActivityForResult( + this, + ShortVideoPagerActivity.newInstance(this, args) + ) + Place.SINGLE_PHOTO -> place.launchActivityForResult( this, SinglePhotoActivity.newInstance(this, args) diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/SinglePhotoActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/SinglePhotoActivity.kt index ea997a4ee..0a6c36875 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/SinglePhotoActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/SinglePhotoActivity.kt @@ -45,7 +45,8 @@ import java.io.File import java.lang.ref.WeakReference import java.text.DateFormat import java.text.SimpleDateFormat -import java.util.* +import java.util.Calendar +import java.util.Date import java.util.concurrent.TimeUnit class SinglePhotoActivity : NoMainActivity(), PlaceProvider, AppStyleable { diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/ValidateActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/ValidateActivity.kt index d70e4ea4a..4a634dc07 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/ValidateActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/ValidateActivity.kt @@ -85,6 +85,10 @@ class ValidateActivity : AppCompatActivity() { ) val webview = findViewById(R.id.vkontakteview) webview.settings.javaScriptEnabled = true + webview.settings.domStorageEnabled = true + webview.settings.blockNetworkLoads = false + webview.settings.blockNetworkImage = false + webview.settings.databaseEnabled = true webview.clearCache(true) webview.settings.userAgentString = UserAgentTool.getAccountUserAgent(accountId) diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/crash/CrashUtils.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/crash/CrashUtils.kt index d1b9883cd..a4137e801 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/crash/CrashUtils.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/crash/CrashUtils.kt @@ -15,7 +15,8 @@ import java.io.PrintWriter import java.io.StringWriter import java.text.DateFormat import java.text.SimpleDateFormat -import java.util.* +import java.util.Date +import java.util.Locale object CrashUtils { private const val TAG = "CrashUtils" diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/photopager/PhotoPagerActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/photopager/PhotoPagerActivity.kt index 330588c8e..e38e23e22 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/photopager/PhotoPagerActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/photopager/PhotoPagerActivity.kt @@ -59,7 +59,6 @@ import dev.ragnarok.fenrir.view.natives.rlottie.RLottieImageView import dev.ragnarok.fenrir.view.pager.WeakPicassoLoadCallback import io.reactivex.rxjava3.core.Completable import io.reactivex.rxjava3.disposables.Disposable -import java.util.* import java.util.concurrent.TimeUnit class PhotoPagerActivity : BaseMvpActivity(), IPhotoPagerView, @@ -569,7 +568,7 @@ class PhotoPagerActivity : BaseMvpActivity override fun displayPhotos(photos: List, initialIndex: Int) { if (bShowPhotosLine) { if (photos.size <= 1) { - mAdapterRecycler.setData(Collections.emptyList()) + mAdapterRecycler.setData(emptyList()) mAdapterRecycler.notifyDataSetChanged() } else { mAdapterRecycler.setData(photos) diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/qr/CameraScanActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/qr/CameraScanActivity.kt index 4f4d7ab5f..7292ab63b 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/qr/CameraScanActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/qr/CameraScanActivity.kt @@ -32,7 +32,8 @@ import dev.ragnarok.fenrir.util.AppPerms import dev.ragnarok.fenrir.util.AppPerms.requestPermissionsResultAbs import dev.ragnarok.fenrir.util.Utils import java.nio.ByteBuffer -import java.util.* +import java.util.EnumMap +import java.util.EnumSet class CameraScanActivity : NoMainActivity() { private lateinit var textureView: PreviewView diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/qr/CustomQRCodeWriter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/qr/CustomQRCodeWriter.kt index a52d90812..5f45c4073 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/qr/CustomQRCodeWriter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/qr/CustomQRCodeWriter.kt @@ -10,7 +10,7 @@ import com.google.zxing.WriterException import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel import com.google.zxing.qrcode.encoder.ByteMatrix import com.google.zxing.qrcode.encoder.Encoder -import java.util.* +import java.util.Arrays import kotlin.math.roundToInt class CustomQRCodeWriter { diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/selectprofiles/SelectedProfilesAdapter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/selectprofiles/SelectedProfilesAdapter.kt index 3e86c8e83..2317fb717 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/selectprofiles/SelectedProfilesAdapter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/selectprofiles/SelectedProfilesAdapter.kt @@ -14,7 +14,6 @@ import dev.ragnarok.fenrir.model.Owner import dev.ragnarok.fenrir.model.User import dev.ragnarok.fenrir.picasso.PicassoInstance.Companion.with import dev.ragnarok.fenrir.settings.CurrentTheme -import java.util.EventListener class SelectedProfilesAdapter(private val mContext: Context, private val mData: List) : RecyclerView.Adapter() { @@ -99,7 +98,7 @@ class SelectedProfilesAdapter(private val mContext: Context, private val mData: notifyItemChanged(0) } - interface ActionListener : EventListener { + interface ActionListener { fun onClick(adapterPosition: Int, owner: Owner) fun onCheckClick() } diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/shortvideopager/IShortVideoPagerView.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/shortvideopager/IShortVideoPagerView.kt new file mode 100644 index 000000000..c294aaf2d --- /dev/null +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/shortvideopager/IShortVideoPagerView.kt @@ -0,0 +1,33 @@ +package dev.ragnarok.fenrir.activity.shortvideopager + +import androidx.annotation.StringRes +import dev.ragnarok.fenrir.fragment.base.core.IErrorView +import dev.ragnarok.fenrir.fragment.base.core.IMvpView +import dev.ragnarok.fenrir.fragment.base.core.IToastView +import dev.ragnarok.fenrir.media.story.IStoryPlayer +import dev.ragnarok.fenrir.model.Commented +import dev.ragnarok.fenrir.model.Video + +interface IShortVideoPagerView : IMvpView, IErrorView, IToastView { + fun displayData(pageCount: Int, selectedIndex: Int) + fun setAspectRatioAt(position: Int, w: Int, h: Int) + fun setPreparingProgressVisible(position: Int, preparing: Boolean) + fun attachDisplayToPlayer(adapterPosition: Int, storyPlayer: IStoryPlayer?) + fun setToolbarTitle(@StringRes titleRes: Int, vararg params: Any?) + fun setToolbarSubtitle(shortVideo: Video, account_id: Long) + fun onShare(shortVideo: Video, account_id: Long) + fun configHolder(adapterPosition: Int, progress: Boolean, aspectRatioW: Int, aspectRatioH: Int) + fun onNext() + fun requestWriteExternalStoragePermission() + fun showMessage(@StringRes message: Int, error: Boolean) + fun showMessage(message: String, error: Boolean) + fun updateCount(count: Int) + fun notifyDataSetChanged() + fun notifyDataAdded(pos: Int, count: Int) + fun displayListLoading(loading: Boolean) + + fun displayLikes(count: Int, userLikes: Boolean) + fun displayCommentCount(count: Int) + fun showComments(accountId: Long, commented: Commented) + fun goToLikes(accountId: Long, type: String, ownerId: Long, id: Int) +} diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/shortvideopager/ShortVideoPagerActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/shortvideopager/ShortVideoPagerActivity.kt new file mode 100644 index 000000000..4793739af --- /dev/null +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/shortvideopager/ShortVideoPagerActivity.kt @@ -0,0 +1,589 @@ +package dev.ragnarok.fenrir.activity.shortvideopager + +import android.Manifest +import android.annotation.SuppressLint +import android.content.Context +import android.content.Intent +import android.graphics.Color +import android.os.Bundle +import android.util.SparseArray +import android.view.* +import android.widget.ImageView +import android.widget.RelativeLayout +import android.widget.TextView +import androidx.annotation.ColorInt +import androidx.annotation.LayoutRes +import androidx.annotation.StringRes +import androidx.appcompat.widget.Toolbar +import androidx.recyclerview.widget.RecyclerView +import androidx.viewpager2.widget.ViewPager2 +import com.google.android.material.snackbar.Snackbar +import com.squareup.picasso3.Transformation +import dev.ragnarok.fenrir.* +import dev.ragnarok.fenrir.activity.ActivityFeatures +import dev.ragnarok.fenrir.activity.BaseMvpActivity +import dev.ragnarok.fenrir.activity.SendAttachmentsActivity +import dev.ragnarok.fenrir.activity.slidr.Slidr +import dev.ragnarok.fenrir.activity.slidr.model.SlidrConfig +import dev.ragnarok.fenrir.activity.slidr.model.SlidrListener +import dev.ragnarok.fenrir.activity.slidr.model.SlidrPosition +import dev.ragnarok.fenrir.domain.ILikesInteractor +import dev.ragnarok.fenrir.fragment.audio.AudioPlayerFragment +import dev.ragnarok.fenrir.fragment.base.core.IPresenterFactory +import dev.ragnarok.fenrir.listener.AppStyleable +import dev.ragnarok.fenrir.media.story.IStoryPlayer +import dev.ragnarok.fenrir.model.Commented +import dev.ragnarok.fenrir.model.Video +import dev.ragnarok.fenrir.place.Place +import dev.ragnarok.fenrir.place.PlaceFactory +import dev.ragnarok.fenrir.place.PlaceProvider +import dev.ragnarok.fenrir.settings.CurrentTheme +import dev.ragnarok.fenrir.settings.Settings +import dev.ragnarok.fenrir.util.AppPerms.requestPermissionsAbs +import dev.ragnarok.fenrir.util.AppTextUtils +import dev.ragnarok.fenrir.util.HelperSimple +import dev.ragnarok.fenrir.util.Utils +import dev.ragnarok.fenrir.util.ViewUtils +import dev.ragnarok.fenrir.util.rxutils.RxUtils +import dev.ragnarok.fenrir.util.toast.CustomSnackbars +import dev.ragnarok.fenrir.view.CircleCounterButton +import dev.ragnarok.fenrir.view.ExpandableSurfaceView +import dev.ragnarok.fenrir.view.natives.rlottie.RLottieImageView +import io.reactivex.rxjava3.core.Completable +import io.reactivex.rxjava3.disposables.Disposable +import java.lang.ref.WeakReference +import java.util.concurrent.TimeUnit + +class ShortVideoPagerActivity : BaseMvpActivity(), + IShortVideoPagerView, PlaceProvider, AppStyleable { + private val mHolderSparseArray = SparseArray>() + private var mViewPager: ViewPager2? = null + private var mToolbar: Toolbar? = null + private var mAvatar: ImageView? = null + private var transformation: Transformation? = null + private var mDownload: CircleCounterButton? = null + private var mShare: CircleCounterButton? = null + private var likeButton: CircleCounterButton? = null + private var commentsButton: CircleCounterButton? = null + private var mFullscreen = false + private var mContentRoot: View? = null + private var helpDisposable = Disposable.disposed() + private var mAdapter: Adapter? = null + private var mLoadingProgressBarDispose = Disposable.disposed() + private var mLoadingProgressBarLoaded = false + private var mLoadingProgressBar: RLottieImageView? = null + private var shortVideoLength: TextView? = null + + @LayoutRes + override fun getNoMainContentView(): Int { + return R.layout.activity_shortvideo_pager + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + mFullscreen = savedInstanceState?.getBoolean("mFullscreen") ?: false + transformation = CurrentTheme.createTransformationForAvatar() + mContentRoot = findViewById(R.id.shortvideo_pager_root) + mToolbar = findViewById(R.id.toolbar) + setSupportActionBar(mToolbar) + mAvatar = findViewById(R.id.toolbar_avatar) + mViewPager = findViewById(R.id.view_pager) + mViewPager?.offscreenPageLimit = 1 + likeButton = findViewById(R.id.like_button) + commentsButton = findViewById(R.id.comments_button) + shortVideoLength = findViewById(R.id.item_short_video_length) + commentsButton?.setOnClickListener { + presenter?.fireCommentsClick() + } + likeButton?.setOnClickListener { + presenter?.fireLikeClick() + } + likeButton?.setOnLongClickListener { + presenter?.fireLikeLongClick() + true + } + mLoadingProgressBar = findViewById(R.id.loading_progress_bar) + mViewPager?.setPageTransformer( + Utils.createPageTransform( + Settings.get().main().viewpager_page_transform + ) + ) + val mHelper = findViewById(R.id.swipe_helper) + if (HelperSimple.needHelp(HelperSimple.SHORT_VIDEO_HELPER, 2)) { + mHelper?.visibility = View.VISIBLE + mHelper?.fromRes( + dev.ragnarok.fenrir_common.R.raw.story_guide_hand_swipe, + Utils.dp(500F), + Utils.dp(500F), + intArrayOf(0x333333, CurrentTheme.getColorSecondary(this)) + ) + mHelper?.playAnimation() + helpDisposable = Completable.create { + it.onComplete() + }.delay(5, TimeUnit.SECONDS).fromIOToMain().subscribe({ + mHelper?.clearAnimationDrawable() + mHelper?.visibility = View.GONE + }, RxUtils.ignore()) + } else { + mHelper?.visibility = View.GONE + } + mViewPager?.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { + override fun onPageSelected(position: Int) { + super.onPageSelected(position) + presenter?.firePageSelected(position) + } + }) + mDownload = findViewById(R.id.button_download) + mShare = findViewById(R.id.button_share) + mShare?.setOnClickListener { presenter?.fireShareButtonClick() } + mDownload?.setOnClickListener { presenter?.fireDownloadButtonClick() } + resolveFullscreenViews() + val mButtonsRoot: View = findViewById(R.id.buttons) + + Slidr.attach( + this, + SlidrConfig.Builder().setAlphaForView(false).fromUnColoredToColoredStatusBar(true) + .position(SlidrPosition.LEFT) + .listener(object : SlidrListener { + override fun onSlideStateChanged(state: Int) { + + } + + @SuppressLint("Range") + override fun onSlideChange(percent: Float) { + var tmp = 1f - percent + tmp *= 4 + tmp = Utils.clamp(1f - tmp, 0f, 1f) + if (Utils.hasOreo()) { + mContentRoot?.setBackgroundColor(Color.argb(tmp, 0f, 0f, 0f)) + } else { + mContentRoot?.setBackgroundColor( + Color.argb( + (tmp * 255).toInt(), + 0, + 0, + 0 + ) + ) + } + mButtonsRoot.alpha = tmp + mToolbar?.alpha = tmp + mViewPager?.alpha = Utils.clamp(percent, 0f, 1f) + } + + override fun onSlideOpened() { + + } + + override fun onSlideClosed(): Boolean { + finish() + overridePendingTransition(0, 0) + return true + } + + }).build() + ) + } + + override fun displayLikes(count: Int, userLikes: Boolean) { + likeButton?.setIcon(if (userLikes) R.drawable.heart_filled else R.drawable.heart) + likeButton?.count = count + likeButton?.isActive = userLikes + } + + override fun displayCommentCount(count: Int) { + commentsButton?.count = count + } + + override fun showComments(accountId: Long, commented: Commented) { + PlaceFactory.getCommentsPlace(accountId, commented, null).tryOpenWith(this) + } + + override fun goToLikes(accountId: Long, type: String, ownerId: Long, id: Int) { + PlaceFactory.getLikesCopiesPlace( + accountId, + type, + ownerId, + id, + ILikesInteractor.FILTER_LIKES + ) + .tryOpenWith(this) + } + + override fun displayListLoading(loading: Boolean) { + mLoadingProgressBarDispose.dispose() + if (loading) { + mLoadingProgressBarDispose = Completable.create { + it.onComplete() + }.delay(300, TimeUnit.MILLISECONDS).fromIOToMain().subscribe({ + mLoadingProgressBarLoaded = true + mLoadingProgressBar?.visibility = View.VISIBLE + mLoadingProgressBar?.fromRes( + dev.ragnarok.fenrir_common.R.raw.loading, + Utils.dp(100F), + Utils.dp(100F), + intArrayOf( + 0x000000, + Color.WHITE, + 0x777777, + Color.WHITE + ) + ) + mLoadingProgressBar?.playAnimation() + }, RxUtils.ignore()) + } else if (mLoadingProgressBarLoaded) { + mLoadingProgressBarLoaded = false + mLoadingProgressBar?.visibility = View.GONE + mLoadingProgressBar?.clearAnimationDrawable() + } + } + + override fun showMessage(@StringRes message: Int, error: Boolean) { + CustomSnackbars.createCustomSnackbars(mContentRoot, null, true) + ?.setDurationSnack(Snackbar.LENGTH_LONG)?.let { + if (error) { + it.coloredSnack(message, Color.parseColor("#ff0000")).show() + } else { + it.defaultSnack(message).show() + } + } + } + + override fun showMessage(message: String, error: Boolean) { + CustomSnackbars.createCustomSnackbars(mContentRoot, null, true) + ?.setDurationSnack(Snackbar.LENGTH_LONG)?.let { + if (error) { + it.coloredSnack(message, Color.parseColor("#ff0000")).show() + } else { + it.defaultSnack(message).show() + } + } + } + + override fun updateCount(count: Int) { + mAdapter?.updateCount(count) + } + + override fun notifyDataSetChanged() { + mAdapter?.notifyDataSetChanged() + } + + override fun notifyDataAdded(pos: Int, count: Int) { + mAdapter?.notifyItemRangeInserted(pos, count) + } + + override fun openPlace(place: Place) { + val args = place.safeArguments() + when (place.type) { + Place.PLAYER -> { + val player = supportFragmentManager.findFragmentByTag("audio_player") + if (player is AudioPlayerFragment) player.dismiss() + AudioPlayerFragment.newInstance(args).show(supportFragmentManager, "audio_player") + } + + else -> Utils.openPlaceWithSwipebleActivity(this, place) + } + } + + override fun hideMenu(hide: Boolean) {} + override fun openMenu(open: Boolean) {} + + @Suppress("DEPRECATION") + override fun setStatusbarColored(colored: Boolean, invertIcons: Boolean) { + val statusbarNonColored = CurrentTheme.getStatusBarNonColored(this) + val statusbarColored = CurrentTheme.getStatusBarColor(this) + val w = window + w.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) + w.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) + w.statusBarColor = if (colored) statusbarColored else statusbarNonColored + @ColorInt val navigationColor = + if (colored) CurrentTheme.getNavigationBarColor(this) else Color.BLACK + w.navigationBarColor = navigationColor + if (Utils.hasMarshmallow()) { + var flags = window.decorView.systemUiVisibility + flags = if (invertIcons) { + flags or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR + } else { + flags and View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.inv() + } + window.decorView.systemUiVisibility = flags + } + if (Utils.hasOreo()) { + var flags = window.decorView.systemUiVisibility + if (invertIcons) { + flags = flags or View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR + w.decorView.systemUiVisibility = flags + w.navigationBarColor = Color.WHITE + } else { + flags = flags and View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR.inv() + w.decorView.systemUiVisibility = flags + } + } + } + + private val requestWritePermission = requestPermissionsAbs( + arrayOf( + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.READ_EXTERNAL_STORAGE + ) + ) { + lazyPresenter { fireWritePermissionResolved() } + } + + override fun requestWriteExternalStoragePermission() { + requestWritePermission.launch() + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + outState.putBoolean("mFullscreen", mFullscreen) + } + + override fun onResume() { + super.onResume() + ActivityFeatures.Builder() + .begin() + .setHideNavigationMenu(true) + .setBarsColored(colored = false, invertIcons = false) + .build() + .apply(this) + } + + internal fun toggleFullscreen() { + mFullscreen = !mFullscreen + resolveFullscreenViews() + } + + private fun resolveFullscreenViews() { + mToolbar?.visibility = if (mFullscreen) View.GONE else View.VISIBLE + mDownload?.visibility = if (mFullscreen) View.GONE else View.VISIBLE + mShare?.visibility = if (mFullscreen) View.GONE else View.VISIBLE + likeButton?.visibility = if (mFullscreen) View.GONE else View.VISIBLE + commentsButton?.visibility = if (mFullscreen) View.GONE else View.VISIBLE + } + + override fun getPresenterFactory(saveInstanceState: Bundle?): IPresenterFactory = + object : IPresenterFactory { + override fun create(): ShortVideoPagerPresenter { + val aid = requireArguments().getLong(Extra.ACCOUNT_ID) + val ownerId: Long? = if (!requireArguments().getBoolean(Extra.NO_OWNER_ID)) { + requireArguments().getLong(Extra.OWNER_ID) + } else { + null + } + return ShortVideoPagerPresenter( + aid, + ownerId, + this@ShortVideoPagerActivity, + saveInstanceState + ) + } + } + + override fun displayData(pageCount: Int, selectedIndex: Int) { + mAdapter = Adapter(pageCount) + mViewPager?.adapter = mAdapter + mViewPager?.setCurrentItem(selectedIndex, false) + } + + override fun setAspectRatioAt(position: Int, w: Int, h: Int) { + findByPosition(position)?.setAspectRatio(w, h) + } + + override fun setPreparingProgressVisible(position: Int, preparing: Boolean) { + for (i in 0 until mHolderSparseArray.size()) { + val key = mHolderSparseArray.keyAt(i) + val holder = findByPosition(key) + val isCurrent = position == key + val progressVisible = isCurrent && preparing + holder?.setProgressVisible(progressVisible) + holder?.setSurfaceVisible(if (isCurrent && !preparing) View.VISIBLE else View.GONE) + } + } + + override fun attachDisplayToPlayer(adapterPosition: Int, storyPlayer: IStoryPlayer?) { + val holder = findByPosition(adapterPosition) + if (holder?.isSurfaceReady == true) { + storyPlayer?.setDisplay(holder.mSurfaceHolder) + } + } + + override fun setToolbarTitle(@StringRes titleRes: Int, vararg params: Any?) { + supportActionBar?.title = getString(titleRes, *params) + } + + override fun setToolbarSubtitle(shortVideo: Video, account_id: Long) { + supportActionBar?.subtitle = shortVideo.optionalOwner?.fullName + mAvatar?.setOnClickListener { + shortVideo.optionalOwner?.let { it1 -> + PlaceFactory.getOwnerWallPlace(account_id, it1) + .tryOpenWith(this) + } + } + mAvatar?.let { + ViewUtils.displayAvatar( + it, + transformation, + shortVideo.optionalOwner?.maxSquareAvatar, + Constants.PICASSO_TAG + ) + } + shortVideoLength?.text = AppTextUtils.getDurationString(shortVideo.duration) + displayLikes(shortVideo.likesCount, shortVideo.isUserLikes) + displayCommentCount(shortVideo.commentsCount) + } + + override fun onShare(shortVideo: Video, account_id: Long) { + SendAttachmentsActivity.startForSendAttachments(this, account_id, shortVideo) + } + + override fun configHolder( + adapterPosition: Int, + progress: Boolean, + aspectRatioW: Int, + aspectRatioH: Int + ) { + val holder = findByPosition(adapterPosition) + holder?.setProgressVisible(progress) + holder?.setAspectRatio(aspectRatioW, aspectRatioH) + holder?.setSurfaceVisible(if (progress) View.GONE else View.VISIBLE) + } + + override fun onDestroy() { + super.onDestroy() + helpDisposable.dispose() + mLoadingProgressBarDispose.dispose() + } + + override fun onNext() { + mViewPager?.let { + it.adapter?.let { so -> + if (so.itemCount > it.currentItem + 1) { + it.setCurrentItem(it.currentItem + 1, true) + } + } + } + } + + internal fun fireHolderCreate(holder: Holder) { + presenter?.fireHolderCreate(holder.bindingAdapterPosition) + } + + private fun findByPosition(position: Int): Holder? { + val weak = mHolderSparseArray[position] + return weak?.get() + } + + inner class Holder(rootView: View) : RecyclerView.ViewHolder(rootView), SurfaceHolder.Callback { + val mSurfaceView: ExpandableSurfaceView = rootView.findViewById(R.id.videoSurface) + val mSurfaceHolder: SurfaceHolder = mSurfaceView.holder + val mProgressBar: RLottieImageView + var isSurfaceReady = false + override fun surfaceCreated(holder: SurfaceHolder) { + isSurfaceReady = true + presenter?.fireSurfaceCreated(bindingAdapterPosition) + } + + override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {} + override fun surfaceDestroyed(holder: SurfaceHolder) { + isSurfaceReady = false + } + + fun setProgressVisible(visible: Boolean) { + mProgressBar.visibility = if (visible) View.VISIBLE else View.GONE + if (visible) { + mProgressBar.fromRes( + dev.ragnarok.fenrir_common.R.raw.loading, + Utils.dp(100F), + Utils.dp(100F), + intArrayOf( + 0x000000, + CurrentTheme.getColorPrimary(this@ShortVideoPagerActivity), + 0x777777, + CurrentTheme.getColorSecondary(this@ShortVideoPagerActivity) + ) + ) + mProgressBar.playAnimation() + } else { + mProgressBar.clearAnimationDrawable() + } + } + + fun setAspectRatio(w: Int, h: Int) { + mSurfaceView.setAspectRatio(w, h) + } + + fun setSurfaceVisible(Vis: Int) { + mSurfaceView.visibility = Vis + } + + init { + mSurfaceHolder.addCallback(this) + mProgressBar = rootView.findViewById(R.id.preparing_progress_bar) + mSurfaceView.setOnClickListener { toggleFullscreen() } + } + } + + private inner class Adapter(private var mPageCount: Int) : RecyclerView.Adapter() { + @SuppressLint("ClickableViewAccessibility") + override fun onCreateViewHolder(container: ViewGroup, viewType: Int): Holder { + return Holder( + LayoutInflater.from(container.context) + .inflate(R.layout.content_shortvideo_page, container, false) + ) + } + + override fun onBindViewHolder(holder: Holder, position: Int) { + + } + + fun updateCount(count: Int) { + mPageCount = count + } + + override fun getItemCount(): Int { + return mPageCount + } + + override fun onViewDetachedFromWindow(holder: Holder) { + super.onViewDetachedFromWindow(holder) + mHolderSparseArray.remove(holder.bindingAdapterPosition) + } + + override fun onViewAttachedToWindow(holder: Holder) { + super.onViewAttachedToWindow(holder) + mHolderSparseArray.put(holder.bindingAdapterPosition, WeakReference(holder)) + fireHolderCreate(holder) + } + + init { + mHolderSparseArray.clear() + } + } + + companion object { + const val ACTION_OPEN = + "dev.ragnarok.fenrir.activity.shortvideopager.ShortVideoPagerActivity" + + fun newInstance(context: Context, args: Bundle?): Intent { + val ph = Intent(context, ShortVideoPagerActivity::class.java) + val targetArgs = Bundle() + targetArgs.putAll(args) + ph.action = ACTION_OPEN + ph.putExtras(targetArgs) + return ph + } + + fun buildArgs(aid: Long, ownerId: Long?): Bundle { + val args = Bundle() + args.putLong(Extra.ACCOUNT_ID, aid) + if (ownerId != null) { + args.putBoolean(Extra.NO_OWNER_ID, false) + args.putLong(Extra.OWNER_ID, ownerId) + } else { + args.putBoolean(Extra.NO_OWNER_ID, true) + } + return args + } + } +} diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/shortvideopager/ShortVideoPagerPresenter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/shortvideopager/ShortVideoPagerPresenter.kt new file mode 100644 index 000000000..d6b2af3d9 --- /dev/null +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/shortvideopager/ShortVideoPagerPresenter.kt @@ -0,0 +1,393 @@ +package dev.ragnarok.fenrir.activity.shortvideopager + +import android.content.Context +import android.os.Bundle +import dev.ragnarok.fenrir.App.Companion.instance +import dev.ragnarok.fenrir.Includes.storyPlayerFactory +import dev.ragnarok.fenrir.R +import dev.ragnarok.fenrir.domain.IVideosInteractor +import dev.ragnarok.fenrir.domain.InteractorFactory +import dev.ragnarok.fenrir.fragment.base.AccountDependencyPresenter +import dev.ragnarok.fenrir.fromIOToMain +import dev.ragnarok.fenrir.media.story.IStoryPlayer +import dev.ragnarok.fenrir.media.story.IStoryPlayer.IStatusChangeListener +import dev.ragnarok.fenrir.model.Commented +import dev.ragnarok.fenrir.model.Video +import dev.ragnarok.fenrir.model.VideoSize +import dev.ragnarok.fenrir.nonNullNoEmpty +import dev.ragnarok.fenrir.util.AppPerms.hasReadWriteStoragePermission +import dev.ragnarok.fenrir.util.DownloadWorkUtils.doDownloadVideo +import dev.ragnarok.fenrir.util.Pair +import dev.ragnarok.fenrir.util.Utils +import dev.ragnarok.fenrir.util.Utils.firstNonEmptyString + +class ShortVideoPagerPresenter( + accountId: Long, + private val ownerId: Long?, + private val context: Context, + savedInstanceState: Bundle? +) : AccountDependencyPresenter(accountId, savedInstanceState), + IStatusChangeListener, IStoryPlayer.IVideoSizeChangeListener { + private var mShortVideoPlayer: IStoryPlayer? = null + private val mShortVideos: ArrayList