Release v1.0.38 (#174)

* Translated using Weblate (Italian)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/it/

* Translated using Weblate (Chinese (Simplified))

Currently translated at 38.7% (125 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/zh_Hans/

* Translated using Weblate (French)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/fr/

* Translated using Weblate (Chinese (Simplified))

Currently translated at 48.0% (155 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/zh_Hans/

* Translated using Weblate (German)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/de/

* Translated using Weblate (French)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/fr/

* Translated using Weblate (Russian)

Currently translated at 99.3% (321 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/ru/

* Translated using Weblate (Russian)

Currently translated at 99.3% (321 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/ru/

* Translated using Weblate (Bengali)

Currently translated at 99.3% (321 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Spanish)

Currently translated at 42.1% (136 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/es/

* Translated using Weblate (Bengali)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Persian)

Currently translated at 40.2% (130 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/fa/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Polish)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/pl/

* Translated using Weblate (Polish)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/pl/

* Translated using Weblate (Russian)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/ru/

* update library and more (#160)

* download files with friendly name (not video ID)

* Update Picasso library
FIX : add extension in downloaded filename.
download files with friendly name (not video ID)

* Update Gradle
Add 0.75x and 1.25x to play speed

* Release v1.0.35

* try to fix 'cannot make a new request because the previous response ... ' error (#164)

* Translations (#163)

* Translated using Weblate (Italian)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/it/

* Translated using Weblate (Chinese (Simplified))

Currently translated at 38.7% (125 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/zh_Hans/

* Translated using Weblate (French)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/fr/

* Translated using Weblate (Chinese (Simplified))

Currently translated at 48.0% (155 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/zh_Hans/

* Translated using Weblate (German)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/de/

* Translated using Weblate (French)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/fr/

* Translated using Weblate (Russian)

Currently translated at 99.3% (321 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/ru/

* Translated using Weblate (Russian)

Currently translated at 99.3% (321 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/ru/

* Translated using Weblate (Bengali)

Currently translated at 99.3% (321 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Spanish)

Currently translated at 42.1% (136 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/es/

* Translated using Weblate (Bengali)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Persian)

Currently translated at 40.2% (130 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/fa/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Polish)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/pl/

* Translated using Weblate (Polish)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/pl/

* Translated using Weblate (Russian)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/ru/

* update library and more (#160)

* download files with friendly name (not video ID)

* Update Picasso library
FIX : add extension in downloaded filename.
download files with friendly name (not video ID)

* Update Gradle
Add 0.75x and 1.25x to play speed

* Release v1.0.35

Co-authored-by: Michael Moroni <michaelmoroni@disroot.org>
Co-authored-by: mostkai <admin@pwplayer.com>
Co-authored-by: B0pol <bopol@e.email>
Co-authored-by: Jeannette L <j.lavoie@net-c.ca>
Co-authored-by: Nathan <bonnemainsnathan@gmail.com>
Co-authored-by: Mihail Iosilevitch <yosik@tutanota.com>
Co-authored-by: anonymous <noreply@weblate.org>
Co-authored-by: Oymate <dhruboadittya96@gmail.com>
Co-authored-by: Juanro49 <juanrobertogarciasanchez@gmail.com>
Co-authored-by: Mostafa Ahangarha <ahangarha@gmail.com>
Co-authored-by: Szylu <chipolade@gmail.com>
Co-authored-by: Artem <KovalevArtem.ru@gmail.com>
Co-authored-by: jmgfr <13685004+jmgfr@users.noreply.github.com>
Co-authored-by: Stefan Schueller <sschueller@nunight.com>

* try to fix 'cannot make a new request because the previous response is still open' when login.

Co-authored-by: Stefan Schüller <sschueller@techdroid.com>
Co-authored-by: Michael Moroni <michaelmoroni@disroot.org>
Co-authored-by: mostkai <admin@pwplayer.com>
Co-authored-by: B0pol <bopol@e.email>
Co-authored-by: Jeannette L <j.lavoie@net-c.ca>
Co-authored-by: Nathan <bonnemainsnathan@gmail.com>
Co-authored-by: Mihail Iosilevitch <yosik@tutanota.com>
Co-authored-by: anonymous <noreply@weblate.org>
Co-authored-by: Oymate <dhruboadittya96@gmail.com>
Co-authored-by: Juanro49 <juanrobertogarciasanchez@gmail.com>
Co-authored-by: Mostafa Ahangarha <ahangarha@gmail.com>
Co-authored-by: Szylu <chipolade@gmail.com>
Co-authored-by: Artem <KovalevArtem.ru@gmail.com>
Co-authored-by: jmgfr <13685004+jmgfr@users.noreply.github.com>
Co-authored-by: Stefan Schueller <sschueller@nunight.com>

* Release 1.0.36

* Translated using Weblate (Arabic)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/ar/

* Translated using Weblate (French)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/fr/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/nl/

* Translated using Weblate (Chinese (Traditional))

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/zh_Hant/

* Translated using Weblate (Polish)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/pl/

* Translated using Weblate (Italian)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/it/

* Master (#170)

* Translations (#163)

* Translated using Weblate (Italian)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/it/

* Translated using Weblate (Chinese (Simplified))

Currently translated at 38.7% (125 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/zh_Hans/

* Translated using Weblate (French)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/fr/

* Translated using Weblate (Chinese (Simplified))

Currently translated at 48.0% (155 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/zh_Hans/

* Translated using Weblate (German)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/de/

* Translated using Weblate (French)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/fr/

* Translated using Weblate (Russian)

Currently translated at 99.3% (321 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/ru/

* Translated using Weblate (Russian)

Currently translated at 99.3% (321 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/ru/

* Translated using Weblate (Bengali)

Currently translated at 99.3% (321 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Spanish)

Currently translated at 42.1% (136 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/es/

* Translated using Weblate (Bengali)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Persian)

Currently translated at 40.2% (130 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/fa/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Polish)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/pl/

* Translated using Weblate (Polish)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/pl/

* Translated using Weblate (Russian)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/ru/

* update library and more (#160)

* download files with friendly name (not video ID)

* Update Picasso library
FIX : add extension in downloaded filename.
download files with friendly name (not video ID)

* Update Gradle
Add 0.75x and 1.25x to play speed

* Release v1.0.35

Co-authored-by: Michael Moroni <michaelmoroni@disroot.org>
Co-authored-by: mostkai <admin@pwplayer.com>
Co-authored-by: B0pol <bopol@e.email>
Co-authored-by: Jeannette L <j.lavoie@net-c.ca>
Co-authored-by: Nathan <bonnemainsnathan@gmail.com>
Co-authored-by: Mihail Iosilevitch <yosik@tutanota.com>
Co-authored-by: anonymous <noreply@weblate.org>
Co-authored-by: Oymate <dhruboadittya96@gmail.com>
Co-authored-by: Juanro49 <juanrobertogarciasanchez@gmail.com>
Co-authored-by: Mostafa Ahangarha <ahangarha@gmail.com>
Co-authored-by: Szylu <chipolade@gmail.com>
Co-authored-by: Artem <KovalevArtem.ru@gmail.com>
Co-authored-by: jmgfr <13685004+jmgfr@users.noreply.github.com>
Co-authored-by: Stefan Schueller <sschueller@nunight.com>

* Release 1.0.36 (#166)

* Translated using Weblate (Italian)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/it/

* Translated using Weblate (Chinese (Simplified))

Currently translated at 38.7% (125 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/zh_Hans/

* Translated using Weblate (French)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/fr/

* Translated using Weblate (Chinese (Simplified))

Currently translated at 48.0% (155 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/zh_Hans/

* Translated using Weblate (German)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/de/

* Translated using Weblate (French)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/fr/

* Translated using Weblate (Russian)

Currently translated at 99.3% (321 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/ru/

* Translated using Weblate (Russian)

Currently translated at 99.3% (321 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/ru/

* Translated using Weblate (Bengali)

Currently translated at 99.3% (321 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Spanish)

Currently translated at 42.1% (136 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/es/

* Translated using Weblate (Bengali)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Persian)

Currently translated at 40.2% (130 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/fa/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Polish)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/pl/

* Translated using Weblate (Polish)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/pl/

* Translated using Weblate (Russian)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/ru/

* update library and more (#160)

* download files with friendly name (not video ID)

* Update Picasso library
FIX : add extension in downloaded filename.
download files with friendly name (not video ID)

* Update Gradle
Add 0.75x and 1.25x to play speed

* Release v1.0.35

* try to fix 'cannot make a new request because the previous response ... ' error (#164)

* Translations (#163)

* Translated using Weblate (Italian)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/it/

* Translated using Weblate (Chinese (Simplified))

Currently translated at 38.7% (125 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/zh_Hans/

* Translated using Weblate (French)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/fr/

* Translated using Weblate (Chinese (Simplified))

Currently translated at 48.0% (155 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/zh_Hans/

* Translated using Weblate (German)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/de/

* Translated using Weblate (French)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/fr/

* Translated using Weblate (Russian)

Currently translated at 99.3% (321 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/ru/

* Translated using Weblate (Russian)

Currently translated at 99.3% (321 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/ru/

* Translated using Weblate (Bengali)

Currently translated at 99.3% (321 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Spanish)

Currently translated at 42.1% (136 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/es/

* Translated using Weblate (Bengali)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Persian)

Currently translated at 40.2% (130 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/fa/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 99.6% (322 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Bengali)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/bn/

* Translated using Weblate (Polish)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/pl/

* Translated using Weblate (Polish)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/pl/

* Translated using Weblate (Russian)

Currently translated at 100.0% (323 of 323 strings)

Translation: PeerTube/Android
Translate-URL: https://hosted.weblate.org/projects/peertube/android/ru/

* update library and more (#160)

* download files with friendly name (not video ID)

* Update Picasso library
FIX : add extension in downloaded filename.
download files with friendly name (not video ID)

* Update Gradle
Add 0.75x and 1.25x to play speed

* Release v1.0.35

Co-authored-by: Michael Moroni <michaelmoroni@disroot.org>
Co-authored-by: mostkai <admin@pwplayer.com>
Co-authored-by: B0pol <bopol@e.email>
Co-authored-by: Jeannette L <j.lavoie@net-c.ca>
Co-authored-by: Nathan <bonnemainsnathan@gmail.com>
Co-authored-by: Mihail Iosilevitch <yosik@tutanota.com>
Co-authored-by: anonymous <noreply@weblate.org>
Co-authored-by: Oymate <dhruboadittya96@gmail.com>
Co-authored-by: Juanro49 <juanrobertogarciasanchez@gmail.com>
Co-authored-by: Mostafa Ahangarha <ahangarha@gmail.com>
Co-authored-by: Szylu <chipolade@gmail.com>
Co-authored-by: Artem <KovalevArtem.ru@gmail.com>
Co-authored-by: jmgfr <13685004+jmgfr@users.noreply.github.com>
Co-authored-by: Stefan Schueller <sschueller@nunight.com>

* try to fix 'cannot make a new request because the previous response is still open' when login.

Co-authored-by: Stefan Schüller <sschueller@techdroid.com>
Co-authored-by: Michael Moroni <michaelmoroni@disroot.org>
Co-authored-by: mostkai <admin@pwplayer.com>
Co-authored-by: B0pol <bopol@e.email>
Co-authored-by: Jeannette L <j.lavoie@net-c.ca>
Co-authored-by: Nathan <bonnemainsnathan@gmail.com>
Co-authored-by: Mihail Iosilevitch <yosik@tutanota.com>
Co-authored-by: anonymous <noreply@weblate.org>
Co-authored-by: Oymate <dhruboadittya96@gmail.com>
Co-authored-by: Juanro49 <juanrobertogarciasanchez@gmail.com>
Co-authored-by: Mostafa Ahangarha <ahangarha@gmail.com>
Co-authored-by: Szylu <chipolade@gmail.com>
Co-authored-by: Artem <KovalevArtem.ru@gmail.com>
Co-authored-by: jmgfr <13685004+jmgfr@users.noreply.github.com>
Co-authored-by: Stefan Schueller <sschueller@nunight.com>

* Release 1.0.36

Co-authored-by: Michael Moroni <michaelmoroni@disroot.org>
Co-authored-by: mostkai <admin@pwplayer.com>
Co-authored-by: B0pol <bopol@e.email>
Co-authored-by: Jeannette L <j.lavoie@net-c.ca>
Co-authored-by: Nathan <bonnemainsnathan@gmail.com>
Co-authored-by: Mihail Iosilevitch <yosik@tutanota.com>
Co-authored-by: anonymous <noreply@weblate.org>
Co-authored-by: Oymate <dhruboadittya96@gmail.com>
Co-authored-by: Juanro49 <juanrobertogarciasanchez@gmail.com>
Co-authored-by: Mostafa Ahangarha <ahangarha@gmail.com>
Co-authored-by: Szylu <chipolade@gmail.com>
Co-authored-by: Artem <KovalevArtem.ru@gmail.com>
Co-authored-by: jmgfr <13685004+jmgfr@users.noreply.github.com>
Co-authored-by: Stefan Schueller <sschueller@nunight.com>
Co-authored-by: lishoujun <lsjun@aliyun.com>

* Adding configuration setting and supporting code to pause playback on back button. (#167)

Co-authored-by: Michael Moroni <michaelmoroni@disroot.org>
Co-authored-by: mostkai <admin@pwplayer.com>
Co-authored-by: B0pol <bopol@e.email>
Co-authored-by: Jeannette L <j.lavoie@net-c.ca>
Co-authored-by: Nathan <bonnemainsnathan@gmail.com>
Co-authored-by: Mihail Iosilevitch <yosik@tutanota.com>
Co-authored-by: anonymous <noreply@weblate.org>
Co-authored-by: Oymate <dhruboadittya96@gmail.com>
Co-authored-by: Juanro49 <juanrobertogarciasanchez@gmail.com>
Co-authored-by: Mostafa Ahangarha <ahangarha@gmail.com>
Co-authored-by: Szylu <chipolade@gmail.com>
Co-authored-by: Artem <KovalevArtem.ru@gmail.com>
Co-authored-by: jmgfr <13685004+jmgfr@users.noreply.github.com>
Co-authored-by: Stefan Schueller <sschueller@nunight.com>
Co-authored-by: lishoujun <lsjun@aliyun.com>
Co-authored-by: Don Kimberlin <donkimberlin@hotmail.com>

* Making Selecting a search suggestion fill search field (#169)

* Adding configuration setting and supporting code to choose language (#168)

* Version Bump

* Fixed merge issue

* Server login (#175)

* Release v1.0.38

Co-authored-by: Michael Moroni <michaelmoroni@disroot.org>
Co-authored-by: mostkai <admin@pwplayer.com>
Co-authored-by: B0pol <bopol@e.email>
Co-authored-by: Jeannette L <j.lavoie@net-c.ca>
Co-authored-by: Nathan <bonnemainsnathan@gmail.com>
Co-authored-by: Mihail Iosilevitch <yosik@tutanota.com>
Co-authored-by: anonymous <noreply@weblate.org>
Co-authored-by: Oymate <dhruboadittya96@gmail.com>
Co-authored-by: Juanro49 <juanrobertogarciasanchez@gmail.com>
Co-authored-by: Mostafa Ahangarha <ahangarha@gmail.com>
Co-authored-by: Szylu <chipolade@gmail.com>
Co-authored-by: Artem <KovalevArtem.ru@gmail.com>
Co-authored-by: jmgfr <13685004+jmgfr@users.noreply.github.com>
Co-authored-by: Stefan Schueller <sschueller@nunight.com>
Co-authored-by: lishoujun <lsjun@aliyun.com>
Co-authored-by: Allan Nordhøy <epost@anotheragency.no>
Co-authored-by: Don Kimberlin <donkimberlin@hotmail.com>
This commit is contained in:
Stefan Schüller 2020-06-21 17:06:30 +02:00 committed by GitHub
parent ee64df7fc9
commit 0f12bf1557
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 1566 additions and 437 deletions

View File

@ -1,3 +1,9 @@
### Version 1.0.38 Tag: v1.0.8 (2020-06-21)
* Multi server login address book
* Clear search history (@dhk2)
* Android SDK to 29
* Various translations
### Version 1.0.37 Tag: v1.0.37 (2020-06-19)
* Making Selecting a search suggestion fill search field (@dhk2)
* Adding configuration setting and supporting code to choose language (@dhk2)
@ -23,6 +29,11 @@
* Gradle update
* Translations
### Version 1.0.31 Tag: v1.0.31 (2019-09-25)
* Renamed overview to discover (PeerTube v1.4.0)
* Translations
* Gradle dependencies updates
### Version 1.0.30 Tag: v1.0.30 (2019-08-07)
* Gradle update
* Translations

View File

@ -1,19 +1,27 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
compileSdkVersion 29
defaultConfig {
applicationId "net.schueller.peertube"
minSdkVersion 21
targetSdkVersion 28
versionCode 1037
versionName "1.0.37"
targetSdkVersion 29
versionCode 1038
versionName "1.0.38"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ext {
libVersions = [
exoplayer: '2.9.3'
]
}
javaCompileOptions {
annotationProcessorOptions {
arguments = [
"room.schemaLocation" : "$projectDir/schemas".toString(),
"room.incremental" : "true",
"room.expandProjection": "true"]
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
@ -70,7 +78,6 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildToolsVersion '28.0.3'
applicationVariants.all { variant ->
variant.resValue "string", "versionName", variant.versionName
@ -78,6 +85,23 @@ android {
}
dependencies {
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta6'
def room_version = "2.2.5"
def archLifecycleVersion = '2.1.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta7'
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'com.google.android.material:material:1.1.0'
// database lib
implementation "androidx.room:room-runtime:$room_version"
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
annotationProcessor "androidx.room:room-compiler:$room_version"
androidTestImplementation "androidx.room:room-testing:$room_version"
// Lifecycle components
implementation "androidx.lifecycle:lifecycle-extensions:$archLifecycleVersion"
annotationProcessor "androidx.lifecycle:lifecycle-common-java8:$archLifecycleVersion"
}

View File

@ -2,11 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="net.schueller.peertube">
<!-- connect to peertube server -->
<uses-permission android:name="android.permission.INTERNET" /> <!-- required for torrent downloading -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- required to play video in background via notification -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- required for torrent downloading -->
<application
android:name=".application.AppApplication"
android:allowBackup="true"
@ -15,6 +11,10 @@
android:supportsRtl="true"
android:theme="@style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name=".activity.ServerAddressBookActivity"
android:label="@string/title_activity_server_address_book"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".activity.VideoListActivity"
android:launchMode="singleTop"
@ -28,12 +28,8 @@
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable"></meta-data>
android:resource="@xml/searchable" />
</activity>
<activity
android:name=".activity.LoginActivity"
android:label="@string/title_activity_login"
android:theme="@style/AppTheme.NoActionBar" />
<activity
android:name=".activity.VideoPlayActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|screenLayout|smallestScreenSize|uiMode"
@ -61,6 +57,10 @@
android:exported="false" />
<service android:name=".service.VideoPlayerService" />
</application>
</application> <!-- required to play video in background via notification -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- connect to peertube server -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>

View File

@ -48,6 +48,7 @@ import net.schueller.peertube.network.RetrofitInstance;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Set;
import androidx.annotation.NonNull;
@ -145,11 +146,10 @@ public class AccountActivity extends CommonActivity {
Toolbar toolbar = findViewById(R.id.tool_bar_account);
// Setting toolbar as the ActionBar with setSupportActionBar() call
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_baseline_close_24);
getSupportActionBar().setTitle(displayNameAndHost);
getSupportActionBar().setHomeAsUpIndicator(
new IconicsDrawable(this, FontAwesome.Icon.faw_chevron_left).actionBar()
);
loadAccountVideos(displayNameAndHost);

View File

@ -18,6 +18,7 @@
package net.schueller.peertube.activity;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.preference.PreferenceActivity;
@ -25,10 +26,14 @@ import androidx.annotation.LayoutRes;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatDelegate;
import android.preference.PreferenceManager;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import static net.schueller.peertube.helper.Constants.DEFAULT_THEME;
import static net.schueller.peertube.helper.Constants.THEME_PREF_KEY;
/**
* A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls
* to be used with AppCompat.
@ -42,6 +47,20 @@ public abstract class AppCompatPreferenceActivity extends PreferenceActivity {
getDelegate().installViewFactory();
getDelegate().onCreate(savedInstanceState);
super.onCreate(savedInstanceState);
// TODO: cleanup this duplication
// Set Night Mode
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
AppCompatDelegate.setDefaultNightMode(sharedPref.getBoolean("pref_dark_mode", false) ?
AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO);
// Set theme
setTheme(getResources().getIdentifier(
sharedPref.getString(THEME_PREF_KEY, DEFAULT_THEME),
"style",
getPackageName())
);
}
@Override

View File

@ -19,18 +19,20 @@
package net.schueller.peertube.activity;
import android.content.Intent;
import android.net.Uri;
import android.nfc.Tag;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.mikepenz.fontawesome_typeface_library.FontAwesome;
import com.mikepenz.iconics.IconicsDrawable;
import net.schueller.peertube.R;
import net.schueller.peertube.helper.APIUrlHelper;
import net.schueller.peertube.model.Avatar;
import net.schueller.peertube.model.Me;
import net.schueller.peertube.network.GetUserService;
import net.schueller.peertube.network.RetrofitInstance;
@ -38,10 +40,17 @@ import net.schueller.peertube.network.Session;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;
import com.squareup.picasso.Picasso;
import java.util.Objects;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import static net.schueller.peertube.application.AppApplication.getContext;
public class MeActivity extends CommonActivity {
@ -52,34 +61,10 @@ public class MeActivity extends CommonActivity {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_top_account, menu);
// Set an icon in the ActionBar
menu.findItem(R.id.action_logout).setIcon(
new IconicsDrawable(this, FontAwesome.Icon.faw_sign_out_alt).actionBar());
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// action with ID action_refresh was selected
case R.id.action_logout:
Session.getInstance().invalidate();
Intent intent = new Intent(this, LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this.startActivity(intent);
finish();
return true;
default:
break;
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onSupportNavigateUp() {
finish(); // close this activity as oppose to navigating up
@ -97,66 +82,99 @@ public class MeActivity extends CommonActivity {
Toolbar toolbar = findViewById(R.id.tool_bar_me);
// Setting toolbar as the ActionBar with setSupportActionBar() call
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(
new IconicsDrawable(this, FontAwesome.Icon.faw_chevron_left).actionBar()
);
Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_baseline_close_24);
LinearLayout account = findViewById(R.id.a_me_account_line);
LinearLayout settings = findViewById(R.id.a_me_settings);
LinearLayout help = findViewById(R.id.a_me_helpnfeedback);
TextView logout = findViewById(R.id.a_me_logout);
init();
}
settings.setOnClickListener(view -> {
Intent settingsActivity = new Intent(getContext(), SettingsActivity.class);
//overridePendingTransition(R.anim.slide_in_bottom, 0);
startActivity(settingsActivity);
});
help.setOnClickListener(view -> {
String url = "https://github.com/sschueller/peertube-android/issues";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);
});
logout.setOnClickListener(view -> {
Session.getInstance().invalidate();
account.setVisibility(View.GONE);
});
private void init() {
// try to get user data
getUserData();
}
private boolean getUserData() {
// TODO
private void getUserData() {
String apiBaseURL = APIUrlHelper.getUrlWithVersion(this);
String baseURL = APIUrlHelper.getUrl(this);
GetUserService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetUserService.class);
Call<Me> call = service.getMe();
call.enqueue(new Callback<Me>() {
LinearLayout account = findViewById(R.id.a_me_account_line);
@Override
public void onResponse(@NonNull Call<Me> call, @NonNull Response<Me> response) {
if (response.isSuccessful()) {
Me me = response.body();
TextView username = findViewById(R.id.account_username);
TextView email = findViewById(R.id.account_email);
Log.d(TAG, response.body().toString());
TextView username = findViewById(R.id.a_me_username);
TextView email = findViewById(R.id.a_me_email);
ImageView avatarView = findViewById(R.id.a_me_avatar);
username.setText(me.getUsername());
email.setText(me.getEmail());
Log.v(TAG, me.getEmail());
Avatar avatar = me.getAccount().getAvatar();
if (avatar != null) {
String avatarPath = avatar.getPath();
Picasso.get()
.load(baseURL + avatarPath)
.into(avatarView);
}
account.setVisibility(View.VISIBLE);
} else {
account.setVisibility(View.GONE);
}
}
@Override
public void onFailure(Call<Me> call, Throwable t) {
public void onFailure(@NonNull Call<Me> call, @NonNull Throwable t) {
account.setVisibility(View.GONE);
}
});
return true;
}
@Override
protected void onResume() {
super.onResume();
init();
getUserData();
}
}

View File

@ -1,3 +1,20 @@
/*
* Copyright 2018 Stefan Schüller <sschueller@techdroid.com>
*
* License: GPL-3.0+
* 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 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.schueller.peertube.activity;
import androidx.annotation.NonNull;
@ -9,6 +26,7 @@ import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
@ -54,28 +72,6 @@ public class SelectServerActivity extends AppCompatActivity {
loadList();
// set url
TextView selectedUrl = findViewById(R.id.serverSelectedUrl);
selectedUrl.setText(APIUrlHelper.getUrl(SelectServerActivity.this));
Button setServerButton = findViewById(R.id.server_selection_set);
setServerButton.setOnClickListener(v -> {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = sharedPref.edit();
String serverUrl = APIUrlHelper.cleanServerUrl(selectedUrl.getText().toString());
if (!Patterns.WEB_URL.matcher(serverUrl).matches()) {
Toast.makeText(this, R.string.invalid_url, Toast.LENGTH_LONG).show();
} else {
editor.putString("pref_api_base", serverUrl);
editor.apply();
this.finish();
}
});
}

View File

@ -0,0 +1,168 @@
/*
* Copyright 2018 Stefan Schüller <sschueller@techdroid.com>
*
* License: GPL-3.0+
* 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 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.schueller.peertube.activity;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import net.schueller.peertube.R;
import net.schueller.peertube.adapter.ServerListAdapter;
import net.schueller.peertube.database.Server;
import net.schueller.peertube.database.ServerViewModel;
import net.schueller.peertube.fragment.AddServerFragment;
import java.util.List;
public class ServerAddressBookActivity extends CommonActivity implements AddServerFragment.OnFragmentInteractionListener {
private String TAG = "ServerAddressBookActivity";
public static final String EXTRA_REPLY = "net.schueller.peertube.room.REPLY";
private ServerViewModel mServerViewModel;
private AddServerFragment addServerFragment;
private FloatingActionButton floatingActionButton;
private FragmentManager fragmentManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_server_address_book);
mServerViewModel = new ViewModelProvider(this).get(ServerViewModel.class);
showServers();
floatingActionButton = findViewById(R.id.add_server);
floatingActionButton.setOnClickListener(view -> {
Log.d(TAG, "Click");
fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
addServerFragment = new AddServerFragment();
fragmentTransaction.replace(R.id.server_book, addServerFragment);
fragmentTransaction.commit();
floatingActionButton.hide();
});
}
@Override
public void onFragmentInteraction(Uri uri) {
}
@Override
public void onPointerCaptureChanged(boolean hasCapture) {
}
public void showServers()
{
RecyclerView recyclerView = findViewById(R.id.server_list_recyclerview);
final ServerListAdapter adapter = new ServerListAdapter(this);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
// Delete items on swipe
ItemTouchHelper helper = new ItemTouchHelper(
new ItemTouchHelper.SimpleCallback(0,
ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
@Override
public boolean onMove(@NonNull RecyclerView recyclerView,
@NonNull RecyclerView.ViewHolder viewHolder,
@NonNull RecyclerView.ViewHolder target) {
return false;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder,
int direction) {
int position = viewHolder.getAdapterPosition();
Server server = adapter.getServerAtPosition(position);
Toast.makeText(ServerAddressBookActivity.this, "Deleting " +
server.getServerName(), Toast.LENGTH_LONG).show();
// Delete the server
mServerViewModel.delete(server);
}
});
helper.attachToRecyclerView(recyclerView);
// Update the cached copy of the words in the adapter.
mServerViewModel.getAllServers().observe(this, adapter::setServers);
}
public void addServer(View view)
{
Log.d(TAG, "addServer");
EditText serverLabel = view.findViewById(R.id.serverLabel);
EditText serverUrl = view.findViewById(R.id.serverUrl);
EditText serverUsername = view.findViewById(R.id.serverUsername);
EditText serverPassword = view.findViewById(R.id.serverPassword);
Server server = new Server(serverLabel.getText().toString());
server.setServerHost(serverUrl.getText().toString());
server.setUsername(serverUsername.getText().toString());
server.setPassword(serverPassword.getText().toString());
mServerViewModel.insert(server);
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.remove(addServerFragment);
fragmentTransaction.commit();
floatingActionButton.show();
}
public void testServer()
{
}
}

View File

@ -135,13 +135,6 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
// Set theme
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
setTheme(getResources().getIdentifier(
sharedPref.getString(THEME_PREF_KEY, DEFAULT_THEME),
"style",
getPackageName())
);
super.onCreate(savedInstanceState);
@ -202,7 +195,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
// to their values. When their values change, their summaries are
// updated to reflect the new value, per the Android Design
// guidelines.
bindPreferenceSummaryToValue(findPreference("pref_api_base"));
//bindPreferenceSummaryToValue(findPreference("pref_api_base"));
bindPreferenceSummaryToValue(findPreference("pref_theme"));
}
@ -219,12 +212,12 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
Preference preference) {
String key = preference.getKey();
if ("pref_api_base".equals(key)) {
Intent intentServer = new Intent(preference.getContext(), SelectServerActivity.class);
startActivity(intentServer);
return true;
}
// String key = preference.getKey();
// if ("pref_api_base".equals(key)) {
// Intent intentServer = new Intent(preference.getContext(), SelectServerActivity.class);
// startActivity(intentServer);
// return true;
// }
return false;
}
@ -232,7 +225,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
public void onResume() {
setPreferenceScreen(null);
addPreferencesFromResource(R.xml.pref_general);
bindPreferenceSummaryToValue(findPreference("pref_api_base"));
//bindPreferenceSummaryToValue(findPreference("pref_api_base"));
super.onResume();
}

View File

@ -50,6 +50,7 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
@ -81,6 +82,7 @@ public class VideoListActivity extends CommonActivity {
public static final String EXTRA_VIDEOID = "VIDEOID";
public static final String EXTRA_ACCOUNTDISPLAYNAME = "ACCOUNTDISPLAYNAMEANDHOST";
public static final Integer SWITCH_INSTANCE = 2;
private VideoAdapter videoAdapter;
private SwipeRefreshLayout swipeRefreshLayout;
@ -125,14 +127,11 @@ public class VideoListActivity extends CommonActivity {
inflater.inflate(R.menu.menu_top_videolist, menu);
// Set an icon in the ActionBar
menu.findItem(R.id.action_settings).setIcon(
new IconicsDrawable(this, FontAwesome.Icon.faw_cog).actionBar());
menu.findItem(R.id.action_account).setIcon(
new IconicsDrawable(this, FontAwesome.Icon.faw_user_circle).actionBar());
// menu.findItem(R.id.action_server_selection).setIcon(
// new IconicsDrawable(this, FontAwesome.Icon.faw_server).actionBar());
menu.findItem(R.id.action_server_address_book).setIcon(
new IconicsDrawable(this, FontAwesome.Icon.faw_server).actionBar());
MenuItem searchMenuItem = menu.findItem(R.id.action_search);
@ -219,6 +218,16 @@ public class VideoListActivity extends CommonActivity {
stopService(new Intent(this, VideoPlayerService.class));
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SWITCH_INSTANCE) {
if(resultCode == RESULT_OK) {
loadVideos(currentStart, count, sort, filter);
}
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
@ -231,25 +240,28 @@ public class VideoListActivity extends CommonActivity {
//Toast.makeText(this, "Search Selected", Toast.LENGTH_SHORT).show();
return false;
case R.id.action_settings:
// Toast.makeText(this, "Login Selected", Toast.LENGTH_SHORT).show();
Intent intentSettings = new Intent(this, SettingsActivity.class);
this.startActivity(intentSettings);
return true;
case R.id.action_account:
if (!Session.getInstance().isLoggedIn()) {
Intent intentLogin = new Intent(this, LoginActivity.class);
this.startActivity(intentLogin);
} else {
// if (!Session.getInstance().isLoggedIn()) {
//Intent intentLogin = new Intent(this, ServerAddressBookActivity.class);
Intent intentMe = new Intent(this, MeActivity.class);
this.startActivity(intentMe);
}
//overridePendingTransition(R.anim.slide_in_bottom, 0);
// this.startActivity(intentLogin);
// } else {
// Intent intentMe = new Intent(this, MeActivity.class);
// this.startActivity(intentMe);
// }
return false;
case R.id.action_server_address_book:
Intent addressBookActivityIntent = new Intent(this, ServerAddressBookActivity.class);
this.startActivityForResult(addressBookActivityIntent, SWITCH_INSTANCE);
return false;
// case R.id.action_server_selection:
// Intent intentServer = new Intent(this, SelectServerActivity.class);
// this.startActivity(intentServer);
// return false;
default:
break;
}
@ -378,6 +390,7 @@ public class VideoListActivity extends CommonActivity {
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
handleIntent(intent);
}
@ -483,8 +496,10 @@ public class VideoListActivity extends CommonActivity {
//Log.v(TAG, "navigation_subscriptions");
if (!Session.getInstance().isLoggedIn()) {
Intent intent = new Intent(this, LoginActivity.class);
this.startActivity(intent);
// Intent intent = new Intent(this, LoginActivity.class);
// this.startActivity(intent);
Intent addressBookActivityIntent = new Intent(this, ServerAddressBookActivity.class);
this.startActivityForResult(addressBookActivityIntent, SWITCH_INSTANCE);
return false;
} else {

View File

@ -18,6 +18,7 @@
package net.schueller.peertube.adapter;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
@ -37,6 +38,8 @@ import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import static android.app.Activity.RESULT_OK;
public class ServerAdapter extends RecyclerView.Adapter<ServerAdapter.AccountViewHolder> {
@ -75,18 +78,25 @@ public class ServerAdapter extends RecyclerView.Adapter<ServerAdapter.AccountVie
holder.itemView.setOnClickListener(v -> {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(activity);
SharedPreferences.Editor editor = sharedPref.edit();
// SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(activity);
// SharedPreferences.Editor editor = sharedPref.edit();
String serverUrl = APIUrlHelper.cleanServerUrl(serverList.get(position).getHost());
editor.putString("pref_api_base", serverUrl);
editor.apply();
activity.finish();
// editor.putString("pref_api_base", serverUrl);
// editor.apply();
//
//
Toast.makeText(activity, activity.getString(R.string.server_selection_set_server, serverUrl), Toast.LENGTH_LONG).show();
Intent intent = new Intent();
intent.putExtra("serverUrl", serverUrl);
intent.putExtra("serverName", serverList.get(position).getName());
activity.setResult(RESULT_OK, intent);
activity.finish();
});
//

View File

@ -0,0 +1,158 @@
/*
* Copyright 2018 Stefan Schüller <sschueller@techdroid.com>
*
* License: GPL-3.0+
* 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 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.schueller.peertube.adapter;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.provider.SearchRecentSuggestions;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import net.schueller.peertube.R;
import net.schueller.peertube.activity.SelectServerActivity;
import net.schueller.peertube.activity.ServerAddressBookActivity;
import net.schueller.peertube.activity.VideoListActivity;
import net.schueller.peertube.database.Server;
import net.schueller.peertube.helper.APIUrlHelper;
import net.schueller.peertube.provider.SearchSuggestionsProvider;
import net.schueller.peertube.service.LoginService;
import java.util.List;
import static android.app.Activity.RESULT_OK;
public class ServerListAdapter extends RecyclerView.Adapter<ServerListAdapter.ServerViewHolder> {
private final LayoutInflater mInflater;
private List<Server> mServers; // Cached copy of Servers
public ServerListAdapter(Context context) {
this.mInflater = LayoutInflater.from(context);
}
@NonNull
@Override
public ServerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = mInflater.inflate(R.layout.row_serverbook, parent, false);
return new ServerViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull ServerViewHolder holder, int position) {
if (mServers != null) {
Server current = mServers.get(position);
holder.serverLabel.setText(current.getServerName());
holder.serverUrl.setText(current.getServerHost());
if (TextUtils.isEmpty(current.getUsername())) {
holder.hasLogin.setVisibility(View.GONE);
} else {
holder.hasLogin.setVisibility(View.VISIBLE);
}
} else {
// Covers the case of data not being ready yet.
holder.serverLabel.setText(R.string.server_book_no_servers_found);
}
holder.itemView.setOnClickListener(v -> {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(mInflater.getContext());
SharedPreferences.Editor editor = sharedPref.edit();
String serverUrl = APIUrlHelper.cleanServerUrl(getServerAtPosition(position).getServerHost());
editor.putString("pref_api_base", serverUrl);
editor.apply();
// attempt authentication if we have a username
if (!TextUtils.isEmpty(getServerAtPosition(position).getUsername())) {
LoginService.Authenticate(
getServerAtPosition(position).getUsername(),
getServerAtPosition(position).getPassword()
);
}
// tell server list activity to reload list
Intent intent = new Intent();
((Activity) mInflater.getContext()).setResult(RESULT_OK, intent);
// close this activity
((Activity) mInflater.getContext()).finish();
Toast.makeText(mInflater.getContext(), mInflater.getContext().getString(R.string.server_selection_set_server, serverUrl), Toast.LENGTH_LONG).show();
});
//
// holder.itemView.setOnLongClickListener(v -> {
// Log.v("ServerListAdapter", "setOnLongClickListener " + position);
// return true;
// });
}
public void setServers(List<Server> Servers) {
mServers = Servers;
this.notifyDataSetChanged();
}
// getItemCount() is called many times, and when it is first called,
// mServers has not been updated (means initially, it's null, and we can't return null).
@Override
public int getItemCount() {
if (mServers != null)
return mServers.size();
else return 0;
}
static class ServerViewHolder extends RecyclerView.ViewHolder {
TextView serverLabel, serverUrl, serverUsername;
ImageView hasLogin;
private ServerViewHolder(View itemView) {
super(itemView);
serverLabel = itemView.findViewById(R.id.serverLabelRow);
serverUrl = itemView.findViewById(R.id.serverUrlRow);
hasLogin = itemView.findViewById(R.id.sb_row_has_login_icon);
}
}
public Server getServerAtPosition (int position) {
return mServers.get(position);
}
}

View File

@ -1,3 +1,20 @@
/*
* Copyright 2018 Stefan Schüller <sschueller@techdroid.com>
*
* License: GPL-3.0+
* 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 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.schueller.peertube.application;
import android.app.Application;

View File

@ -0,0 +1,26 @@
/*
* Copyright 2018 Stefan Schüller <sschueller@techdroid.com>
*
* License: GPL-3.0+
* 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 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.schueller.peertube.database;
import androidx.room.Database;
import androidx.room.RoomDatabase;
@Database(entities = {Server.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract ServerDao serverDao();
}

View File

@ -0,0 +1,87 @@
/*
* Copyright 2018 Stefan Schüller <sschueller@techdroid.com>
*
* License: GPL-3.0+
* 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 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.schueller.peertube.database;
import androidx.annotation.NonNull;
import androidx.room.ColumnInfo;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "server_table")
public class Server {
@PrimaryKey(autoGenerate = true)
private int id;
@NonNull
@ColumnInfo(name = "server_name")
private String serverName;
@ColumnInfo(name = "server_host")
private String serverHost;
@ColumnInfo(name = "username")
private String username;
@ColumnInfo(name = "password")
private String password;
public Server(@NonNull String serverName) {
this.serverName = serverName;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getServerName() {
return serverName;
}
public void setServerName(String serverName) {
this.serverName = serverName;
}
public String getServerHost() {
return serverHost;
}
public void setServerHost(String serverHost) {
this.serverHost = serverHost;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

View File

@ -0,0 +1,43 @@
/*
* Copyright 2018 Stefan Schüller <sschueller@techdroid.com>
*
* License: GPL-3.0+
* 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 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.schueller.peertube.database;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import java.util.List;
@Dao
public interface ServerDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(Server server);
@Query("DELETE FROM server_table")
void deleteAll();
@Delete
void delete(Server server);
@Query("SELECT * from server_table ORDER BY server_name DESC")
LiveData<List<Server>> getAllServers();
}

View File

@ -0,0 +1,80 @@
/*
* Copyright 2018 Stefan Schüller <sschueller@techdroid.com>
*
* License: GPL-3.0+
* 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 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.schueller.peertube.database;
import android.app.Application;
import android.os.AsyncTask;
import androidx.lifecycle.LiveData;
import java.util.List;
class ServerRepository {
private ServerDao mServerDao;
private LiveData<List<Server>> mAllServers;
ServerRepository(Application application) {
ServerRoomDatabase db = ServerRoomDatabase.getDatabase(application);
mServerDao = db.serverDao();
mAllServers = mServerDao.getAllServers();
}
LiveData<List<Server>> getAllServers() {
return mAllServers;
}
void insert (Server server) {
new insertAsyncTask(mServerDao).execute(server);
}
public void delete(Server server) {
new deleteServerAsyncTask(mServerDao).execute(server);
}
private static class insertAsyncTask extends AsyncTask<Server, Void, Void> {
private ServerDao mAsyncTaskDao;
insertAsyncTask(ServerDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(final Server... params) {
mAsyncTaskDao.insert(params[0]);
return null;
}
}
private static class deleteServerAsyncTask extends AsyncTask<Server, Void, Void> {
private ServerDao mAsyncTaskDao;
deleteServerAsyncTask(ServerDao dao) {
mAsyncTaskDao = dao;
}
@Override
protected Void doInBackground(final Server... params) {
mAsyncTaskDao.delete(params[0]);
return null;
}
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright 2018 Stefan Schüller <sschueller@techdroid.com>
*
* License: GPL-3.0+
* 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 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.schueller.peertube.database;
import android.content.Context;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Database(entities = {Server.class}, version = 1, exportSchema = false)
public abstract class ServerRoomDatabase extends RoomDatabase {
public abstract ServerDao serverDao();
private static volatile ServerRoomDatabase INSTANCE;
private static final int NUMBER_OF_THREADS = 4;
static final ExecutorService databaseWriteExecutor =
Executors.newFixedThreadPool(NUMBER_OF_THREADS);
public static ServerRoomDatabase getDatabase(final Context context) {
if (INSTANCE == null) {
synchronized (ServerRoomDatabase.class) {
if (INSTANCE == null) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
ServerRoomDatabase.class, "server_database")
.build();
}
}
}
}
return INSTANCE;
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright 2018 Stefan Schüller <sschueller@techdroid.com>
*
* License: GPL-3.0+
* 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 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.schueller.peertube.database;
import android.app.Application;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import java.util.List;
public class ServerViewModel extends AndroidViewModel {
private ServerRepository mRepository;
private LiveData<List<Server>> mAllServers;
public ServerViewModel (Application application) {
super(application);
mRepository = new ServerRepository(application);
mAllServers = mRepository.getAllServers();
}
public LiveData<List<Server>> getAllServers() { return mAllServers; }
public void insert(Server server) { mRepository.insert(server); }
public void delete(Server server) {mRepository.delete(server);}
}

View File

@ -0,0 +1,178 @@
/*
* Copyright 2018 Stefan Schüller <sschueller@techdroid.com>
*
* License: GPL-3.0+
* 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 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.schueller.peertube.fragment;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import android.text.TextUtils;
import android.util.Log;
import android.util.Patterns;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import net.schueller.peertube.R;
import net.schueller.peertube.activity.SelectServerActivity;
import net.schueller.peertube.activity.ServerAddressBookActivity;
import net.schueller.peertube.helper.APIUrlHelper;
import static android.app.Activity.RESULT_OK;
public class AddServerFragment extends Fragment {
public static final String TAG = "AddServerFragment";
public static final Integer PICK_SERVER = 1;
private OnFragmentInteractionListener mListener;
private View mView;
public AddServerFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.d(TAG, "onCreateView");
// Inflate the layout for this fragment
mView = inflater.inflate(R.layout.fragment_add_server, container, false);
// bind button click
Button addServerButton = mView.findViewById(R.id.addServerButton);
addServerButton.setOnClickListener(view -> {
Activity act = getActivity();
Boolean formValid = true;
// close keyboard
try {
InputMethodManager inputManager = (InputMethodManager)
act.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(act.getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
} catch (Exception e) {
}
EditText selectedLabel = mView.findViewById(R.id.serverLabel);
if ( TextUtils.isEmpty(selectedLabel.getText())){
selectedLabel.setError( act.getString(R.string.server_book_label_is_required ));
Toast.makeText(act, R.string.invalid_url, Toast.LENGTH_LONG).show();
formValid = false;
}
// validate url
EditText selectedUrl = mView.findViewById(R.id.serverUrl);
String serverUrl = APIUrlHelper.cleanServerUrl(selectedUrl.getText().toString());
selectedUrl.setText(serverUrl);
if (!Patterns.WEB_URL.matcher(serverUrl).matches()) {
selectedUrl.setError( act.getString(R.string.server_book_valid_url_is_required ) );
Toast.makeText(act, R.string.invalid_url, Toast.LENGTH_LONG).show();
formValid = false;
}
if (formValid) {
if (act instanceof ServerAddressBookActivity) {
((ServerAddressBookActivity) act).addServer(mView);
}
}
});
// Button testServerButton = mView.findViewById(R.id.testServerButton);
// testServerButton.setOnClickListener(view -> {
// Activity act = getActivity();
// if (act instanceof ServerAddressBookActivity) {
// ((ServerAddressBookActivity) act).testServer();
// }
// });
Button pickServerUrl = mView.findViewById(R.id.pickServerUrl);
pickServerUrl.setOnClickListener(view -> {
Intent intentServer = new Intent(getActivity(), SelectServerActivity.class);
this.startActivityForResult(intentServer, PICK_SERVER);
});
return mView;
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_SERVER) {
if(resultCode == RESULT_OK) {
String serverUrlTest = data.getStringExtra("serverUrl");
//Log.d(TAG, "serverUrl " + serverUrlTest);
EditText serverUrl = mView.findViewById(R.id.serverUrl);
serverUrl.setText(serverUrlTest);
EditText serverLabel = mView.findViewById(R.id.serverLabel);
if ("".equals(serverLabel.getText().toString())) {
serverLabel.setText(data.getStringExtra("serverName"));
}
}
}
}
@Override
public void onAttach(@NonNull Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}

View File

@ -15,23 +15,15 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.schueller.peertube.activity;
package net.schueller.peertube.service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.os.Bundle;
import android.text.InputType;
import android.util.Log;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.mikepenz.fontawesome_typeface_library.FontAwesome;
import com.mikepenz.iconics.IconicsDrawable;
import androidx.annotation.NonNull;
import net.schueller.peertube.R;
import net.schueller.peertube.helper.APIUrlHelper;
@ -40,88 +32,23 @@ import net.schueller.peertube.model.Token;
import net.schueller.peertube.network.AuthenticationService;
import net.schueller.peertube.network.RetrofitInstance;
import androidx.annotation.NonNull;
import androidx.appcompat.widget.Toolbar;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class LoginActivity extends CommonActivity {
import static net.schueller.peertube.application.AppApplication.getContext;
private String TAG = "LoginActivity";
public class LoginService {
// UI references.
private AutoCompleteTextView mEmailView;
private EditText mPasswordView;
private static final String TAG = "LoginService";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
public static void Authenticate(String username, String password)
{
Context context = getContext();
setContentView(R.layout.activity_login);
String apiBaseURL = APIUrlHelper.getUrlWithVersion(context);
// bind button click
Button mEmailSignInButton = findViewById(R.id.email_sign_in_button);
mEmailSignInButton.setOnClickListener(view -> attemptLogin());
mEmailView = findViewById(R.id.email);
mPasswordView = findViewById(R.id.password);
// Attaching the layout to the toolbar object
Toolbar toolbar = findViewById(R.id.tool_bar_login);
// Setting toolbar as the ActionBar with setSupportActionBar() call
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeAsUpIndicator(
new IconicsDrawable(this, FontAwesome.Icon.faw_chevron_left).actionBar()
);
}
@Override
public void onResume() {
EditText mServerName = findViewById(R.id.login_current_server);
mServerName.setText(APIUrlHelper.getUrl(this));
mServerName.setInputType(InputType.TYPE_NULL);
super.onResume();
}
@Override
public boolean onSupportNavigateUp() {
finish(); // close this activity as oppose to navigating up
return false;
}
private void attemptLogin() {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
Context context = this;
// Reset errors.
mEmailView.setError(null);
mPasswordView.setError(null);
// Store values at the time of the login attempt.
String email = mEmailView.getText().toString();
String password = mPasswordView.getText().toString();
//check values
if (email.isEmpty()) {
Toast.makeText(LoginActivity.this, "Email/Username is empty", Toast.LENGTH_LONG).show();
return;
}
if (password.isEmpty()) {
Toast.makeText(LoginActivity.this, "Password is empty", Toast.LENGTH_LONG).show();
return;
}
// make http call to login and save access tokens
String apiBaseURL = APIUrlHelper.getUrlWithVersion(this);
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
AuthenticationService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(AuthenticationService.class);
@ -141,7 +68,7 @@ public class LoginActivity extends CommonActivity {
"code",
"password",
"upload",
email,
username,
password
);
call2.enqueue(new Callback<Token>() {
@ -157,23 +84,19 @@ public class LoginActivity extends CommonActivity {
// TODO: calc expiration
//editor.putInt(getString(R.string.pref_token_expiration), token.getRefreshToken());
editor.putString(getString(R.string.pref_token_access), token.getAccessToken());
editor.putString(getString(R.string.pref_token_refresh), token.getExpiresIn());
editor.putString(getString(R.string.pref_token_type), token.getTokenType());
editor.commit();
editor.putString(context.getString(R.string.pref_token_access), token.getAccessToken());
editor.putString(context.getString(R.string.pref_token_refresh), token.getExpiresIn());
editor.putString(context.getString(R.string.pref_token_type), token.getTokenType());
editor.apply();
Log.wtf(TAG, "Logged in");
Intent intent = new Intent(context, MeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
Toast.makeText(context, context.getString(R.string.authentication_login_success), Toast.LENGTH_LONG).show();
finish(); // close this activity
} else {
Log.wtf(TAG, response2.toString());
Toast.makeText(LoginActivity.this, "Login Error!", Toast.LENGTH_LONG).show();
Toast.makeText(context, context.getString(R.string.authentication_login_failed), Toast.LENGTH_LONG).show();
}
}
@ -181,21 +104,24 @@ public class LoginActivity extends CommonActivity {
@Override
public void onFailure(@NonNull Call<Token> call2, @NonNull Throwable t2) {
Log.wtf("err", t2.fillInStackTrace());
Toast.makeText(context, context.getString(R.string.authentication_login_failed), Toast.LENGTH_LONG).show();
}
});
} else {
Log.wtf(TAG, response.toString());
Toast.makeText(context, context.getString(R.string.authentication_login_failed), Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(@NonNull Call<OauthClient> call, @NonNull Throwable t) {
Log.wtf("err", t.fillInStackTrace());
Toast.makeText(context, context.getString(R.string.authentication_login_failed), Toast.LENGTH_LONG).show();
}
});
}
}

View File

@ -0,0 +1,6 @@
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="250"
android:fromYDelta="0%p"
android:toYDelta="-100%p">
</translate>

View File

@ -0,0 +1,6 @@
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="200"
android:fromYDelta="100%p"
android:toYDelta="0">
</translate>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,5c1.66,0 3,1.34 3,3s-1.34,3 -3,3 -3,-1.34 -3,-3 1.34,-3 3,-3zM12,19.2c-2.5,0 -4.71,-1.28 -6,-3.22 0.03,-1.99 4,-3.08 6,-3.08 1.99,0 5.97,1.09 6,3.08 -1.29,1.94 -3.5,3.22 -6,3.22z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,19h-2v-2h2v2zM15.07,11.25l-0.9,0.92C13.45,12.9 13,13.5 13,15h-2v-0.5c0,-1.1 0.45,-2.1 1.17,-2.83l1.24,-1.26c0.37,-0.36 0.59,-0.86 0.59,-1.41 0,-1.1 -0.9,-2 -2,-2s-2,0.9 -2,2L8,9c0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,0.88 -0.36,1.68 -0.93,2.25z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2c-4.97,0 -9,4.03 -9,9 0,4.17 2.84,7.67 6.69,8.69L12,22l2.31,-2.31C18.16,18.67 21,15.17 21,11c0,-4.97 -4.03,-9 -9,-9zM12,4c1.66,0 3,1.34 3,3s-1.34,3 -3,3 -3,-1.34 -3,-3 1.34,-3 3,-3zM12,18.3c-2.5,0 -4.71,-1.28 -6,-3.22 0.03,-1.99 4,-3.08 6,-3.08 1.99,0 5.97,1.09 6,3.08 -1.29,1.94 -3.5,3.22 -6,3.22z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M19.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.12,5.92 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87C2.62,9.08 2.66,9.34 2.86,9.48l2.03,1.58C4.84,11.36 4.8,11.69 4.8,12s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M4,6L2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6zM20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM12,14.5v-9l6,4.5 -6,4.5z"/>
</vector>

View File

@ -1,113 +0,0 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tool_bar_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="4dp" />
</com.google.android.material.appbar.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="net.schueller.peertube.activity.LoginActivity">
<ScrollView
android:id="@+id/login_form"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/email_login_form"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Alpha! Login is still in heavy development and may not work correctly! You must have an account on the instance you are connecting to. Registration is currently not supported"
android:textSize="16sp" />
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/login_current_server"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/login_current_server_hint"
android:inputType="none"
android:focusable="false"
android:maxLines="1"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<AutoCompleteTextView
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_email"
android:inputType="textEmailAddress"
android:maxLines="1"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_password"
android:imeActionId="6"
android:imeActionLabel="@string/action_sign_in_short"
android:imeOptions="actionUnspecified"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/email_sign_in_button"
style="?android:textAppearanceSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/action_sign_in"
android:textStyle="bold" />
</LinearLayout>
</ScrollView>
</LinearLayout>
</LinearLayout>

View File

@ -5,6 +5,7 @@
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".activity.MeActivity"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
@ -13,7 +14,7 @@
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.appcompat.widget.Toolbar
android:id="@+id/tool_bar_me"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -23,26 +24,154 @@
</com.google.android.material.appbar.AppBarLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_marginBottom="0dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/account_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/account_email"
<LinearLayout
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
android:layout_marginTop="12dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
android:id="@+id/a_me_account_line"
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/a_me_avatar"
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_marginTop="0dp"
android:paddingStart="12dp"
android:paddingTop="12dp"
android:paddingEnd="12dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/a_me_username"
android:drawablePadding="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:textAppearance="@style/Base.TextAppearance.AppCompat.Title" />
<TextView
android:id="@+id/a_me_email"
android:drawablePadding="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:textAppearance="@style/Base.TextAppearance.AppCompat.Title" />
<TextView
android:drawablePadding="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/me_logout_button"
android:id="@+id/a_me_logout"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Title" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="4dp"
android:layout_marginBottom="4dp"
android:background="@android:color/darker_gray" />
<LinearLayout
android:id="@+id/a_me_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
android:orientation="horizontal">
<TextView
android:drawableStart="@drawable/ic_baseline_settings_24"
android:drawablePadding="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/title_activity_settings"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Title" />
</LinearLayout>
<LinearLayout
android:id="@+id/a_me_helpnfeedback"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
android:orientation="horizontal">
<TextView
android:drawableStart="@drawable/ic_baseline_help_24"
android:drawablePadding="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/me_help_and_feedback_button"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Title" />
</LinearLayout>
</LinearLayout>
</ScrollView>
<!-- <LinearLayout-->
<!-- android:layout_marginBottom="0dp"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:orientation="vertical">-->
<!-- <androidx.appcompat.widget.AppCompatTextView-->
<!-- android:id="@+id/account_username"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="" />-->
<!-- <androidx.appcompat.widget.AppCompatTextView-->
<!-- android:id="@+id/account_email"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="" />-->
<!-- </LinearLayout>-->
</LinearLayout>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.ServerAddressBookActivity"
android:id="@+id/server_book">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/add_server"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@drawable/ic_baseline_add_24" />
<include layout="@layout/content_server_address_book" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -12,46 +12,6 @@
android:orientation="vertical"
>
<LinearLayout
android:padding="@dimen/fab_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<androidx.appcompat.widget.AppCompatTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="@string/server_selection_select_a_server" />
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<AutoCompleteTextView
android:hint="@string/server_selection_peertube_server_url"
android:id="@+id/serverSelectedUrl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textUri"
android:maxLines="1"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/server_selection_set"
style="?android:textAppearanceSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/action_set_url"
android:textStyle="bold" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".activity.ServerAddressBookActivity"
tools:showIn="@layout/activity_server_address_book">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/server_list_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/darker_gray"
tools:listitem="@layout/row_serverbook" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingTop="100dp"
android:paddingRight="16dp"
tools:context=".fragment.AddServerFragment"
android:background="?android:colorBackground">
<EditText
android:id="@+id/serverLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="@string/server_book_add_label"
android:inputType="textPersonName" />
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content">
<EditText
android:layout_alignParentStart="true"
android:id="@+id/serverUrl"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="@string/server_book_add_server_url"
android:inputType="textUri"
android:layout_toStartOf="@+id/pickServerUrl"/>
<Button
android:layout_alignParentEnd="true"
android:id="@+id/pickServerUrl"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/server_book_add_pick_server_button" />
</RelativeLayout>
<EditText
android:id="@+id/serverUsername"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="@string/server_book_add_username"
android:inputType="textPersonName" />
<EditText
android:id="@+id/serverPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="@string/server_book_add_password"
android:inputType="textPassword" />
<!-- <Button-->
<!-- android:id="@+id/testServerButton"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="wrap_content"-->
<!-- android:text="Test" />-->
<Button
android:id="@+id/addServerButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/server_book_add_add_button" />
</LinearLayout>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusable="true"
card_view:cardCornerRadius="0dp"
card_view:cardElevation="0dp"
card_view:cardUseCompatPadding="true">
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:padding="12dp">
<LinearLayout
android:layout_alignParentStart="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="@+id/serverLabelRow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Headline" />
<TextView
android:id="@+id/serverUrlRow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="0dp"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Subhead" />
</LinearLayout>
<ImageView
android:id="@+id/sb_row_has_login_icon"
android:src="@drawable/ic_baseline_account_circle_24"
android:visibility="visible"
android:contentDescription="@string/server_book_list_has_login"
android:layout_width="24dp"
android:layout_alignParentEnd="true"
android:layout_height="wrap_content"/>
</RelativeLayout>
</androidx.cardview.widget.CardView>

View File

@ -3,10 +3,5 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="activity.VideoListActivity">
<item
android:id="@+id/action_logout"
android:orderInCategory="300"
android:title="@string/action_bar_title_logout"
app:showAsAction="ifRoom" />
</menu>

View File

@ -12,13 +12,15 @@
android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption"
app:actionViewClass="androidx.appcompat.widget.SearchView" />
<item
android:id="@+id/action_settings"
android:id="@+id/action_server_address_book"
android:orderInCategory="300"
android:title="@string/action_bar_title_settings"
android:title="@string/action_bar_title_address_book"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_account"
android:orderInCategory="300"

View File

@ -42,9 +42,9 @@
<string name="pref_description_torrent_player">تشغيل الفيديو عبر بث التورنت . يتطلب أذونات التخزين. (ألفا ، غير مستقر!)</string>
<string name="pref_title_license">الرخصة</string>
<string name="pref_description_license">
<b>رخصة جنو العمومية v3.0</b>\n
\n
إن أذونات هذا الترخيص الأقوى للحقوق المتروكة مشروطة بإتاحة الشفرة المصدرية الكاملة للأعمال والتعديلات المرخصة ، والتي تشتمل على أعمال أكبر باستخدام عمل مرخص ، تحت نفس الترخيص. يجب الحفاظ على حقوق النشر وإشعارات الترخيص. يقدم المساهمون منحة صريحة لحقوق البراءة. عند استخدام إصدار معدل لتوفير خدمة عبر شبكة ، يجب توفير شفرة المصدر الكاملة للإصدار المعدل.</string>
\n<b>رخصة جنو العمومية v3.0</b>
\n
\nإن أذونات هذا الترخيص الأقوى للحقوق المتروكة مشروطة بإتاحة الشفرة المصدرية الكاملة للأعمال والتعديلات المرخصة ، والتي تشتمل على أعمال أكبر باستخدام عمل مرخص ، تحت نفس الترخيص. يجب الحفاظ على حقوق النشر وإشعارات الترخيص. يقدم المساهمون منحة صريحة لحقوق البراءة. عند استخدام إصدار معدل لتوفير خدمة عبر شبكة ، يجب توفير شفرة المصدر الكاملة للإصدار المعدل.</string>
<string name="pref_title_version">الإصدار</string>
<string name="search_hint">مشاركة PeerTube</string>
<string name="title_activity_search">بحث</string>

View File

@ -39,7 +39,10 @@
<string name="pref_title_torrent_player">Lecteur vidéo torrent</string>
<string name="pref_description_torrent_player">Lecture de vidéo via un flux torrent. Ceci requiert les permissions de stockage. (Alpha, instable !)</string>
<string name="pref_title_license">Licence</string>
<string name="pref_description_license"> Strings related to login </string>
<string name="pref_description_license">
\n<b>GNU Affero General Public License v3.0</b>
\n
\nLes autorisations de cette licence de copyleft la plus forte sont conditionnées à la mise à disposition d\'un code source complet des œuvres sous licence et des modifications, qui comprennent des œuvres plus grandes utilisant une œuvre sous licence, sous la même licence. Les avis de droit d\'auteur et de licence doivent être conservés. Les contributeurs accordent expressément des droits de brevet. Lorsqu\'une version modifiée est utilisée pour fournir un service sur un réseau, le code source complet de la version modifiée doit être mis à disposition.</string>
<string name="pref_title_version">Version</string>
<string name="search_hint">Rechercher sur PeerTube</string>
<string name="title_activity_search">Rechercher</string>

View File

@ -49,7 +49,7 @@
<string name="pref_title_dark_mode">Modo scuro</string>
<string name="pref_description_license">
\n<b>GNU Affero General Public License v3.0</b>
\n
\n
\nLe autorizzazioni di questa licenza copyleft più forte sono condizionate a rendere disponibile il codice sorgente completo delle opere concesse in licenza e delle modifiche, che includono opere più grandi utilizzando un lavoro concesso in licenza, sotto la stessa licenza. Le note di copyright e di licenza devono essere conservate. I contributori forniscono una concessione espressa dei diritti di brevetto. Quando si utilizza una versione modificata per fornire un servizio in rete, è necessario rendere disponibile il codice sorgente completo della versione modificata.</string>
<string name="ab">abcaso</string>
<string name="aa">afar</string>

View File

@ -288,8 +288,8 @@
<string name="account_about_joined">Lid geworden op:</string>
<string name="api_error">Er is iets misgegaan; probeer het later opnieuw!</string>
<string name="pref_description_license">
\n<b>GNU Affero General Public License v3.0</b>
\n
\n<b>GNU Affero General Public License v3.0</b>
\n
\nPermissions of this strongest copyleft license are conditioned on making available complete source code of licensed works and modifications, which include larger works using a licensed work, under the same license. Copyright and license notices must be preserved. Contributors provide an express grant of patent rights. When a modified version is used to provide a service over a network, the complete source code of the modified version must be made available.</string>
<string name="action_set_url">Server kiezen</string>
<string name="server_selection_signup_allowed">Registreren toegestaan: %s</string>

View File

@ -291,7 +291,7 @@
<string name="pref_description_show_nsfw">Pokaż zawartość NSFW</string>
<string name="pref_title_show_nsfw">Zawartość NSFW</string>
<string name="pref_description_license">
\n<b> Powszechna Licencja Publiczna GNU Affero v3.0 </b>
\n<b> Powszechna Licencja Publiczna GNU Affero v3.0</b>
\n
\nUprawnienia tej najsilniejszej licencji copyleft są uzależnione od udostępnienia pełnego kodu źródłowego licencjonowanych utworów i modyfikacji, które obejmują większe dzieła przy użyciu licencjonowanego dzieła, na tej samej licencji. Informacje o prawach autorskich i licencjach należy zachować. Autorzy zapewniają wyraźne przyznanie praw patentowych. Gdy zmodyfikowana wersja jest używana do świadczenia usługi przez sieć, należy udostępnić pełny kod źródłowy zmodyfikowanej wersji.</string>
<string name="pref_description_torrent_player">Odtwarzanie wideo przez strumień torrentów. Wymaga to uprawnień do przechowywania. (Alfa, niestabilny!)</string>

View File

@ -37,7 +37,7 @@
<string name="pref_title_license">授權條款</string>
<string name="pref_description_license">
\n<b>Affero通用公眾授權條款 v3.0</b>
\n
\n
\n這份最強的著作傳式授權條款提供作品完整的原始碼與修改其中包含了使用同一個授權條款的作品。著作權與授權條款聲明都必須保留。貢獻者提供明確的專利權授予。當修改版被用於提供透過網路的服務時修改版的完整原始碼也必須釋出。</string>
<string name="pref_title_version">版本</string>
<string name="search_hint">搜尋 PeerTube</string>

View File

@ -327,6 +327,32 @@
<string name="account_about_joined">Joined:</string>
<string name="api_error">Something went wrong, please try later!</string>
<string name="action_bar_title_server_selection">Select Server</string>
<string name="hello_blank_fragment">Hello blank fragment</string>
<string name="action_bar_title_address_book" />
<string name="authentication_login_success">Login Successfull</string>
<string name="authentication_login_failed">Login Failed!</string>
<string name="server_book_no_servers_found">Server Books is empty</string>
<string name="server_book_label_is_required">Server label is required</string>
<string name="server_book_valid_url_is_required">Valid URL is required</string>
<string name="me_logout_button">Logout</string>
<string name="me_help_and_feedback_button"><![CDATA[Help & Feedback]]></string>
<string name="server_book_add_label">Label</string>
<string name="server_book_add_server_url">Server Url</string>
<string name="server_book_add_pick_server_button">Search</string>
<string name="server_book_add_username">Username</string>
<string name="server_book_add_password">Password</string>
<string name="server_book_add_add_button">Add</string>
<string name="server_book_list_has_login">Has Login</string>
<string name="video_rating_none" translatable="false">none</string>
<string name="video_rating_like" translatable="false">like</string>
<string name="video_rating_dislike" translatable="false">dislike</string>
<string name="peertube_required_server_version" translatable="false">1.0.0-alpha.7</string>
<string name="login_current_server_hint">Current Server</string>
<string name="title_activity_server_address_book">Address Book</string>
<string name="video_speed_075">0.75x</string>
<string name="video_speed_125">1.25x</string>
<!-- Constants, Don't translate -->
<string name="pref_token_access" translatable="false">pref_token_access</string>
<string name="pref_token_refresh" translatable="false">pref_token_refresh</string>
@ -334,12 +360,8 @@
<string name="pref_token_type" translatable="false">pref_token_type</string>
<string name="pref_auth_username" translatable="false">pref_auth_username</string>
<string name="pref_auth_password" translatable="false">pref_auth_password</string>
<string name="video_rating_none" translatable="false">none</string>
<string name="video_rating_like" translatable="false">like</string>
<string name="video_rating_dislike" translatable="false">dislike</string>
<string name="peertube_required_server_version" translatable="false">1.0.0-alpha.7</string>
<string name="login_current_server_hint">Current Server</string>
<string name="video_speed_075">0.75x</string>
<string name="video_speed_125">1.25x</string>
<!-- TODO: Remove or change this placeholder text -->
</resources>

View File

@ -150,25 +150,40 @@
<!-- Text styles -->
<style name="Text" parent="TextAppearance.AppCompat"></style>
<style name="Text.Caption" parent="TextAppearance.AppCompat.Caption"></style>
<style name="Text.Small" parent="TextAppearance.AppCompat.Small"></style>
<style name="Text.Body1" parent="TextAppearance.AppCompat.Body1"></style>
<style name="Text.Body2" parent="TextAppearance.AppCompat.Body2"></style>
<style name="Text.Medium" parent="TextAppearance.AppCompat.Medium"></style>
<style name="Text.Large" parent="TextAppearance.AppCompat.Large"></style>
<style name="Text.Headline" parent="TextAppearance.AppCompat.Headline"></style>
<style name="Text.Title" parent="TextAppearance.AppCompat.Title"></style>
<style name="Text.Display1" parent="TextAppearance.AppCompat.Display1"></style>
<style name="Text.Subhead" parent="TextAppearance.AppCompat.Subhead"></style>
<style name="Text.Button" parent="TextAppearance.AppCompat.Button"></style>
<style name="Text" parent="TextAppearance.AppCompat" />
<style name="Text.Caption" parent="TextAppearance.AppCompat.Caption" />
<style name="Text.Small" parent="TextAppearance.AppCompat.Small" />
<style name="Text.Body1" parent="TextAppearance.AppCompat.Body1" />
<style name="Text.Body2" parent="TextAppearance.AppCompat.Body2" />
<style name="Text.Medium" parent="TextAppearance.AppCompat.Medium" />
<style name="Text.Large" parent="TextAppearance.AppCompat.Large" />
<style name="Text.Headline" parent="TextAppearance.AppCompat.Headline" />
<style name="Text.Title" parent="TextAppearance.AppCompat.Title" />
<style name="Text.Display1" parent="TextAppearance.AppCompat.Display1" />
<style name="Text.Subhead" parent="TextAppearance.AppCompat.Subhead" />
<style name="Text.Button" parent="TextAppearance.AppCompat.Button" />
<!-- Button Styles-->
<style name="Buton" parent="Widget.AppCompat.Button"></style>
<style name="Buton.Small" parent="Widget.AppCompat.Button.Small"></style>
<style name="Buton.Colored" parent="Widget.AppCompat.Button.Colored"></style>
<style name="Buton.Borderless" parent="Widget.AppCompat.Button.Borderless"></style>
<style name="Buton.Borderless.Colored" parent="Widget.AppCompat.Button.Borderless.Colored"></style>
<style name="Buton" parent="Widget.AppCompat.Button" />
<style name="Buton.Small" parent="Widget.AppCompat.Button.Small" />
<style name="Buton.Colored" parent="Widget.AppCompat.Button.Colored" />
<style name="Buton.Borderless" parent="Widget.AppCompat.Button.Borderless" />
<style name="Buton.Borderless.Colored" parent="Widget.AppCompat.Button.Borderless.Colored" />
</resources>

View File

@ -1,8 +1,5 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<Preference
android:key="pref_api_base"
android:title="@string/pref_title_peertube_server" />
<!--<SwitchPreference-->
<!--android:key="pref_background_play"-->

View File

@ -1,4 +1,4 @@
#Mon Jun 01 12:58:36 CEST 2020
#Fri Jun 12 19:07:10 CEST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME