package org.moire.ultrasonic.subsonic import android.app.AlertDialog import android.content.Context import android.content.Intent import android.view.LayoutInflater import android.view.View import android.widget.CheckBox import android.widget.EditText import android.widget.TextView import androidx.core.view.isVisible import androidx.fragment.app.Fragment import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import java.util.Locale import java.util.regex.Pattern import kotlin.collections.ArrayList import org.moire.ultrasonic.R import org.moire.ultrasonic.domain.MusicDirectory import org.moire.ultrasonic.domain.Share import org.moire.ultrasonic.service.MusicServiceFactory.getMusicService import org.moire.ultrasonic.util.BackgroundTask import org.moire.ultrasonic.util.CancellationToken import org.moire.ultrasonic.util.Constants import org.moire.ultrasonic.util.FragmentBackgroundTask import org.moire.ultrasonic.util.Settings import org.moire.ultrasonic.util.ShareDetails import org.moire.ultrasonic.util.TimeSpan import org.moire.ultrasonic.util.TimeSpanPicker import org.moire.ultrasonic.util.Util.ifNotNull /** * This class handles sharing items in the media library */ class ShareHandler(val context: Context) { private var shareDescription: EditText? = null private var timeSpanPicker: TimeSpanPicker? = null private var shareOnServerCheckBox: CheckBox? = null private var hideDialogCheckBox: CheckBox? = null private var noExpirationCheckBox: CheckBox? = null private var saveAsDefaultsCheckBox: CheckBox? = null private var textViewComment: TextView? = null private var textViewExpiration: TextView? = null private val pattern = Pattern.compile(":") fun createShare( fragment: Fragment, entries: List?, swipe: SwipeRefreshLayout?, cancellationToken: CancellationToken ) { val askForDetails = Settings.shouldAskForShareDetails val shareDetails = ShareDetails() shareDetails.Entries = entries if (askForDetails) { showDialog(fragment, shareDetails, swipe, cancellationToken) } else { shareDetails.Description = Settings.defaultShareDescription shareDetails.Expiration = TimeSpan.getCurrentTime().add( Settings.defaultShareExpirationInMillis ).totalMilliseconds share(fragment, shareDetails, swipe, cancellationToken) } } fun share( fragment: Fragment, shareDetails: ShareDetails, swipe: SwipeRefreshLayout?, cancellationToken: CancellationToken ) { val task: BackgroundTask = object : FragmentBackgroundTask( fragment.requireActivity(), true, swipe, cancellationToken ) { @Throws(Throwable::class) override fun doInBackground(): Share? { val ids: MutableList = ArrayList() if (!shareDetails.ShareOnServer && shareDetails.Entries.size == 1) return null if (shareDetails.Entries.isEmpty()) { fragment.arguments?.getString(Constants.INTENT_EXTRA_NAME_ID).ifNotNull { ids.add(it) } } else { for ((id) in shareDetails.Entries) { ids.add(id) } } val musicService = getMusicService() var timeInMillis: Long = 0 if (shareDetails.Expiration != 0L) { timeInMillis = shareDetails.Expiration } val shares = musicService.createShare(ids, shareDetails.Description, timeInMillis) return shares[0] } override fun done(result: Share?) { val intent = Intent(Intent.ACTION_SEND) intent.type = "text/plain" if (result != null) { // Created a share, send the URL intent.putExtra( Intent.EXTRA_TEXT, String.format( Locale.ROOT, "%s\n\n%s", Settings.shareGreeting, result.url ) ) } else { // Sending only text details val textBuilder = StringBuilder() textBuilder.appendLine(Settings.shareGreeting) if (!shareDetails.Entries[0].title.isNullOrEmpty()) textBuilder.append(context.resources.getString(R.string.common_title)) .append(": ").appendLine(shareDetails.Entries[0].title) if (!shareDetails.Entries[0].artist.isNullOrEmpty()) textBuilder.append(context.resources.getString(R.string.common_artist)) .append(": ").appendLine(shareDetails.Entries[0].artist) if (!shareDetails.Entries[0].album.isNullOrEmpty()) textBuilder.append(context.resources.getString(R.string.common_album)) .append(": ").append(shareDetails.Entries[0].album) intent.putExtra(Intent.EXTRA_TEXT, textBuilder.toString()) } fragment.activity?.startActivity( Intent.createChooser( intent, context.resources.getString(R.string.share_via) ) ) } } task.execute() } private fun showDialog( fragment: Fragment, shareDetails: ShareDetails, swipe: SwipeRefreshLayout?, cancellationToken: CancellationToken ) { val layout = LayoutInflater.from(fragment.context).inflate(R.layout.share_details, null) if (layout != null) { shareDescription = layout.findViewById(R.id.share_description) as EditText hideDialogCheckBox = layout.findViewById(R.id.hide_dialog) as CheckBox shareOnServerCheckBox = layout.findViewById(R.id.share_on_server) as CheckBox noExpirationCheckBox = layout.findViewById( R.id.timeSpanDisableCheckBox ) as CheckBox saveAsDefaultsCheckBox = layout.findViewById(R.id.save_as_defaults) as CheckBox timeSpanPicker = layout.findViewById(R.id.date_picker) as TimeSpanPicker textViewComment = layout.findViewById(R.id.textViewComment) as TextView textViewExpiration = layout.findViewById(R.id.textViewExpiration) as TextView } if (shareDetails.Entries.size == 1) { // For single songs the sharing may be done by text only shareOnServerCheckBox?.setOnCheckedChangeListener { _, _ -> updateVisibility() } shareOnServerCheckBox?.isChecked = Settings.shareOnServer } else { shareOnServerCheckBox?.isVisible = false } updateVisibility() val builder = AlertDialog.Builder(fragment.context) builder.setTitle(R.string.share_set_share_options) builder.setPositiveButton(R.string.menu_share) { _, _ -> if (!noExpirationCheckBox!!.isChecked) { val timeSpan: TimeSpan = timeSpanPicker!!.timeSpan val now = TimeSpan.getCurrentTime() shareDetails.Expiration = now.add(timeSpan).totalMilliseconds } shareDetails.Description = shareDescription!!.text.toString() shareDetails.ShareOnServer = shareOnServerCheckBox!!.isChecked if (hideDialogCheckBox!!.isChecked) { Settings.shouldAskForShareDetails = false } if (saveAsDefaultsCheckBox!!.isChecked) { val timeSpanType: String = timeSpanPicker!!.timeSpanType val timeSpanAmount: Int = timeSpanPicker!!.timeSpanAmount Settings.defaultShareExpiration = if (!noExpirationCheckBox!!.isChecked && timeSpanAmount > 0) String.format("%d:%s", timeSpanAmount, timeSpanType) else "" Settings.defaultShareDescription = shareDetails.Description Settings.shareOnServer = shareDetails.ShareOnServer } share(fragment, shareDetails, swipe, cancellationToken) } builder.setNegativeButton(R.string.common_cancel) { dialog, _ -> dialog.cancel() } builder.setView(layout) builder.setCancelable(true) timeSpanPicker!!.setTimeSpanDisableText(context.resources.getString(R.string.no_expiration)) noExpirationCheckBox!!.setOnCheckedChangeListener { _, b -> timeSpanPicker!!.isEnabled = !b } val defaultDescription = Settings.defaultShareDescription val timeSpan = Settings.defaultShareExpiration val split = pattern.split(timeSpan) if (split.size == 2) { val timeSpanAmount = split[0].toInt() val timeSpanType = split[1] if (timeSpanAmount > 0) { noExpirationCheckBox!!.isChecked = false timeSpanPicker!!.isEnabled = true timeSpanPicker!!.setTimeSpanAmount(timeSpanAmount.toString()) timeSpanPicker!!.setTimeSpanType(timeSpanType) } else { noExpirationCheckBox!!.isChecked = true timeSpanPicker!!.isEnabled = false } } else { noExpirationCheckBox!!.isChecked = true timeSpanPicker!!.isEnabled = false } shareDescription!!.setText(defaultDescription) builder.create() builder.show() } private fun updateVisibility() { if (!shareOnServerCheckBox!!.isVisible || shareOnServerCheckBox!!.isChecked) { noExpirationCheckBox?.isVisible = true timeSpanPicker?.isVisible = true shareDescription?.isVisible = true textViewComment?.isVisible = true textViewExpiration?.isVisible = true } else { noExpirationCheckBox?.isVisible = false timeSpanPicker?.isVisible = false shareDescription?.isVisible = false textViewComment?.isVisible = false textViewExpiration?.isVisible = false } } }