Update license
This commit is contained in:
parent
0f22127a12
commit
211db34142
2 changed files with 365 additions and 176 deletions
184
AUTHORS
Normal file
184
AUTHORS
Normal file
|
@ -0,0 +1,184 @@
|
|||
# List of authors of Husky
|
||||
|
||||
Current maintainer: Adolfo Santiago (captainepoch)
|
||||
|
||||
# All of the contributors to Tusky and Husky
|
||||
#
|
||||
# This list was retrived from the original Husky repository. If someone is
|
||||
# missing or you want to add or change something, send an email to the
|
||||
# project's mailist.
|
||||
Aditoo
|
||||
Aditoo17
|
||||
Akarshan Biswas
|
||||
Alibek Omarov (a1batross)
|
||||
Alice Heart
|
||||
Allysson Samuel Amorim Vaz Cunha
|
||||
Alperen
|
||||
Anna e só
|
||||
Anonymous
|
||||
Artur Mancha
|
||||
BOSCH, Cedric
|
||||
Balasankar C
|
||||
Basix
|
||||
Ben
|
||||
Bernd
|
||||
Billy Brawner
|
||||
Boced66
|
||||
Briar Rose Schreiber
|
||||
ButterflyOfFire
|
||||
Caleb Maclennan
|
||||
Christian Paul
|
||||
Conny Duck
|
||||
Connyduck
|
||||
Conor Flynn
|
||||
Constantin A
|
||||
Criss
|
||||
CryptKiddie
|
||||
Dani
|
||||
Danial Behzadi
|
||||
Daniele Lira Mereb
|
||||
David Teresi
|
||||
Dryusdan
|
||||
Elarcis
|
||||
Elias Mårtenson
|
||||
Eugen
|
||||
Eugen Rochko
|
||||
Evgeny
|
||||
Evgeny Petrov
|
||||
FeiYang
|
||||
FlameArche
|
||||
Francesc Galí
|
||||
Frieder Bluemle
|
||||
Gareth Murphy
|
||||
Garrit Franke
|
||||
Gian Sass
|
||||
Gyuhwan Park
|
||||
Hararan
|
||||
HellPie
|
||||
Henri Gourvest
|
||||
INAGAKI Hiroshi
|
||||
Isak Alexander
|
||||
Isak Holmström
|
||||
Ivan Kupalov
|
||||
Jan Boddez
|
||||
Jeong Arm
|
||||
Jeroen
|
||||
Joan Montané
|
||||
Johannes Barre
|
||||
Juanjo Salvador
|
||||
Karol Kosek
|
||||
Kazuki KANDA
|
||||
Konrad Pozniak
|
||||
Koyu Berteon
|
||||
Kristijan Tkalec
|
||||
Krzysztof Jurewicz
|
||||
Kyle Sunden
|
||||
Kévin Commaille
|
||||
Len Chan
|
||||
Levi Bard
|
||||
Manimaran.K
|
||||
Marcin Mikołajczak
|
||||
Marie Axelsson
|
||||
Markel @wakutiteo
|
||||
Mary
|
||||
Michel
|
||||
Mickson
|
||||
Mihai Boisteanu
|
||||
Mike Barnes
|
||||
Mitchell Hentges
|
||||
Mostafa Ahangarha
|
||||
Muha Aliss
|
||||
MzA
|
||||
Mélanie Chauvel
|
||||
Mélanie Chauvel (ariasuni)
|
||||
Neville Park
|
||||
Nicholas Tinsley
|
||||
Noah Akers
|
||||
Ondřej Hruška
|
||||
Pangoraw
|
||||
Paul
|
||||
Pellaeon Lin
|
||||
Peter Cai
|
||||
PhotonQyv
|
||||
Poulpette
|
||||
Prat
|
||||
Quentí
|
||||
Quim Gil
|
||||
Raphael Michel
|
||||
Repu
|
||||
Ryu jongheon
|
||||
Sandor Teglasy
|
||||
Selyan Slimane Amiri
|
||||
Serage(pl)
|
||||
Sergio López
|
||||
Serkan Cık
|
||||
Sojo
|
||||
Subin Siby
|
||||
Sveinn í Felli
|
||||
Sylke Vicious
|
||||
Sylvia van Os
|
||||
Thomas Citharel
|
||||
Tibike Miklós
|
||||
Tryton Van Meer
|
||||
Unai Tolosa Pontesta
|
||||
Vavassor
|
||||
Vegard Skjefstad
|
||||
Vignesh Kumar
|
||||
Vivianne
|
||||
Weblate
|
||||
Wesley Ellis
|
||||
Yaroslav
|
||||
Zachary Epps
|
||||
Zoltán Gera
|
||||
aka-rin
|
||||
ati3
|
||||
autumnontape
|
||||
charlag
|
||||
dadosch
|
||||
dani
|
||||
daycode
|
||||
dimqua
|
||||
duggalsu
|
||||
eleete0712
|
||||
flyingrub
|
||||
freetux
|
||||
goofy-bz
|
||||
hg
|
||||
in_dow
|
||||
jchmrt
|
||||
jeroenpraat
|
||||
jma
|
||||
knuxify
|
||||
koyu
|
||||
kyori
|
||||
kyori19
|
||||
lenchan139
|
||||
lindwurm
|
||||
littlebelgianwriter
|
||||
m4sk1n
|
||||
marcin mikołajczak
|
||||
mewmew
|
||||
mike castleman
|
||||
mr.bumper Gonzalez perez
|
||||
mynameismonkey
|
||||
nailyk
|
||||
nailyk-fr
|
||||
nailyk-weblate
|
||||
nora
|
||||
nore715
|
||||
ntngrtltr
|
||||
orimpe
|
||||
pandasoft0
|
||||
qwazix
|
||||
remi6397
|
||||
serage.betelmal
|
||||
simevo
|
||||
tolstoevsky
|
||||
torrentcome
|
||||
toumi
|
||||
tsdgeos
|
||||
uckfayer
|
||||
vala
|
||||
zital
|
||||
Óliver García Albertos
|
||||
Хлеп
|
|
@ -1,17 +1,22 @@
|
|||
/* Copyright 2017 Andrew Dawson
|
||||
/*
|
||||
* Husky -- A Pleroma client for Android
|
||||
*
|
||||
* This file is a part of Tusky.
|
||||
* Copyright (C) 2021 The Husky Developers
|
||||
* Copyright (C) 2017 Andrew Dawson
|
||||
*
|
||||
* This program 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 program 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.
|
||||
*
|
||||
* Tusky 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.
|
||||
* This program 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Tusky; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.keylesspalace.tusky.fragment
|
||||
|
||||
|
@ -44,202 +49,202 @@ import timber.log.Timber
|
|||
|
||||
class ViewVideoFragment : ViewMediaFragment() {
|
||||
|
||||
private lateinit var toolbar: View
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
private val hideToolbar = Runnable {
|
||||
// Hoist toolbar hiding to activity so it can track state across different fragments
|
||||
// This is explicitly stored as runnable so that we pass it to the handler later for cancellation
|
||||
mediaActivity.onPhotoTap()
|
||||
mediaController.hide()
|
||||
}
|
||||
private lateinit var mediaActivity: ViewMediaActivity
|
||||
private val TOOLBAR_HIDE_DELAY_MS = 3000L
|
||||
private lateinit var mediaController: MediaController
|
||||
private var isAudio = false
|
||||
private lateinit var toolbar: View
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
private val hideToolbar = Runnable {
|
||||
// Hoist toolbar hiding to activity so it can track state across different fragments
|
||||
// This is explicitly stored as runnable so that we pass it to the handler later for cancellation
|
||||
mediaActivity.onPhotoTap()
|
||||
mediaController.hide()
|
||||
}
|
||||
private lateinit var mediaActivity: ViewMediaActivity
|
||||
private val TOOLBAR_HIDE_DELAY_MS = 3000L
|
||||
private lateinit var mediaController: MediaController
|
||||
private var isAudio = false
|
||||
|
||||
private var exoPlayer: SimpleExoPlayer? = null
|
||||
private val playbackStateListener: Player.Listener = playbackStateListener()
|
||||
private var playWhenReady = true
|
||||
private var currentWindow = 0
|
||||
private var playbackPosition = 0L
|
||||
private var exoPlayer: SimpleExoPlayer? = null
|
||||
private val playbackStateListener: Player.Listener = playbackStateListener()
|
||||
private var playWhenReady = true
|
||||
private var currentWindow = 0
|
||||
private var playbackPosition = 0L
|
||||
|
||||
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
|
||||
// Start/pause/resume video playback as fragment is shown/hidden
|
||||
super.setUserVisibleHint(isVisibleToUser)
|
||||
override fun setUserVisibleHint(isVisibleToUser: Boolean) {
|
||||
// Start/pause/resume video playback as fragment is shown/hidden
|
||||
super.setUserVisibleHint(isVisibleToUser)
|
||||
|
||||
if(videoView == null) {
|
||||
return
|
||||
}
|
||||
if(videoView == null) {
|
||||
return
|
||||
}
|
||||
|
||||
if(isVisibleToUser) {
|
||||
if(mediaActivity.isToolbarVisible) {
|
||||
handler.postDelayed(hideToolbar, TOOLBAR_HIDE_DELAY_MS)
|
||||
}
|
||||
exoPlayer?.play()
|
||||
} else {
|
||||
handler.removeCallbacks(hideToolbar)
|
||||
exoPlayer?.pause()
|
||||
mediaController.hide()
|
||||
}
|
||||
}
|
||||
if(isVisibleToUser) {
|
||||
if(mediaActivity.isToolbarVisible) {
|
||||
handler.postDelayed(hideToolbar, TOOLBAR_HIDE_DELAY_MS)
|
||||
}
|
||||
exoPlayer?.play()
|
||||
} else {
|
||||
handler.removeCallbacks(hideToolbar)
|
||||
exoPlayer?.pause()
|
||||
mediaController.hide()
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun setupMediaView(
|
||||
url: String,
|
||||
previewUrl: String?,
|
||||
description: String?,
|
||||
showingDescription: Boolean
|
||||
) {
|
||||
mediaDescription.text = description
|
||||
mediaDescription.visible(showingDescription)
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun setupMediaView(
|
||||
url: String,
|
||||
previewUrl: String?,
|
||||
description: String?,
|
||||
showingDescription: Boolean
|
||||
) {
|
||||
mediaDescription.text = description
|
||||
mediaDescription.visible(showingDescription)
|
||||
|
||||
videoView.transitionName = url
|
||||
mediaController = object : MediaController(mediaActivity) {
|
||||
override fun show(timeout: Int) {
|
||||
// We're doing manual auto-close management.
|
||||
// Also, take focus back from the pause button so we can use the back button.
|
||||
super.show(0)
|
||||
mediaController.requestFocus()
|
||||
}
|
||||
videoView.transitionName = url
|
||||
mediaController = object : MediaController(mediaActivity) {
|
||||
override fun show(timeout: Int) {
|
||||
// We're doing manual auto-close management.
|
||||
// Also, take focus back from the pause button so we can use the back button.
|
||||
super.show(0)
|
||||
mediaController.requestFocus()
|
||||
}
|
||||
|
||||
override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
|
||||
if(event?.keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
if(event.action == KeyEvent.ACTION_UP) {
|
||||
hide()
|
||||
activity?.supportFinishAfterTransition()
|
||||
}
|
||||
return true
|
||||
}
|
||||
return super.dispatchKeyEvent(event)
|
||||
}
|
||||
}
|
||||
override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
|
||||
if(event?.keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
if(event.action == KeyEvent.ACTION_UP) {
|
||||
hide()
|
||||
activity?.supportFinishAfterTransition()
|
||||
}
|
||||
return true
|
||||
}
|
||||
return super.dispatchKeyEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
val trackSelector = DefaultTrackSelector(requireActivity()).apply {
|
||||
setParameters(buildUponParameters().setMaxVideoSizeSd())
|
||||
}
|
||||
val trackSelector = DefaultTrackSelector(requireActivity()).apply {
|
||||
setParameters(buildUponParameters().setMaxVideoSizeSd())
|
||||
}
|
||||
|
||||
exoPlayer = SimpleExoPlayer.Builder(requireActivity())
|
||||
.setTrackSelector(trackSelector)
|
||||
.build()
|
||||
.also { player ->
|
||||
videoView.player = player
|
||||
exoPlayer = SimpleExoPlayer.Builder(requireActivity())
|
||||
.setTrackSelector(trackSelector)
|
||||
.build()
|
||||
.also { player ->
|
||||
videoView.player = player
|
||||
|
||||
val mediaItem = MediaItem.Builder()
|
||||
.setUri(Uri.parse(url))
|
||||
.build()
|
||||
player.setMediaItem(mediaItem)
|
||||
val mediaItem = MediaItem.Builder()
|
||||
.setUri(Uri.parse(url))
|
||||
.build()
|
||||
player.setMediaItem(mediaItem)
|
||||
|
||||
player.addListener(playbackStateListener)
|
||||
player.seekTo(currentWindow, playbackPosition)
|
||||
player.playWhenReady = playWhenReady
|
||||
player.addListener(playbackStateListener)
|
||||
player.seekTo(currentWindow, playbackPosition)
|
||||
player.playWhenReady = playWhenReady
|
||||
|
||||
player.prepare()
|
||||
}
|
||||
player.prepare()
|
||||
}
|
||||
|
||||
videoView.requestFocus()
|
||||
videoView.requestFocus()
|
||||
|
||||
if(arguments!!.getBoolean(ARG_START_POSTPONED_TRANSITION)) {
|
||||
mediaActivity.onBringUp()
|
||||
}
|
||||
}
|
||||
if(arguments!!.getBoolean(ARG_START_POSTPONED_TRANSITION)) {
|
||||
mediaActivity.onBringUp()
|
||||
}
|
||||
}
|
||||
|
||||
private fun hideToolbarAfterDelay(delayMilliseconds: Long) {
|
||||
handler.postDelayed(hideToolbar, delayMilliseconds)
|
||||
}
|
||||
private fun hideToolbarAfterDelay(delayMilliseconds: Long) {
|
||||
handler.postDelayed(hideToolbar, delayMilliseconds)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
toolbar = activity!!.toolbar
|
||||
mediaActivity = activity as ViewMediaActivity
|
||||
return inflater.inflate(R.layout.fragment_view_video, container, false)
|
||||
}
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
toolbar = activity!!.toolbar
|
||||
mediaActivity = activity as ViewMediaActivity
|
||||
return inflater.inflate(R.layout.fragment_view_video, container, false)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
||||
val attachment = arguments?.getParcelable<Attachment>(ARG_ATTACHMENT)
|
||||
?: throw IllegalArgumentException("attachment has to be set")
|
||||
val attachment = arguments?.getParcelable<Attachment>(ARG_ATTACHMENT)
|
||||
?: throw IllegalArgumentException("attachment has to be set")
|
||||
|
||||
isAudio = (attachment.type == Attachment.Type.AUDIO)
|
||||
finalizeViewSetup(attachment.url, attachment.previewUrl, attachment.description)
|
||||
}
|
||||
isAudio = (attachment.type == Attachment.Type.AUDIO)
|
||||
finalizeViewSetup(attachment.url, attachment.previewUrl, attachment.description)
|
||||
}
|
||||
|
||||
override fun onToolbarVisibilityChange(visible: Boolean) {
|
||||
if(videoView == null || mediaDescription == null || !userVisibleHint) {
|
||||
return
|
||||
}
|
||||
override fun onToolbarVisibilityChange(visible: Boolean) {
|
||||
if(videoView == null || mediaDescription == null || !userVisibleHint) {
|
||||
return
|
||||
}
|
||||
|
||||
isDescriptionVisible = showingDescription && visible
|
||||
val alpha = if(isDescriptionVisible) 1.0f else 0.0f
|
||||
if(isDescriptionVisible) {
|
||||
// If to be visible, need to make visible immediately and animate alpha
|
||||
mediaDescription.alpha = 0.0f
|
||||
mediaDescription.visible(isDescriptionVisible)
|
||||
}
|
||||
isDescriptionVisible = showingDescription && visible
|
||||
val alpha = if(isDescriptionVisible) 1.0f else 0.0f
|
||||
if(isDescriptionVisible) {
|
||||
// If to be visible, need to make visible immediately and animate alpha
|
||||
mediaDescription.alpha = 0.0f
|
||||
mediaDescription.visible(isDescriptionVisible)
|
||||
}
|
||||
|
||||
mediaDescription.animate().alpha(alpha)
|
||||
.setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
mediaDescription?.visible(isDescriptionVisible)
|
||||
animation.removeListener(this)
|
||||
}
|
||||
})
|
||||
.start()
|
||||
mediaDescription.animate().alpha(alpha)
|
||||
.setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
mediaDescription?.visible(isDescriptionVisible)
|
||||
animation.removeListener(this)
|
||||
}
|
||||
})
|
||||
.start()
|
||||
|
||||
if(visible && (videoView.player?.isPlaying == true) && !isAudio) {
|
||||
hideToolbarAfterDelay(TOOLBAR_HIDE_DELAY_MS)
|
||||
} else {
|
||||
handler.removeCallbacks(hideToolbar)
|
||||
}
|
||||
}
|
||||
if(visible && (videoView.player?.isPlaying == true) && !isAudio) {
|
||||
hideToolbarAfterDelay(TOOLBAR_HIDE_DELAY_MS)
|
||||
} else {
|
||||
handler.removeCallbacks(hideToolbar)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTransitionEnd() {
|
||||
}
|
||||
override fun onTransitionEnd() {
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
|
||||
releasePlayer()
|
||||
}
|
||||
releasePlayer()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
|
||||
releasePlayer()
|
||||
}
|
||||
releasePlayer()
|
||||
}
|
||||
|
||||
private fun releasePlayer() {
|
||||
exoPlayer?.run {
|
||||
playbackPosition = this.currentPosition
|
||||
currentWindow = this.currentWindowIndex
|
||||
playWhenReady = this.playWhenReady
|
||||
removeListener(playbackStateListener)
|
||||
release()
|
||||
}
|
||||
exoPlayer = null
|
||||
}
|
||||
private fun releasePlayer() {
|
||||
exoPlayer?.run {
|
||||
playbackPosition = this.currentPosition
|
||||
currentWindow = this.currentWindowIndex
|
||||
playWhenReady = this.playWhenReady
|
||||
removeListener(playbackStateListener)
|
||||
release()
|
||||
}
|
||||
exoPlayer = null
|
||||
}
|
||||
|
||||
private fun playbackStateListener() = object : Player.Listener {
|
||||
private fun playbackStateListener() = object : Player.Listener {
|
||||
|
||||
override fun onPlaybackStateChanged(playbackState: Int) {
|
||||
when(playbackState) {
|
||||
Player.STATE_BUFFERING -> {
|
||||
progressBar.visibility = View.VISIBLE
|
||||
}
|
||||
Player.STATE_READY,
|
||||
Player.STATE_ENDED -> {
|
||||
progressBar.visibility = View.GONE
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
override fun onPlaybackStateChanged(playbackState: Int) {
|
||||
when(playbackState) {
|
||||
Player.STATE_BUFFERING -> {
|
||||
progressBar.visibility = View.VISIBLE
|
||||
}
|
||||
Player.STATE_READY,
|
||||
Player.STATE_ENDED -> {
|
||||
progressBar.visibility = View.GONE
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPlayerError(error: PlaybackException) {
|
||||
Timber.e(error.errorCodeName)
|
||||
}
|
||||
}
|
||||
override fun onPlayerError(error: PlaybackException) {
|
||||
Timber.e(error.errorCodeName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue