diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/DeltaOwnerActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/DeltaOwnerActivity.kt index ca572f27d..7bbfb4951 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/DeltaOwnerActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/DeltaOwnerActivity.kt @@ -187,7 +187,6 @@ class DeltaOwnerActivity : AppCompatActivity(), PlaceProvider, AppStyleable { ) val viewPager: ViewPager2 = findViewById(R.id.delta_pager) - viewPager.offscreenPageLimit = 1 viewPager.setPageTransformer( Utils.createPageTransform( Settings.get().main().viewpager_page_transform diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/SendAttachmentsActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/SendAttachmentsActivity.kt index 0331655f8..039a16c34 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/SendAttachmentsActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/SendAttachmentsActivity.kt @@ -42,6 +42,19 @@ class SendAttachmentsActivity : MainActivity() { context.startActivity(intent) } + fun startForSendAttachmentsIntent( + context: Context, + accountId: Long, + bundle: ModelsBundle? + ): Intent { + val intent = Intent(context, SendAttachmentsActivity::class.java) + intent.action = ACTION_SEND_ATTACHMENTS + intent.putExtra(EXTRA_INPUT_ATTACHMENTS, bundle) + intent.putExtra(EXTRA_NO_REQUIRE_PIN, true) + intent.putExtra(Extra.PLACE, PlaceFactory.getDialogsPlace(accountId, accountId, null)) + return intent + } + fun startForSendAttachmentsFor( context: Context, accountId: Long, @@ -62,11 +75,17 @@ class SendAttachmentsActivity : MainActivity() { context.startActivity(intent) } - fun startForSendAttachments(context: Context, accountId: Long, model: AbsModel) { startForSendAttachments(context, accountId, ModelsBundle(1).append(model)) } + fun startForSendAttachmentsIntent( + context: Context, + accountId: Long, + model: AbsModel + ): Intent { + return startForSendAttachmentsIntent(context, accountId, ModelsBundle(1).append(model)) + } fun startForSendAttachmentsFor( context: Context, diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/VideoPlayerActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/VideoPlayerActivity.kt index 4e947c83d..29fb4bac0 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/VideoPlayerActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/VideoPlayerActivity.kt @@ -54,7 +54,7 @@ class VideoPlayerActivity : AppCompatActivity(), SurfaceHolder.Callback, VideoControllerView.MediaPlayerControl, IVideoPlayer.IVideoSizeChangeListener, AppStyleable { private val mCompositeDisposable = CompositeDisposable() private var mDecorView: View? = null - private var mSpeed: ImageView? = null + private var mPlaySpeed: ImageView? = null private var mControllerView: VideoControllerView? = null private var mSurfaceView: ExpandableSurfaceView? = null private var mPlayer: IVideoPlayer? = null @@ -251,17 +251,17 @@ class VideoPlayerActivity : AppCompatActivity(), SurfaceHolder.Callback, if (seekSave > 0) { mPlayer?.seekTo(seekSave) } - mSpeed = findViewById(R.id.toolbar_play_speed) + mPlaySpeed = findViewById(R.id.toolbar_play_speed) Utils.setTint( - mSpeed, + mPlaySpeed, if (mPlayer?.isPlaybackSpeed == true) CurrentTheme.getColorPrimary(this) else Color.parseColor( "#ffffff" ) ) - mSpeed?.setOnClickListener { + mPlaySpeed?.setOnClickListener { mPlayer?.togglePlaybackSpeed() Utils.setTint( - mSpeed, + mPlaySpeed, if (mPlayer?.isPlaybackSpeed == true) CurrentTheme.getColorPrimary(this) else Color.parseColor( "#ffffff" ) diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/gifpager/GifPagerActivity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/gifpager/GifPagerActivity.kt index ebe6c9a84..30a42850a 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/gifpager/GifPagerActivity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/gifpager/GifPagerActivity.kt @@ -63,7 +63,6 @@ class GifPagerActivity : AbsDocumentPreviewActivity mToolbar = findViewById(R.id.toolbar) setSupportActionBar(mToolbar) mViewPager = findViewById(R.id.view_pager) - mViewPager?.offscreenPageLimit = 1 mViewPager?.setPageTransformer( Utils.createPageTransform( Settings.get().main().viewpager_page_transform 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 index c294aaf2d..7e7a9b2aa 100644 --- 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 @@ -14,7 +14,7 @@ interface IShortVideoPagerView : IMvpView, IErrorView, IToastView { 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 setToolbarSubtitle(shortVideo: Video, account_id: Long, isPlaySpeed: Boolean) fun onShare(shortVideo: Video, account_id: Long) fun configHolder(adapterPosition: Int, progress: Boolean, aspectRatioW: Int, aspectRatioH: Int) fun onNext() 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 index 4793739af..6f359c22d 100644 --- 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 @@ -50,6 +50,7 @@ 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.core.Observable import io.reactivex.rxjava3.disposables.Disposable import java.lang.ref.WeakReference import java.util.concurrent.TimeUnit @@ -60,6 +61,7 @@ class ShortVideoPagerActivity : BaseMvpActivity @@ -428,7 +444,13 @@ class ShortVideoPagerActivity : BaseMvpActivity private var mViewPager: ViewPager2? = null private var mToolbar: Toolbar? = null private var mAvatar: ImageView? = null - private var mExp: TextView? = null + private var mExpires: TextView? = null + private var mDuration: TextView? = null private var transformation: Transformation? = null private var mDownload: CircleCounterButton? = null private var mShare: CircleCounterButton? = null private var mLink: CircleCounterButton? = null private var mFullscreen = false private var hasExternalUrl = false + private var mPlaySpeed: ImageView? = null private var helpDisposable = Disposable.disposed() + private var playDispose = Disposable.disposed() @LayoutRes override fun getNoMainContentView(): Int { @@ -93,13 +98,23 @@ class StoryPagerActivity : BaseMvpActivity setSupportActionBar(mToolbar) mAvatar = findViewById(R.id.toolbar_avatar) mViewPager = findViewById(R.id.view_pager) - mViewPager?.offscreenPageLimit = 1 mViewPager?.setPageTransformer( Utils.createPageTransform( Settings.get().main().viewpager_page_transform ) ) - mExp = findViewById(R.id.item_story_expires) + mExpires = findViewById(R.id.item_story_expires) + mDuration = findViewById(R.id.item_story_duration) + mPlaySpeed = findViewById(R.id.toolbar_play_speed) + mPlaySpeed?.setOnClickListener { + val stateSpeed = presenter?.togglePlaybackSpeed() ?: false + Utils.setTint( + mPlaySpeed, + if (stateSpeed) CurrentTheme.getColorPrimary(this) else Color.parseColor( + "#ffffff" + ) + ) + } val mHelper = findViewById(R.id.swipe_helper) if (HelperSimple.needHelp(HelperSimple.STORY_HELPER, 2)) { mHelper?.visibility = View.VISIBLE @@ -122,7 +137,11 @@ class StoryPagerActivity : BaseMvpActivity mViewPager?.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { super.onPageSelected(position) - presenter?.firePageSelected(position) + playDispose.dispose() + playDispose = Observable.just(Object()) + .delay(400, TimeUnit.MILLISECONDS) + .toMainThread() + .subscribe { presenter?.firePageSelected(position) } } }) mDownload = findViewById(R.id.button_download) @@ -327,7 +346,7 @@ class StoryPagerActivity : BaseMvpActivity supportActionBar?.title = getString(titleRes, *params) } - override fun setToolbarSubtitle(story: Story, account_id: Long) { + override fun setToolbarSubtitle(story: Story, account_id: Long, isPlaySpeed: Boolean) { supportActionBar?.subtitle = story.owner?.fullName mAvatar?.setOnClickListener { story.owner?.let { it1 -> @@ -343,10 +362,10 @@ class StoryPagerActivity : BaseMvpActivity Constants.PICASSO_TAG ) } - if (story.expires <= 0) mExp?.visibility = View.GONE else { - mExp?.visibility = View.VISIBLE + if (story.expires <= 0) mExpires?.visibility = View.GONE else { + mExpires?.visibility = View.VISIBLE val exp = (story.expires - Calendar.getInstance().time.time / 1000) / 3600 - mExp?.text = getString( + mExpires?.text = getString( R.string.expires, exp.toString(), getString( @@ -357,6 +376,20 @@ class StoryPagerActivity : BaseMvpActivity ) ) } + if (story.isStoryIsVideo()) { + mDuration?.visibility = View.VISIBLE + mDuration?.text = story.video?.duration?.let { AppTextUtils.getDurationString(it) } + mPlaySpeed?.visibility = View.VISIBLE + } else { + mDuration?.visibility = View.GONE + mPlaySpeed?.visibility = View.GONE + } + Utils.setTint( + mPlaySpeed, + if (isPlaySpeed) CurrentTheme.getColorPrimary(this) else Color.parseColor( + "#ffffff" + ) + ) if (story.target_url.isNullOrEmpty()) { mLink?.visibility = View.GONE hasExternalUrl = false @@ -392,6 +425,7 @@ class StoryPagerActivity : BaseMvpActivity override fun onDestroy() { super.onDestroy() helpDisposable.dispose() + playDispose.dispose() } override fun onNext() { diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/storypager/StoryPagerPresenter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/storypager/StoryPagerPresenter.kt index 36cd0d48f..b90f41fda 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/storypager/StoryPagerPresenter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/activity/storypager/StoryPagerPresenter.kt @@ -33,8 +33,16 @@ class StoryPagerPresenter( ) : AccountDependencyPresenter(accountId, savedInstanceState), IStatusChangeListener, IStoryPlayer.IVideoSizeChangeListener { private var mStoryPlayer: IStoryPlayer? = null + private var isPlayBackSpeed = false + fun isStoryIsVideo(pos: Int): Boolean { - return mStories[pos].photo == null && mStories[pos].video != null + return mStories[pos].isStoryIsVideo() + } + + fun togglePlaybackSpeed(): Boolean { + isPlayBackSpeed = !isPlayBackSpeed + mStoryPlayer?.setPlaybackSpeed(isPlayBackSpeed) + return isPlayBackSpeed } fun getStory(pos: Int): Story { @@ -77,15 +85,16 @@ class StoryPagerPresenter( } private fun initStoryPlayer() { - if (mStoryPlayer != null) { - val old: IStoryPlayer? = mStoryPlayer - mStoryPlayer = null - old?.release() - } val story = mStories[mCurrentIndex] if (story.video == null) { + if (mStoryPlayer != null) { + val old: IStoryPlayer? = mStoryPlayer + mStoryPlayer = null + old?.release() + } return } + val update: Boolean = mStoryPlayer != null val url = firstNonEmptyString( story.video?.mp4link2160, story.video?.mp4link1440, story.video?.mp4link1080, story.video?.mp4link720, story.video?.mp4link480, @@ -95,9 +104,14 @@ class StoryPagerPresenter( view?.showError(R.string.unable_to_play_file) return } - mStoryPlayer = storyPlayerFactory.createStoryPlayer(url, false) - mStoryPlayer?.addStatusChangeListener(this) - mStoryPlayer?.addVideoSizeChangeListener(this) + if (!update) { + mStoryPlayer = storyPlayerFactory.createStoryPlayer(url, false) + mStoryPlayer?.setPlaybackSpeed(isPlayBackSpeed) + mStoryPlayer?.addStatusChangeListener(this) + mStoryPlayer?.addVideoSizeChangeListener(this) + } else { + mStoryPlayer?.updateSource(url) + } try { mStoryPlayer?.play() } catch (e: Exception) { @@ -148,7 +162,7 @@ class StoryPagerPresenter( private fun resolveToolbarSubtitle() { view?.setToolbarSubtitle( mStories[mCurrentIndex], - accountId + accountId, isPlayBackSpeed ) } diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/adapters/VideoDtoAdapter.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/adapters/VideoDtoAdapter.kt index aeebaa381..e1acd7f12 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/adapters/VideoDtoAdapter.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/adapters/VideoDtoAdapter.kt @@ -22,7 +22,7 @@ class VideoDtoAdapter : AbsAdapter("VKApiVideo") { dto.owner_id = optLong(root, "owner_id") dto.title = optString(root, "title") dto.description = optString(root, "description") - dto.duration = optInt(root, "duration") + dto.duration = optLong(root, "duration") dto.link = optString(root, "link") dto.date = optLong(root, "date") dto.adding_date = optLong(root, "adding_date") diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/model/VKApiVideo.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/model/VKApiVideo.kt index abce6195c..347e33e3c 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/model/VKApiVideo.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/api/model/VKApiVideo.kt @@ -41,7 +41,7 @@ class VKApiVideo : VKApiAttachment, Commentable, Likeable, Copyable, IIdComparab /** * Duration of the video in seconds. */ - var duration = 0 + var duration = 0L /** * String with video+vid key. diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/db/impl/VideoStorage.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/db/impl/VideoStorage.kt index 82fc5b10f..4325c2035 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/db/impl/VideoStorage.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/db/impl/VideoStorage.kt @@ -73,7 +73,7 @@ internal class VideoStorage(base: AppStorages) : AbsStorage(base), IVideoStorage .setTitle(cursor.getString(VideoColumns.TITLE)) .setDescription(cursor.getString(VideoColumns.DESCRIPTION)) .setLink(cursor.getString(VideoColumns.LINK)) - .setDuration(cursor.getInt(VideoColumns.DURATION)) + .setDuration(cursor.getLong(VideoColumns.DURATION)) .setDate(cursor.getLong(VideoColumns.DATE)) .setAddingDate(cursor.getLong(VideoColumns.ADDING_DATE)) .setViews(cursor.getInt(VideoColumns.VIEWS)) diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/db/model/entity/VideoDboEntity.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/db/model/entity/VideoDboEntity.kt index 5a3d7cc3b..e4dd324f3 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/db/model/entity/VideoDboEntity.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/db/model/entity/VideoDboEntity.kt @@ -62,7 +62,7 @@ class VideoDboEntity : DboEntity() { private set var isRepeat = false private set - var duration = 0 + var duration = 0L private set var private = false private set @@ -212,7 +212,7 @@ class VideoDboEntity : DboEntity() { return this } - fun setDuration(duration: Int): VideoDboEntity { + fun setDuration(duration: Long): VideoDboEntity { this.duration = duration return this } diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/DualTabPhotosFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/DualTabPhotosFragment.kt index a4cb19452..4b81895c6 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/DualTabPhotosFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/DualTabPhotosFragment.kt @@ -55,7 +55,6 @@ class DualTabPhotosFragment : BaseFragment(), BackPressCallback { val viewPager: ViewPager2 = root.findViewById(R.id.view_pager) mPagerAdapter = Adapter(this, mSources) viewPager.adapter = mPagerAdapter - viewPager.offscreenPageLimit = 1 viewPager.setPageTransformer( createPageTransform( Settings.get().main().viewpager_page_transform diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/AudioPlayerFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/AudioPlayerFragment.kt index 4bb82430c..ef346be05 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/AudioPlayerFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/AudioPlayerFragment.kt @@ -116,10 +116,11 @@ class AudioPlayerFragment : BottomSheetDialogFragment(), CustomSeekBar.CustomSee private val requestEqualizer = registerForActivityResult( ActivityResultContracts.StartActivityForResult() - ) { - CustomSnackbars.createCustomSnackbars(view, mPlayPauseButton) - ?.setDurationSnack(Snackbar.LENGTH_LONG)?.themedSnack(R.string.equalizer_closed)?.show() - } + ) {} + + private val requestShare = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) {} /** * Used to scan backwards through the track @@ -373,7 +374,6 @@ class AudioPlayerFragment : BottomSheetDialogFragment(), CustomSeekBar.CustomSee Settings.get().main().player_cover_transform ) ) - ivCoverPager?.offscreenPageLimit = 1 ivCoverPager?.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() { override fun onPageSelected(position: Int) { super.onPageSelected(position) @@ -862,7 +862,13 @@ class AudioPlayerFragment : BottomSheetDialogFragment(), CustomSeekBar.CustomSee createCustomToast(requireActivity()).showToastError(R.string.not_supported) return } - SendAttachmentsActivity.startForSendAttachments(requireActivity(), mAccountId, current) + requestShare.launch( + SendAttachmentsActivity.startForSendAttachmentsIntent( + requireActivity(), + mAccountId, + current + ) + ) } private fun resolveAddButton() { diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/AudioSelectTabsFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/AudioSelectTabsFragment.kt index 0ae14564d..1ea71d2b9 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/AudioSelectTabsFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/AudioSelectTabsFragment.kt @@ -52,7 +52,6 @@ class AudioSelectTabsFragment : BaseFragment(), MenuProvider { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { requireActivity().addMenuProvider(this, viewLifecycleOwner) val viewPager: ViewPager2 = view.findViewById(R.id.fragment_audios_pager) - viewPager.offscreenPageLimit = 1 viewPager.setPageTransformer( createPageTransform( Settings.get().main().viewpager_page_transform diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/AudiosTabsFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/AudiosTabsFragment.kt index 14cec8612..0b5fe5724 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/AudiosTabsFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/AudiosTabsFragment.kt @@ -55,7 +55,6 @@ class AudiosTabsFragment : BaseFragment(), MenuProvider { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { requireActivity().addMenuProvider(this, viewLifecycleOwner) val viewPager: ViewPager2 = view.findViewById(R.id.fragment_audios_pager) - viewPager.offscreenPageLimit = 1 viewPager.setPageTransformer( createPageTransform( Settings.get().main().viewpager_page_transform diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/catalog_v2/lists/CatalogV2ListFragment.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/catalog_v2/lists/CatalogV2ListFragment.kt index b4ede984e..ca03aa2f0 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/catalog_v2/lists/CatalogV2ListFragment.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/fragment/audio/catalog_v2/lists/CatalogV2ListFragment.kt @@ -146,7 +146,6 @@ class CatalogV2ListFragment : BaseMvpFragment = ArrayList(1) override var videoSize: VideoSize? = null private set + private var playbackSpeed = false private val videoListener: Player.Listener = object : Player.Listener { override fun onVideoSizeChanged(videoSize: com.google.android.exoplayer2.video.VideoSize) { this@ExoStoryPlayer.videoSize = VideoSize(videoSize.width, videoSize.height) @@ -33,7 +34,7 @@ class ExoStoryPlayer( override fun onRenderedFirstFrame() {} override fun onPlaybackStateChanged(state: @Player.State Int) { - d("FenrirExo", "onPlaybackStateChanged, state: $state") + d("FenrirExoStoryPlayer", "onPlaybackStateChanged, state: $state") onInternalPlayerStateChanged(state) } } @@ -50,6 +51,22 @@ class ExoStoryPlayer( } } + override fun updateSource(url: String?) { + internalPlayer?.stop() + setStatus(IStatus.PREPARING) + val userAgent = UserAgentTool.USER_AGENT_CURRENT_ACCOUNT + val mediaSource: MediaSource = + ProgressiveMediaSource.Factory(getExoPlayerFactory(userAgent, proxyConfig)) + .createMediaSource( + makeMediaItem( + url + ) + ) + internalPlayer?.playWhenReady = true + internalPlayer?.setMediaSource(mediaSource) + internalPlayer?.prepare() + } + private fun preparePlayer() { setStatus(IStatus.PREPARING) internalPlayer = ExoPlayer.Builder(instance).build() @@ -71,9 +88,18 @@ class ExoStoryPlayer( internalPlayer?.addListener(videoListener) internalPlayer?.playWhenReady = true internalPlayer?.setMediaSource(mediaSource) + internalPlayer?.setPlaybackSpeed(if (playbackSpeed) 2f else 1f) internalPlayer?.prepare() } + override val isPlaybackSpeed: Boolean + get() = playbackSpeed + + override fun setPlaybackSpeed(isSpeed: Boolean) { + playbackSpeed = isSpeed + internalPlayer?.setPlaybackSpeed(if (playbackSpeed) 2f else 1f) + } + internal fun onInternalPlayerStateChanged(state: @Player.State Int) { if (state == Player.STATE_READY) { setStatus(IStatus.PREPARED) diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/media/story/IStoryPlayer.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/media/story/IStoryPlayer.kt index 303d4df9d..a0595e562 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/media/story/IStoryPlayer.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/media/story/IStoryPlayer.kt @@ -4,6 +4,7 @@ import android.view.SurfaceHolder import dev.ragnarok.fenrir.model.VideoSize interface IStoryPlayer { + fun updateSource(url: String?) val videoSize: VideoSize? fun play() fun pause() @@ -14,6 +15,8 @@ interface IStoryPlayer { fun removeVideoSizeChangeListener(listener: IVideoSizeChangeListener) fun removeStatusChangeListener(listener: IStatusChangeListener) var playerStatus: Int + val isPlaybackSpeed: Boolean + fun setPlaybackSpeed(isSpeed: Boolean) interface IStatus { companion object { diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/media/video/ExoVideoPlayer.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/media/video/ExoVideoPlayer.kt index 45da0c826..adbc0ef7f 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/media/video/ExoVideoPlayer.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/media/video/ExoVideoPlayer.kt @@ -43,6 +43,7 @@ class ExoVideoPlayer( config: ProxyConfig?, @InternalVideoSize size: Int ) { + player?.stop() source = createMediaSource( context, url, @@ -91,10 +92,8 @@ class ExoVideoPlayer( get() = playbackSpeed override fun togglePlaybackSpeed() { - if (player != null) { - playbackSpeed = !playbackSpeed - player.setPlaybackSpeed(if (playbackSpeed) 2f else 1f) - } + playbackSpeed = !playbackSpeed + player?.setPlaybackSpeed(if (playbackSpeed) 2f else 1f) } override fun release() { diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/model/Story.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/model/Story.kt index 47d651831..00a2e09b5 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/model/Story.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/model/Story.kt @@ -85,6 +85,14 @@ class Story : AbsModel, ParcelNative.ParcelableNative { writeOwner(dest, owner) } + fun isStoryIsVideo(): Boolean { + return photo == null && video != null + } + + fun isStoryIsPhoto(): Boolean { + return photo != null && video == null + } + fun isEmptyStory(): Boolean { return photo == null && video == null && target_url.isNullOrEmpty() } diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/model/Video.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/model/Video.kt index b4f196d36..0e6eade24 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/model/Video.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/model/Video.kt @@ -59,7 +59,7 @@ class Video : AbsModel, ParcelNative.ParcelableNative { private set var isRepeat = false private set - var duration = 0 + var duration = 0L private set var privacyView: SimplePrivacy? = null private set @@ -119,7 +119,7 @@ class Video : AbsModel, ParcelNative.ParcelableNative { live = parcel.readString() platform = parcel.readString() isRepeat = parcel.getBoolean() - duration = parcel.readInt() + duration = parcel.readLong() privacyView = parcel.readTypedObjectCompat(SimplePrivacy.CREATOR) privacyComment = parcel.readTypedObjectCompat(SimplePrivacy.CREATOR) isCanEdit = parcel.getBoolean() @@ -161,7 +161,7 @@ class Video : AbsModel, ParcelNative.ParcelableNative { live = parcel.readString() platform = parcel.readString() isRepeat = parcel.readBoolean() - duration = parcel.readInt() + duration = parcel.readLong() privacyView = parcel.readParcelable(SimplePrivacy.NativeCreator) privacyComment = parcel.readParcelable(SimplePrivacy.NativeCreator) isCanEdit = parcel.readBoolean() @@ -218,7 +218,7 @@ class Video : AbsModel, ParcelNative.ParcelableNative { parcel.writeString(live) parcel.writeString(platform) parcel.putBoolean(isRepeat) - parcel.writeInt(duration) + parcel.writeLong(duration) parcel.writeTypedObjectCompat(privacyView, flags) parcel.writeTypedObjectCompat(privacyComment, flags) parcel.putBoolean(isCanEdit) @@ -260,7 +260,7 @@ class Video : AbsModel, ParcelNative.ParcelableNative { dest.writeString(live) dest.writeString(platform) dest.writeBoolean(isRepeat) - dest.writeInt(duration) + dest.writeLong(duration) dest.writeParcelable(privacyView) dest.writeParcelable(privacyComment) dest.writeBoolean(isCanEdit) @@ -441,7 +441,7 @@ class Video : AbsModel, ParcelNative.ParcelableNative { return this } - fun setDuration(duration: Int): Video { + fun setDuration(duration: Long): Video { this.duration = duration return this } diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/AppTextUtils.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/AppTextUtils.kt index 72750f56a..720d50373 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/AppTextUtils.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/AppTextUtils.kt @@ -168,6 +168,19 @@ object AppTextUtils { } } + fun getDurationString(seconds: Long): String { + var pSeconds = seconds + val hours = pSeconds / 3600 + val minutes = pSeconds % 3600 / 60 + pSeconds %= 60 + return if (hours == 0L) { + twoDigitString(minutes) + ":" + twoDigitString(pSeconds) + } else { + twoDigitString(hours) + ":" + twoDigitString(minutes) + ":" + twoDigitString( + pSeconds + ) + } + } fun getDurationStringMS(ms: Int): String { return getDurationString(ms / 1000) @@ -182,6 +195,14 @@ object AppTextUtils { } else number.toString() } + private fun twoDigitString(number: Long): String { + if (number == 0L) { + return TWO_ZERO + } + return if (number / 10 == 0L) { + ZERO + number + } else number.toString() + } fun getCounterWithK(counter: Int): String { val num = counter / 1000 diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/Utils.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/Utils.kt index 79506183f..dcf159b8f 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/Utils.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/util/Utils.kt @@ -1520,7 +1520,7 @@ object Utils { fun createPageTransform(@Transformers_Types type: Int): ViewPager2.PageTransformer? { when (type) { - Transformers_Types.SLIDER_TRANSFORMER -> return SliderTransformer(1) + Transformers_Types.SLIDER_TRANSFORMER -> return SliderTransformer(ViewPager2.OFFSCREEN_PAGE_LIMIT_DEFAULT) Transformers_Types.CLOCK_SPIN_TRANSFORMER -> return ClockSpinTransformer() Transformers_Types.BACKGROUND_TO_FOREGROUND_TRANSFORMER -> return BackgroundToForegroundTransformer() Transformers_Types.CUBE_IN_DEPTH_TRANSFORMER -> return CubeInDepthTransformer() diff --git a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/CustomSeekBar.kt b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/CustomSeekBar.kt index b3e11f9a2..334e2bcd6 100644 --- a/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/CustomSeekBar.kt +++ b/app_fenrir/src/main/kotlin/dev/ragnarok/fenrir/view/CustomSeekBar.kt @@ -42,6 +42,7 @@ class CustomSeekBar @JvmOverloads constructor( private var circleColor: Int private var progressColor: Int private var pressedCircleColor: Int + private var noCircle: Boolean private val rect = RectF() private var lineHeight: Float private var bufferedProgress = 0f @@ -176,6 +177,9 @@ class CustomSeekBar @JvmOverloads constructor( override fun draw(canvas: Canvas) { super.draw(canvas) + val halfLayoutHeight = layoutHeight / 2 + val halfLineHeight = lineHeight / 2 + val halfThumbWidth = thumbWidth / 2 if (pendingPosition >= 0 && thumbX <= 0 && layoutWidth > 0) { thumbX = ceil(((layoutWidth - thumbWidth) * (pendingPosition.toDouble() / duration))).toInt() @@ -186,25 +190,25 @@ class CustomSeekBar @JvmOverloads constructor( } pendingPosition = -1 } - rect[(thumbWidth / 2).toFloat(), (layoutHeight / 2 - lineHeight / 2), (layoutWidth - thumbWidth / 2).toFloat()] = - (layoutHeight / 2 + lineHeight / 2) + rect[halfThumbWidth.toFloat(), (halfLayoutHeight - halfLineHeight), (layoutWidth - halfThumbWidth).toFloat()] = + (halfLayoutHeight + halfLineHeight) paint.color = lineColor - canvas.drawRoundRect(rect, (thumbWidth / 2).toFloat(), (thumbWidth / 2).toFloat(), paint) + canvas.drawRoundRect(rect, halfThumbWidth.toFloat(), halfThumbWidth.toFloat(), paint) if (bufferedProgress > 0 && duration > 0) { paint.color = cacheColor - rect[(thumbWidth / 2).toFloat(), (layoutHeight / 2 - lineHeight / 2), thumbWidth / 2 + bufferedProgress * (layoutWidth - thumbWidth)] = - (layoutHeight / 2 + lineHeight / 2) + rect[halfThumbWidth.toFloat(), (halfLayoutHeight - halfLineHeight), halfThumbWidth + bufferedProgress * (layoutWidth - thumbWidth)] = + (halfLayoutHeight + halfLineHeight) canvas.drawRoundRect( rect, - (thumbWidth / 2).toFloat(), - (thumbWidth / 2).toFloat(), + halfThumbWidth.toFloat(), + halfThumbWidth.toFloat(), paint ) } - rect[(thumbWidth / 2).toFloat(), (layoutHeight / 2 - lineHeight / 2), (thumbWidth / 2 + if (isDragging) draggingThumbX else thumbX).toFloat()] = - (layoutHeight / 2 + lineHeight / 2) + rect[halfThumbWidth.toFloat(), (halfLayoutHeight - halfLineHeight), (halfThumbWidth + if (isDragging) draggingThumbX else thumbX).toFloat()] = + (halfLayoutHeight + halfLineHeight) paint.color = progressColor - canvas.drawRoundRect(rect, (thumbWidth / 2).toFloat(), (thumbWidth / 2).toFloat(), paint) + canvas.drawRoundRect(rect, halfThumbWidth.toFloat(), halfThumbWidth.toFloat(), paint) if (duration <= 0) { return @@ -242,24 +246,33 @@ class CustomSeekBar @JvmOverloads constructor( Color.blue(tmpColor) ) canvas.drawCircle( - ((if (isDragging) draggingThumbX else thumbX) + thumbWidth / 2).toFloat(), - (layoutHeight / 2).toFloat(), + ((if (isDragging) draggingThumbX else thumbX) + halfThumbWidth).toFloat(), + halfLayoutHeight.toFloat(), currentRadius + Utils.dp(4f), paint ) - invalidate() } else { paint.color = if (isDragging) pressedCircleColor else circleColor } - canvas.drawCircle( - ((if (isDragging) draggingThumbX else thumbX) + thumbWidth / 2).toFloat(), - (layoutHeight / 2).toFloat(), - currentRadius, - paint - ) + if (!noCircle) { + canvas.drawCircle( + ((if (isDragging) draggingThumbX else thumbX) + halfThumbWidth).toFloat(), + halfLayoutHeight.toFloat(), + currentRadius, + paint + ) + } if (isDragging) { + if (noCircle) { + canvas.drawCircle( + (draggingThumbX + halfThumbWidth).toFloat(), + halfLayoutHeight.toFloat(), + currentRadius, + paint + ) + } paint.color = Color.argb( 140, Color.red(pressedCircleColor), @@ -267,8 +280,8 @@ class CustomSeekBar @JvmOverloads constructor( Color.blue(pressedCircleColor) ) canvas.drawCircle( - ((if (isDragging) draggingThumbX else thumbX) + thumbWidth / 2).toFloat(), - (layoutHeight / 2).toFloat(), + (draggingThumbX + halfThumbWidth).toFloat(), + halfLayoutHeight.toFloat(), currentRadius + Utils.dp(4f), paint ) @@ -303,6 +316,7 @@ class CustomSeekBar @JvmOverloads constructor( a.getColor(R.styleable.CustomSeekBar_pressedCircleColor, getColorSecondary(context)) lineHeight = a.getDimension(R.styleable.CustomSeekBar_lineHeight, Utils.dpf2(2f)) val isAlpha = a.getBoolean(R.styleable.CustomSeekBar_applyAlpha, false) + noCircle = a.getBoolean(R.styleable.CustomSeekBar_noCircle, false) a.recycle() if (isAlpha) { diff --git a/app_fenrir/src/main/res/layout/activity_shortvideo_pager.xml b/app_fenrir/src/main/res/layout/activity_shortvideo_pager.xml index 914bc4d04..9cd75c0ea 100644 --- a/app_fenrir/src/main/res/layout/activity_shortvideo_pager.xml +++ b/app_fenrir/src/main/res/layout/activity_shortvideo_pager.xml @@ -31,7 +31,7 @@ app:subtitleTextColor="?colorSecondary"> + + + + + + Лакальны медыя сервер На серверы Няма сістэмнага эквалайзера - Эквалайзер зачынены Паказваць схаваныя акаўнты Задаць прыладу Непрачытаныя diff --git a/app_fenrir/src/main/res/values-ru/strings.xml b/app_fenrir/src/main/res/values-ru/strings.xml index f4ba45bbe..753364f21 100644 --- a/app_fenrir/src/main/res/values-ru/strings.xml +++ b/app_fenrir/src/main/res/values-ru/strings.xml @@ -1553,7 +1553,6 @@ Локальный медиа сервер На сервере Нет системного эквалайзера - Эквалайзер закрыт Показывать скрытые аккаунты Задать устройство Непрочитанные diff --git a/app_fenrir/src/main/res/values/attrs.xml b/app_fenrir/src/main/res/values/attrs.xml index 15277e398..bcacee367 100644 --- a/app_fenrir/src/main/res/values/attrs.xml +++ b/app_fenrir/src/main/res/values/attrs.xml @@ -218,5 +218,6 @@ + diff --git a/app_fenrir/src/main/res/values/strings.xml b/app_fenrir/src/main/res/values/strings.xml index 1383d9b03..0be71b06c 100644 --- a/app_fenrir/src/main/res/values/strings.xml +++ b/app_fenrir/src/main/res/values/strings.xml @@ -1790,7 +1790,6 @@ Local Media Server On Server No system equalizer found - equalizer closed Show hidden accounts Set Device Not read diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/activity/photopager/PhotoPagerActivity.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/activity/photopager/PhotoPagerActivity.kt index c497c0753..c09b23daa 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/activity/photopager/PhotoPagerActivity.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/activity/photopager/PhotoPagerActivity.kt @@ -160,7 +160,6 @@ class PhotoPagerActivity : BaseMvpActivity mToolbar = findViewById(R.id.toolbar) setSupportActionBar(mToolbar) mViewPager = findViewById(R.id.view_pager) - mViewPager?.offscreenPageLimit = 1 mViewPager?.setPageTransformer( Utils.createPageTransform( Settings.get().main().getViewpager_page_transform() diff --git a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/api/adapters/VideoDtoAdapter.kt b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/api/adapters/VideoDtoAdapter.kt index 6e975e283..0221defdc 100644 --- a/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/api/adapters/VideoDtoAdapter.kt +++ b/app_filegallery/src/main/kotlin/dev/ragnarok/filegallery/api/adapters/VideoDtoAdapter.kt @@ -18,7 +18,7 @@ class VideoDtoAdapter : AbsAdapter