Merge pull request #596 from nitehu/feature/share-on-server

Added option whether to create a share on the server when sharing songs
This commit is contained in:
tzugen 2021-10-13 15:05:16 +02:00 committed by GitHub
commit 910a05d49d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 191 additions and 59 deletions

View File

@ -10,6 +10,7 @@ import java.util.List;
public class ShareDetails public class ShareDetails
{ {
public String Description; public String Description;
public boolean ShareOnServer;
public long Expiration; public long Expiration;
public List<MusicDirectory.Entry> Entries; public List<MusicDirectory.Entry> Entries;
} }

View File

@ -33,6 +33,7 @@ import android.widget.SeekBar
import android.widget.SeekBar.OnSeekBarChangeListener import android.widget.SeekBar.OnSeekBarChangeListener
import android.widget.TextView import android.widget.TextView
import android.widget.ViewFlipper import android.widget.ViewFlipper
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.navigation.Navigation import androidx.navigation.Navigation
import com.mobeta.android.dslv.DragSortListView import com.mobeta.android.dslv.DragSortListView
@ -153,7 +154,7 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
return inflater.inflate(R.layout.current_playing, container, false) return inflater.inflate(R.layout.current_playing, container, false)
} }
fun findViews(view: View) { private fun findViews(view: View) {
playlistFlipper = view.findViewById(R.id.current_playing_playlist_flipper) playlistFlipper = view.findViewById(R.id.current_playing_playlist_flipper)
emptyTextView = view.findViewById(R.id.playlist_empty) emptyTextView = view.findViewById(R.id.playlist_empty)
songTitleTextView = view.findViewById(R.id.current_playing_song) songTitleTextView = view.findViewById(R.id.current_playing_song)
@ -209,7 +210,7 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
val nextButton: AutoRepeatButton = view.findViewById(R.id.button_next) val nextButton: AutoRepeatButton = view.findViewById(R.id.button_next)
val shuffleButton = view.findViewById<View>(R.id.button_shuffle) val shuffleButton = view.findViewById<View>(R.id.button_shuffle)
val ratingLinearLayout = view.findViewById<LinearLayout>(R.id.song_rating) val ratingLinearLayout = view.findViewById<LinearLayout>(R.id.song_rating)
if (!useFiveStarRating) ratingLinearLayout.visibility = View.GONE if (!useFiveStarRating) ratingLinearLayout.isVisible = false
hollowStar = Util.getDrawableFromAttribute(view.context, R.attr.star_hollow) hollowStar = Util.getDrawableFromAttribute(view.context, R.attr.star_hollow)
fullStar = Util.getDrawableFromAttribute(context, R.attr.star_full) fullStar = Util.getDrawableFromAttribute(context, R.attr.star_full)
@ -375,7 +376,7 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
mediaPlayerController.isShufflePlayEnabled = true mediaPlayerController.isShufflePlayEnabled = true
} }
visualizerViewLayout.visibility = View.GONE visualizerViewLayout.isVisible = false
VisualizerController.get().observe( VisualizerController.get().observe(
requireActivity(), requireActivity(),
{ visualizerController -> { visualizerController ->
@ -389,11 +390,9 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
LinearLayout.LayoutParams.MATCH_PARENT LinearLayout.LayoutParams.MATCH_PARENT
) )
) )
if (!visualizerView.isActive) {
visualizerViewLayout.visibility = View.GONE visualizerViewLayout.isVisible = visualizerView.isActive
} else {
visualizerViewLayout.visibility = View.VISIBLE
}
visualizerView.setOnTouchListener { _, _ -> visualizerView.setOnTouchListener { _, _ ->
visualizerView.isActive = !visualizerView.isActive visualizerView.isActive = !visualizerView.isActive
mediaPlayerController.showVisualization = visualizerView.isActive mediaPlayerController.showVisualization = visualizerView.isActive
@ -402,7 +401,7 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
isVisualizerAvailable = true isVisualizerAvailable = true
} else { } else {
Timber.d("VisualizerController Observer.onChanged has no controller") Timber.d("VisualizerController Observer.onChanged has no controller")
visualizerViewLayout.visibility = View.GONE visualizerViewLayout.isVisible = false
isVisualizerAvailable = false isVisualizerAvailable = false
} }
} }
@ -497,6 +496,7 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
val equalizerMenuItem = menu.findItem(R.id.menu_item_equalizer) val equalizerMenuItem = menu.findItem(R.id.menu_item_equalizer)
val visualizerMenuItem = menu.findItem(R.id.menu_item_visualizer) val visualizerMenuItem = menu.findItem(R.id.menu_item_visualizer)
val shareMenuItem = menu.findItem(R.id.menu_item_share) val shareMenuItem = menu.findItem(R.id.menu_item_share)
val shareSongMenuItem = menu.findItem(R.id.menu_item_share_song)
starMenuItem = menu.findItem(R.id.menu_item_star) starMenuItem = menu.findItem(R.id.menu_item_star)
val bookmarkMenuItem = menu.findItem(R.id.menu_item_bookmark_set) val bookmarkMenuItem = menu.findItem(R.id.menu_item_bookmark_set)
val bookmarkRemoveMenuItem = menu.findItem(R.id.menu_item_bookmark_delete) val bookmarkRemoveMenuItem = menu.findItem(R.id.menu_item_bookmark_delete)
@ -523,20 +523,27 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
} }
val mediaPlayerController = mediaPlayerController val mediaPlayerController = mediaPlayerController
val downloadFile = mediaPlayerController.currentPlaying val downloadFile = mediaPlayerController.currentPlaying
if (downloadFile != null) { if (downloadFile != null) {
currentSong = downloadFile.song currentSong = downloadFile.song
} }
if (useFiveStarRating) starMenuItem.isVisible = false if (useFiveStarRating) starMenuItem.isVisible = false
if (currentSong != null) { if (currentSong != null) {
starMenuItem.icon = if (currentSong!!.starred) fullStar else hollowStar starMenuItem.icon = if (currentSong!!.starred) fullStar else hollowStar
shareSongMenuItem.isVisible = true
} else { } else {
starMenuItem.icon = hollowStar starMenuItem.icon = hollowStar
shareSongMenuItem.isVisible = false
} }
if (mediaPlayerController.keepScreenOn) { if (mediaPlayerController.keepScreenOn) {
screenOption?.setTitle(R.string.download_menu_screen_off) screenOption?.setTitle(R.string.download_menu_screen_off)
} else { } else {
screenOption?.setTitle(R.string.download_menu_screen_on) screenOption?.setTitle(R.string.download_menu_screen_on)
} }
if (jukeboxOption != null) { if (jukeboxOption != null) {
jukeboxOption.isEnabled = jukeboxAvailable jukeboxOption.isEnabled = jukeboxAvailable
jukeboxOption.isVisible = jukeboxAvailable jukeboxOption.isVisible = jukeboxAvailable
@ -598,9 +605,8 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
when (menuItemId) { when (menuItemId) {
R.id.menu_show_artist -> { R.id.menu_show_artist -> {
if (entry == null) { if (entry == null) return false
return false
}
if (Settings.shouldUseId3Tags) { if (Settings.shouldUseId3Tags) {
bundle = Bundle() bundle = Bundle()
bundle.putString(Constants.INTENT_EXTRA_NAME_ID, entry.artistId) bundle.putString(Constants.INTENT_EXTRA_NAME_ID, entry.artistId)
@ -613,9 +619,8 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
return true return true
} }
R.id.menu_show_album -> { R.id.menu_show_album -> {
if (entry == null) { if (entry == null) return false
return false
}
val albumId = if (Settings.shouldUseId3Tags) entry.albumId else entry.parent val albumId = if (Settings.shouldUseId3Tags) entry.albumId else entry.parent
bundle = Bundle() bundle = Bundle()
bundle.putString(Constants.INTENT_EXTRA_NAME_ID, albumId) bundle.putString(Constants.INTENT_EXTRA_NAME_ID, albumId)
@ -627,9 +632,8 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
return true return true
} }
R.id.menu_lyrics -> { R.id.menu_lyrics -> {
if (entry == null) { if (entry == null) return false
return false
}
bundle = Bundle() bundle = Bundle()
bundle.putString(Constants.INTENT_EXTRA_NAME_ARTIST, entry.artist) bundle.putString(Constants.INTENT_EXTRA_NAME_ARTIST, entry.artist)
bundle.putString(Constants.INTENT_EXTRA_NAME_TITLE, entry.title) bundle.putString(Constants.INTENT_EXTRA_NAME_TITLE, entry.title)
@ -664,11 +668,9 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
R.id.menu_item_visualizer -> { R.id.menu_item_visualizer -> {
val active = !visualizerView.isActive val active = !visualizerView.isActive
visualizerView.isActive = active visualizerView.isActive = active
if (!visualizerView.isActive) {
visualizerViewLayout.visibility = View.GONE visualizerViewLayout.isVisible = visualizerView.isActive
} else {
visualizerViewLayout.visibility = View.VISIBLE
}
mediaPlayerController.showVisualization = visualizerView.isActive mediaPlayerController.showVisualization = visualizerView.isActive
Util.toast( Util.toast(
context, context,
@ -705,9 +707,8 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
return true return true
} }
R.id.menu_item_star -> { R.id.menu_item_star -> {
if (currentSong == null) { if (currentSong == null) return true
return true
}
val isStarred = currentSong!!.starred val isStarred = currentSong!!.starred
val id = currentSong!!.id val id = currentSong!!.id
if (isStarred) { if (isStarred) {
@ -732,9 +733,8 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
return true return true
} }
R.id.menu_item_bookmark_set -> { R.id.menu_item_bookmark_set -> {
if (currentSong == null) { if (currentSong == null) return true
return true
}
val songId = currentSong!!.id val songId = currentSong!!.id
val playerPosition = mediaPlayerController.playerPosition val playerPosition = mediaPlayerController.playerPosition
currentSong!!.bookmarkPosition = playerPosition currentSong!!.bookmarkPosition = playerPosition
@ -755,9 +755,8 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
return true return true
} }
R.id.menu_item_bookmark_delete -> { R.id.menu_item_bookmark_delete -> {
if (currentSong == null) { if (currentSong == null) return true
return true
}
val bookmarkSongId = currentSong!!.id val bookmarkSongId = currentSong!!.id
currentSong!!.bookmarkPosition = 0 currentSong!!.bookmarkPosition = 0
Thread { Thread {
@ -782,6 +781,15 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
shareHandler.createShare(this, entries, null, cancellationToken) shareHandler.createShare(this, entries, null, cancellationToken)
return true return true
} }
R.id.menu_item_share_song -> {
if (currentSong == null) return true
val entries: MutableList<MusicDirectory.Entry?> = ArrayList()
entries.add(currentSong)
shareHandler.createShare(this, entries, null, cancellationToken)
return true
}
else -> return false else -> return false
} }
} }
@ -903,7 +911,9 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
onCurrentChanged() onCurrentChanged()
} }
}) })
emptyTextView.visibility = if (list.isEmpty()) View.VISIBLE else View.GONE
emptyTextView.isVisible = list.isEmpty()
currentRevision = mediaPlayerController.playListUpdateRevision currentRevision = mediaPlayerController.playListUpdateRevision
when (mediaPlayerController.repeatMode) { when (mediaPlayerController.repeatMode) {
RepeatMode.OFF -> repeatButton.setImageDrawable( RepeatMode.OFF -> repeatButton.setImageDrawable(
@ -1028,19 +1038,19 @@ class PlayerFragment : Fragment(), GestureDetector.OnGestureListener, KoinCompon
when (playerState) { when (playerState) {
PlayerState.STARTED -> { PlayerState.STARTED -> {
pauseButton.visibility = View.VISIBLE pauseButton.isVisible = true
stopButton.visibility = View.GONE stopButton.isVisible = false
startButton.visibility = View.GONE startButton.isVisible = false
} }
PlayerState.DOWNLOADING, PlayerState.PREPARING -> { PlayerState.DOWNLOADING, PlayerState.PREPARING -> {
pauseButton.visibility = View.GONE pauseButton.isVisible = false
stopButton.visibility = View.VISIBLE stopButton.isVisible = true
startButton.visibility = View.GONE startButton.isVisible = false
} }
else -> { else -> {
pauseButton.visibility = View.GONE pauseButton.isVisible = false
stopButton.visibility = View.GONE stopButton.isVisible = false
startButton.visibility = View.VISIBLE startButton.isVisible = true
} }
} }

View File

@ -7,6 +7,8 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.CheckBox import android.widget.CheckBox
import android.widget.EditText import android.widget.EditText
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import java.util.Locale import java.util.Locale
@ -31,9 +33,12 @@ import org.moire.ultrasonic.util.TimeSpanPicker
class ShareHandler(val context: Context) { class ShareHandler(val context: Context) {
private var shareDescription: EditText? = null private var shareDescription: EditText? = null
private var timeSpanPicker: TimeSpanPicker? = null private var timeSpanPicker: TimeSpanPicker? = null
private var shareOnServerCheckBox: CheckBox? = null
private var hideDialogCheckBox: CheckBox? = null private var hideDialogCheckBox: CheckBox? = null
private var noExpirationCheckBox: CheckBox? = null private var noExpirationCheckBox: CheckBox? = null
private var saveAsDefaultsCheckBox: CheckBox? = null private var saveAsDefaultsCheckBox: CheckBox? = null
private var textViewComment: TextView? = null
private var textViewExpiration: TextView? = null
private val pattern = Pattern.compile(":") private val pattern = Pattern.compile(":")
fun createShare( fun createShare(
@ -62,15 +67,17 @@ class ShareHandler(val context: Context) {
swipe: SwipeRefreshLayout?, swipe: SwipeRefreshLayout?,
cancellationToken: CancellationToken cancellationToken: CancellationToken
) { ) {
val task: BackgroundTask<Share> = object : FragmentBackgroundTask<Share>( val task: BackgroundTask<Share?> = object : FragmentBackgroundTask<Share?>(
fragment.requireActivity(), fragment.requireActivity(),
true, true,
swipe, swipe,
cancellationToken cancellationToken
) { ) {
@Throws(Throwable::class) @Throws(Throwable::class)
override fun doInBackground(): Share { override fun doInBackground(): Share? {
val ids: MutableList<String> = ArrayList() val ids: MutableList<String> = ArrayList()
if (!shareDetails.ShareOnServer && shareDetails.Entries.size == 1) return null
if (shareDetails.Entries.isEmpty()) { if (shareDetails.Entries.isEmpty()) {
fragment.arguments?.getString(Constants.INTENT_EXTRA_NAME_ID)?.let { fragment.arguments?.getString(Constants.INTENT_EXTRA_NAME_ID)?.let {
ids.add(it) ids.add(it)
@ -80,23 +87,51 @@ class ShareHandler(val context: Context) {
ids.add(id) ids.add(id)
} }
} }
val musicService = getMusicService() val musicService = getMusicService()
var timeInMillis: Long = 0 var timeInMillis: Long = 0
if (shareDetails.Expiration != 0L) { if (shareDetails.Expiration != 0L) {
timeInMillis = shareDetails.Expiration timeInMillis = shareDetails.Expiration
} }
val shares = val shares =
musicService.createShare(ids, shareDetails.Description, timeInMillis) musicService.createShare(ids, shareDetails.Description, timeInMillis)
return shares[0] return shares[0]
} }
override fun done(result: Share) { override fun done(result: Share?) {
val intent = Intent(Intent.ACTION_SEND) val intent = Intent(Intent.ACTION_SEND)
intent.type = "text/plain" intent.type = "text/plain"
intent.putExtra(
Intent.EXTRA_TEXT, if (result != null) {
String.format(Locale.ROOT, "%s\n\n%s", Settings.shareGreeting, result.url) // 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( fragment.activity?.startActivity(
Intent.createChooser( Intent.createChooser(
intent, intent,
@ -119,24 +154,45 @@ class ShareHandler(val context: Context) {
if (layout != null) { if (layout != null) {
shareDescription = layout.findViewById<View>(R.id.share_description) as EditText shareDescription = layout.findViewById<View>(R.id.share_description) as EditText
hideDialogCheckBox = layout.findViewById<View>(R.id.hide_dialog) as CheckBox hideDialogCheckBox = layout.findViewById<View>(R.id.hide_dialog) as CheckBox
shareOnServerCheckBox = layout.findViewById<View>(R.id.share_on_server) as CheckBox
noExpirationCheckBox = layout.findViewById<View>( noExpirationCheckBox = layout.findViewById<View>(
R.id.timeSpanDisableCheckBox R.id.timeSpanDisableCheckBox
) as CheckBox ) as CheckBox
saveAsDefaultsCheckBox = layout.findViewById<View>(R.id.save_as_defaults) as CheckBox saveAsDefaultsCheckBox = layout.findViewById<View>(R.id.save_as_defaults) as CheckBox
timeSpanPicker = layout.findViewById<View>(R.id.date_picker) as TimeSpanPicker timeSpanPicker = layout.findViewById<View>(R.id.date_picker) as TimeSpanPicker
textViewComment = layout.findViewById<View>(R.id.textViewComment) as TextView
textViewExpiration = layout.findViewById<View>(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) val builder = AlertDialog.Builder(fragment.context)
builder.setTitle(R.string.share_set_share_options) builder.setTitle(R.string.share_set_share_options)
builder.setPositiveButton(R.string.common_save) { _, _ ->
builder.setPositiveButton(R.string.menu_share) { _, _ ->
if (!noExpirationCheckBox!!.isChecked) { if (!noExpirationCheckBox!!.isChecked) {
val timeSpan: TimeSpan = timeSpanPicker!!.timeSpan val timeSpan: TimeSpan = timeSpanPicker!!.timeSpan
val now = TimeSpan.getCurrentTime() val now = TimeSpan.getCurrentTime()
shareDetails.Expiration = now.add(timeSpan).totalMilliseconds shareDetails.Expiration = now.add(timeSpan).totalMilliseconds
} }
shareDetails.Description = shareDescription!!.text.toString() shareDetails.Description = shareDescription!!.text.toString()
shareDetails.ShareOnServer = shareOnServerCheckBox!!.isChecked
if (hideDialogCheckBox!!.isChecked) { if (hideDialogCheckBox!!.isChecked) {
Settings.shouldAskForShareDetails = false Settings.shouldAskForShareDetails = false
} }
if (saveAsDefaultsCheckBox!!.isChecked) { if (saveAsDefaultsCheckBox!!.isChecked) {
val timeSpanType: String = timeSpanPicker!!.timeSpanType val timeSpanType: String = timeSpanPicker!!.timeSpanType
val timeSpanAmount: Int = timeSpanPicker!!.timeSpanAmount val timeSpanAmount: Int = timeSpanPicker!!.timeSpanAmount
@ -145,22 +201,29 @@ class ShareHandler(val context: Context) {
String.format("%d:%s", timeSpanAmount, timeSpanType) else "" String.format("%d:%s", timeSpanAmount, timeSpanType) else ""
Settings.defaultShareDescription = shareDetails.Description Settings.defaultShareDescription = shareDetails.Description
Settings.shareOnServer = shareDetails.ShareOnServer
} }
share(fragment, shareDetails, swipe, cancellationToken) share(fragment, shareDetails, swipe, cancellationToken)
} }
builder.setNegativeButton(R.string.common_cancel) { dialog, _ -> builder.setNegativeButton(R.string.common_cancel) { dialog, _ ->
dialog.cancel() dialog.cancel()
} }
builder.setView(layout) builder.setView(layout)
builder.setCancelable(true) builder.setCancelable(true)
timeSpanPicker!!.setTimeSpanDisableText(context.resources.getString(R.string.no_expiration)) timeSpanPicker!!.setTimeSpanDisableText(context.resources.getString(R.string.no_expiration))
noExpirationCheckBox!!.setOnCheckedChangeListener { noExpirationCheckBox!!.setOnCheckedChangeListener {
_, _,
b -> b ->
timeSpanPicker!!.isEnabled = !b timeSpanPicker!!.isEnabled = !b
} }
val defaultDescription = Settings.defaultShareDescription val defaultDescription = Settings.defaultShareDescription
val timeSpan = Settings.defaultShareExpiration val timeSpan = Settings.defaultShareExpiration
val split = pattern.split(timeSpan) val split = pattern.split(timeSpan)
if (split.size == 2) { if (split.size == 2) {
val timeSpanAmount = split[0].toInt() val timeSpanAmount = split[0].toInt()
@ -178,8 +241,25 @@ class ShareHandler(val context: Context) {
noExpirationCheckBox!!.isChecked = true noExpirationCheckBox!!.isChecked = true
timeSpanPicker!!.isEnabled = false timeSpanPicker!!.isEnabled = false
} }
shareDescription!!.setText(defaultDescription) shareDescription!!.setText(defaultDescription)
builder.create() builder.create()
builder.show() 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
}
}
} }

View File

@ -105,6 +105,7 @@ object Constants {
const val PREFERENCES_KEY_ASK_FOR_SHARE_DETAILS = "sharingAlwaysAskForDetails" const val PREFERENCES_KEY_ASK_FOR_SHARE_DETAILS = "sharingAlwaysAskForDetails"
const val PREFERENCES_KEY_DEFAULT_SHARE_DESCRIPTION = "sharingDefaultDescription" const val PREFERENCES_KEY_DEFAULT_SHARE_DESCRIPTION = "sharingDefaultDescription"
const val PREFERENCES_KEY_DEFAULT_SHARE_GREETING = "sharingDefaultGreeting" const val PREFERENCES_KEY_DEFAULT_SHARE_GREETING = "sharingDefaultGreeting"
const val PREFERENCES_KEY_SHARE_ON_SERVER = "sharingCreateOnServer"
const val PREFERENCES_KEY_DEFAULT_SHARE_EXPIRATION = "sharingDefaultExpiration" const val PREFERENCES_KEY_DEFAULT_SHARE_EXPIRATION = "sharingDefaultExpiration"
const val PREFERENCES_KEY_SHOW_ALL_SONGS_BY_ARTIST = "showAllSongsByArtist" const val PREFERENCES_KEY_SHOW_ALL_SONGS_BY_ARTIST = "showAllSongsByArtist"
const val PREFERENCES_KEY_USE_FIVE_STAR_RATING = "use_five_star_rating" const val PREFERENCES_KEY_USE_FIVE_STAR_RATING = "use_five_star_rating"

View File

@ -376,6 +376,21 @@ object Settings {
) )
} }
var shareOnServer: Boolean
get() {
val preferences = preferences
return preferences.getBoolean(Constants.PREFERENCES_KEY_SHARE_ON_SERVER, true)!!
}
set(shareOnServer) {
val preferences = preferences
val editor = preferences.edit()
editor.putBoolean(
Constants.PREFERENCES_KEY_SHARE_ON_SERVER,
shareOnServer
)
editor.apply()
}
var defaultShareExpiration: String var defaultShareExpiration: String
get() { get() {
val preferences = preferences val preferences = preferences

View File

@ -10,6 +10,14 @@
a:layout_width="wrap_content" a:layout_width="wrap_content"
a:layout_height="wrap_content"> a:layout_height="wrap_content">
<CheckBox
a:id="@+id/share_on_server"
a:text="@string/share_on_server"
a:layout_width="wrap_content"
a:layout_height="wrap_content"
a:layout_marginTop="4dip"
a:layout_marginBottom="4dip" />
<TextView <TextView
a:layout_width="wrap_content" a:layout_width="wrap_content"
a:layout_height="wrap_content" a:layout_height="wrap_content"

View File

@ -14,6 +14,11 @@
a:icon="?attr/star_hollow" a:icon="?attr/star_hollow"
app:showAsAction="ifRoom|withText" app:showAsAction="ifRoom|withText"
a:title="@string/download.menu_star"/> a:title="@string/download.menu_star"/>
<item
a:id="@+id/menu_item_share_song"
a:icon="?attr/share"
app:showAsAction="ifRoom|withText"
a:title="@string/download.share_song"/>
<item <item
a:id="@+id/menu_item_share" a:id="@+id/menu_item_share"
a:icon="?attr/share" a:icon="?attr/share"

View File

@ -28,7 +28,9 @@
<string name="button_bar.playlists">Playlists</string> <string name="button_bar.playlists">Playlists</string>
<string name="button_bar.search">Search</string> <string name="button_bar.search">Search</string>
<string name="chat.send_a_message">Send a message</string> <string name="chat.send_a_message">Send a message</string>
<string name="common.album">Album</string>
<string name="common.appname">Ultrasonic</string> <string name="common.appname">Ultrasonic</string>
<string name="common.artist">Artist</string>
<string name="common.cancel">Cancel</string> <string name="common.cancel">Cancel</string>
<string name="common.comment">Comment</string> <string name="common.comment">Comment</string>
<string name="common.confirm">Confirm</string> <string name="common.confirm">Confirm</string>
@ -48,6 +50,7 @@
<string name="common.play_shuffled">Play Shuffled</string> <string name="common.play_shuffled">Play Shuffled</string>
<string name="common.public">Public</string> <string name="common.public">Public</string>
<string name="common.save">Save</string> <string name="common.save">Save</string>
<string name="common.title">Title</string>
<string name="common.unpin">Unpin</string> <string name="common.unpin">Unpin</string>
<string name="common.various_artists">Various Artists</string> <string name="common.various_artists">Various Artists</string>
<string name="delete_playlist">Do you want to delete %1$s</string> <string name="delete_playlist">Do you want to delete %1$s</string>
@ -350,11 +353,13 @@
<string name="widget.sdcard_missing">No SD card</string> <string name="widget.sdcard_missing">No SD card</string>
<string name="settings.share_description_default">Default Share Description</string> <string name="settings.share_description_default">Default Share Description</string>
<string name="settings.sharing_title">Sharing</string> <string name="settings.sharing_title">Sharing</string>
<string name="settings.sharing_always_ask_for_details_summary">Always ask for description and expiration when creating a share</string> <string name="settings.sharing_always_ask_for_details_summary">Always ask for description and expiration when creating a share on the server</string>
<string name="settings.sharing_always_ask_for_details">Always Ask For Details</string> <string name="settings.sharing_always_ask_for_details">Always Ask For Details</string>
<string name="settings.share_expiration_default">Default Expiration Time</string> <string name="settings.share_expiration_default">Default Expiration Time</string>
<string name="do_not_show_dialog_again">Do not show dialog again</string> <string name="do_not_show_dialog_again">Do not show dialog again</string>
<string name="share_set_share_options">Set Share Options</string> <string name="share_set_share_options">Set Share Options</string>
<string name="share_on_server">Create share on the server</string>
<string name="settings.share_on_server_summary">Sharing will create a share on the server and share its URL. If disabled, only the song details are shared</string>
<string name="no_expiration">No Expiration</string> <string name="no_expiration">No Expiration</string>
<string name="download.toggle_playlist">Toggle Playlist</string> <string name="download.toggle_playlist">Toggle Playlist</string>
<string name="download.bookmark_set">Set Bookmark</string> <string name="download.bookmark_set">Set Bookmark</string>
@ -377,6 +382,7 @@
<string name="settings.share_expiration">Time To Expiration</string> <string name="settings.share_expiration">Time To Expiration</string>
<string name="download_song_removed">\"%s\" was removed from playlist</string> <string name="download_song_removed">\"%s\" was removed from playlist</string>
<string name="download.share_playlist">Share Playlist</string> <string name="download.share_playlist">Share Playlist</string>
<string name="download.share_song">Share Current Song</string>
<string name="settings.share_greeting_default">Default Share Greeting</string> <string name="settings.share_greeting_default">Default Share Greeting</string>
<string name="share_default_greeting">Check out this music I shared from %s</string> <string name="share_default_greeting">Check out this music I shared from %s</string>
<string name="share_via">Share songs via</string> <string name="share_via">Share songs via</string>

View File

@ -189,18 +189,15 @@
<PreferenceCategory <PreferenceCategory
a:title="@string/settings.sharing_title" a:title="@string/settings.sharing_title"
app:iconSpaceReserved="false"> app:iconSpaceReserved="false">
<EditTextPreference
a:key="sharingDefaultDescription"
a:title="@string/settings.share_description_default"
app:iconSpaceReserved="false"/>
<EditTextPreference <EditTextPreference
a:key="sharingDefaultGreeting" a:key="sharingDefaultGreeting"
a:title="@string/settings.share_greeting_default" a:title="@string/settings.share_greeting_default"
app:iconSpaceReserved="false"/> app:iconSpaceReserved="false"/>
<org.moire.ultrasonic.util.TimeSpanPreference <CheckBoxPreference
a:defaultValue="0" a:defaultValue="true"
a:key="sharingDefaultExpiration" a:key="sharingCreateOnServer"
a:title="@string/settings.share_expiration_default" a:title="@string/share_on_server"
a:summary="@string/settings.share_on_server_summary"
app:iconSpaceReserved="false"/> app:iconSpaceReserved="false"/>
<CheckBoxPreference <CheckBoxPreference
a:defaultValue="true" a:defaultValue="true"
@ -208,6 +205,15 @@
a:summary="@string/settings.sharing_always_ask_for_details_summary" a:summary="@string/settings.sharing_always_ask_for_details_summary"
a:title="@string/settings.sharing_always_ask_for_details" a:title="@string/settings.sharing_always_ask_for_details"
app:iconSpaceReserved="false"/> app:iconSpaceReserved="false"/>
<EditTextPreference
a:key="sharingDefaultDescription"
a:title="@string/settings.share_description_default"
app:iconSpaceReserved="false"/>
<org.moire.ultrasonic.util.TimeSpanPreference
a:defaultValue="0"
a:key="sharingDefaultExpiration"
a:title="@string/settings.share_expiration_default"
app:iconSpaceReserved="false"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory
a:title="@string/settings.network_title" a:title="@string/settings.network_title"