Skip to content

Commit

Permalink
feat: status sharing and saving from playback fragment
Browse files Browse the repository at this point in the history
  • Loading branch information
mardous committed Nov 6, 2024
1 parent a6303bf commit 5af7ca2
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ class WhatSaveViewModel(
}
}

fun statusIsSaved(status: Status): LiveData<Boolean> = repository.statusIsSaved(status)

fun shareStatus(status: Status): LiveData<ShareResult> = liveData(IO) {
emit(ShareResult(isLoading = true))
val data = repository.shareStatus(status)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ interface StatusDao {
@Query("SELECT EXISTS(SELECT * FROM saved_statuses WHERE original_uri = :origin OR save_name = :name)")
fun statusSaved(origin: Uri, name: String): Boolean

@Query("SELECT EXISTS(SELECT * FROM saved_statuses WHERE original_uri = :origin OR save_name = :name)")
fun statusSavedObservable(origin: Uri, name: String): LiveData<Boolean>

@Query("SELECT * FROM saved_statuses WHERE status_type = :type")
fun savedStatuses(type: Int): LiveData<List<StatusEntity>>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (C) 2024 Christians Martínez Alvarado
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/
package com.simplified.wsstatussaver.fragments.playback

import android.os.Bundle
import android.widget.TextView
import androidx.core.os.BundleCompat
import androidx.fragment.app.Fragment
import com.simplified.wsstatussaver.R
import com.simplified.wsstatussaver.WhatSaveViewModel
import com.simplified.wsstatussaver.extensions.createProgressDialog
import com.simplified.wsstatussaver.extensions.showToast
import com.simplified.wsstatussaver.extensions.startActivitySafe
import com.simplified.wsstatussaver.fragments.playback.PlaybackFragment.Companion.EXTRA_STATUS
import com.simplified.wsstatussaver.model.SavedStatus
import com.simplified.wsstatussaver.model.Status
import org.koin.androidx.viewmodel.ext.android.activityViewModel
import kotlin.properties.Delegates

/**
* @author Christians M. A. (mardous)
*/
abstract class PlaybackChildFragment(layoutRes: Int) : Fragment(layoutRes) {

protected val viewModel: WhatSaveViewModel by activityViewModel()

protected abstract val saveButton: TextView
protected abstract val shareButton: TextView

protected var status: Status by Delegates.notNull()
protected var isSaved: Boolean = false

private val progressDialog by lazy { requireContext().createProgressDialog() }

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
status = BundleCompat.getParcelable(requireArguments(), EXTRA_STATUS, Status::class.java)!!
}

override fun onStart() {
super.onStart()
viewModel.statusIsSaved(status).observe(viewLifecycleOwner) { isSaved ->
this.isSaved = (status is SavedStatus) || isSaved
if (isSaved) {
saveButton.setText(R.string.saved_label)
saveButton.setCompoundDrawablesRelativeWithIntrinsicBounds(
R.drawable.ic_round_check_24dp, 0, 0, 0
)
} else {
saveButton.setText(R.string.save_action)
saveButton.setCompoundDrawablesRelativeWithIntrinsicBounds(
R.drawable.ic_save_alt_24dp, 0, 0, 0
)
}
}
saveButton.setOnClickListener {
if (!isSaved) {
viewModel.saveStatus(status).observe(viewLifecycleOwner) { result ->
if (result.isSuccess) {
showToast(R.string.saved_successfully)
} else if (!result.isSaving) {
showToast(R.string.failed_to_save)
}
}
}
}
shareButton.setOnClickListener {
viewModel.shareStatus(status).observe(viewLifecycleOwner) { result ->
if (result.isLoading) {
progressDialog.show()
} else {
progressDialog.dismiss()
if (result.isSuccess) {
startActivitySafe(result.data.createIntent(requireContext()))
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,35 +16,31 @@ package com.simplified.wsstatussaver.fragments.playback.image
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.View
import androidx.core.os.BundleCompat
import androidx.fragment.app.Fragment
import android.widget.TextView
import com.bumptech.glide.Glide
import com.simplified.wsstatussaver.R
import com.simplified.wsstatussaver.databinding.FragmentImageBinding
import com.simplified.wsstatussaver.fragments.playback.PlaybackFragment.Companion.EXTRA_STATUS
import com.simplified.wsstatussaver.model.Status
import kotlin.properties.Delegates
import com.simplified.wsstatussaver.fragments.playback.PlaybackChildFragment

/**
* @author Christians M. A. (mardous)
*/
class ImageFragment : Fragment(R.layout.fragment_image) {
class ImageFragment : PlaybackChildFragment(R.layout.fragment_image) {

private var _binding: FragmentImageBinding? = null
private val imageView get() = _binding!!.image
private val binding get() = _binding!!
private val imageView get() = binding.image

private var status: Status by Delegates.notNull()
override val saveButton: TextView
get() = binding.playbackActionButton.saveView

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
status = BundleCompat.getParcelable(requireArguments(), EXTRA_STATUS, Status::class.java)!!
}
override val shareButton: TextView
get() = binding.playbackActionButton.shareView

@SuppressLint("ClickableViewAccessibility")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentImageBinding.bind(view)

Glide.with(this)
.asBitmap()
.load(status.fileUri)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ package com.simplified.wsstatussaver.fragments.playback.video

import android.os.Bundle
import android.view.View
import android.widget.TextView
import androidx.annotation.OptIn
import androidx.core.os.BundleCompat
import androidx.fragment.app.Fragment
import androidx.media3.common.AudioAttributes
import androidx.media3.common.C
import androidx.media3.common.MediaItem
Expand All @@ -26,26 +25,24 @@ import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.ExoPlayer
import com.simplified.wsstatussaver.R
import com.simplified.wsstatussaver.databinding.FragmentVideoBinding
import com.simplified.wsstatussaver.fragments.playback.PlaybackFragment.Companion.EXTRA_STATUS
import com.simplified.wsstatussaver.model.Status
import kotlin.properties.Delegates
import com.simplified.wsstatussaver.fragments.playback.PlaybackChildFragment

/**
* @author Christians M. A. (mardous)
*/
class VideoFragment : Fragment(R.layout.fragment_video), Player.Listener {
class VideoFragment : PlaybackChildFragment(R.layout.fragment_video), Player.Listener {

private var _binding: FragmentVideoBinding? = null
private val binding get() = _binding!!
private val playerView get() = binding.playerView

private var status: Status by Delegates.notNull()
private var player: ExoPlayer? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
status = BundleCompat.getParcelable(requireArguments(), EXTRA_STATUS, Status::class.java)!!
}
override val saveButton: TextView
get() = playerView.findViewById(R.id.saveView)

override val shareButton: TextView
get() = playerView.findViewById(R.id.shareView)

@OptIn(UnstableApi::class)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import com.simplified.wsstatussaver.model.StatusQueryResult
import com.simplified.wsstatussaver.model.StatusType

interface Repository {
fun statusIsSaved(status: Status): LiveData<Boolean>
suspend fun statuses(type: StatusType): StatusQueryResult
suspend fun savedStatuses(type: StatusType): StatusQueryResult
suspend fun shareStatus(status: Status): ShareData
Expand All @@ -50,6 +51,8 @@ class RepositoryImpl(
private val messageRepository: MessageRepository
) : Repository {

override fun statusIsSaved(status: Status): LiveData<Boolean> = statusesRepository.statusIsSaved(status)

override suspend fun statuses(type: StatusType): StatusQueryResult = statusesRepository.statuses(type)

override suspend fun savedStatuses(type: StatusType): StatusQueryResult = statusesRepository.savedStatuses(type)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import java.io.*
import java.util.Date

interface StatusesRepository {
fun statusIsSaved(status: Status): LiveData<Boolean>
suspend fun statuses(type: StatusType): StatusQueryResult
suspend fun savedStatuses(type: StatusType): StatusQueryResult
suspend fun savedStatusesObservable(type: StatusType): LiveData<List<StatusEntity>>
Expand Down Expand Up @@ -62,6 +63,9 @@ class StatusesRepositoryImpl(
return statusesLocation?.path ?: storage.externalStoragePath
}

override fun statusIsSaved(status: Status): LiveData<Boolean> =
statusDao.statusSavedObservable(status.fileUri, status.name)

override suspend fun statuses(type: StatusType): StatusQueryResult {
val statusList = arrayListOf<Status>()
val isExcludeSaved = preferences.isExcludeSavedStatuses()
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/res/layout/fragment_image.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
android:layout_height="wrap_content"
android:layout_gravity="bottom">

<include layout="@layout/playback_action_button" />
<include
android:id="@+id/playback_action_button"
layout="@layout/playback_action_button" />

</FrameLayout>

Expand Down
5 changes: 4 additions & 1 deletion app/src/main/res/layout/playback_action_button.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
<com.simplified.wsstatussaver.views.InsetsConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/actions"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="16dp">
Expand All @@ -34,6 +33,7 @@
app:layout_constraintBottom_toBottomOf="parent">

<com.google.android.material.textview.MaterialTextView
android:id="@+id/saveView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
Expand All @@ -43,6 +43,7 @@
android:gravity="center_vertical"
android:text="@string/save_action"
android:textColor="@android:color/white"
android:background="?rectSelector"
app:drawableTint="@android:color/white"
android:drawablePadding="16dp"
android:drawableStart="@drawable/ic_save_alt_24dp" />
Expand All @@ -63,6 +64,7 @@
app:layout_constraintBottom_toBottomOf="parent">

<com.google.android.material.textview.MaterialTextView
android:id="@+id/shareView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
Expand All @@ -72,6 +74,7 @@
android:gravity="center_vertical"
android:text="@string/share_action"
android:textColor="@android:color/white"
android:background="?rectSelector"
app:drawableTint="@android:color/white"
android:drawablePadding="16dp"
android:drawableStart="@drawable/ic_share_24dp" />
Expand Down

0 comments on commit 5af7ca2

Please sign in to comment.