diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..1d1fe94
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1 @@
+Dockerfile
\ No newline at end of file
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..8af2caf
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,163 @@
+stages:
+ - environment
+ - build
+ - test
+ - internal
+ - alpha
+ - beta
+ - production
+ - stop
+
+.updateContainerJob:
+ image: docker:stable
+ stage: environment
+ services:
+ - docker:dind
+ script:
+ - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
+ - docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG || true
+ - docker build --cache-from $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG -t $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG .
+ - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
+ tags:
+ - shell
+
+updateContainer:
+ extends: .updateContainerJob
+ only:
+ changes:
+ - Dockerfile
+
+ensureContainer:
+ extends: .updateContainerJob
+ allow_failure: true
+ before_script:
+ - "mkdir -p ~/.docker && echo '{\"experimental\": \"enabled\"}' > ~/.docker/config.json"
+ - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
+ # Skip update container `script` if the container already exists
+ # via https://gitlab.com/gitlab-org/gitlab-ce/issues/26866#note_97609397 -> https://stackoverflow.com/a/52077071/796832
+ - docker manifest inspect $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG > /dev/null && exit || true
+
+.build_job:
+ image: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
+ stage: build
+ before_script:
+ # We store this binary file in a variable as hex with this command, `xxd -p android-signing-keystore.jks > jks.txt` (remove all \n)
+ # Then we convert the hex back to a binary file
+ - pwd
+ - echo "$signing_jks_file_hex" | xxd -r -p - > android-signing-keystore.jks
+ - md5sum android-signing-keystore.jks
+ # get next version from latest changelog
+ - "export VERSION_CODE=`ls -f ./fastlane/metadata/android/en-US/changelogs | cut -d_ -f3 | sort -n | tail -1 | rev | cut -c5- | rev` && echo $VERSION_CODE"
+ # We add 200 to get this high enough above current versionCodes that are published
+ # - "export VERSION_CODE=$((200 + $CI_PIPELINE_IID)) && echo $VERSION_CODE"
+ - "export VERSION_SHA=`echo ${CI_COMMIT_SHA:0:8}` && echo $VERSION_SHA"
+ - "export VERSION_NAME=${VERSION_CODE:0:1}.${VERSION_CODE:1:1}.${VERSION_CODE:2} && echo $VERSION_NAME"
+ after_script:
+ - rm -f android-signing-keystore.jks || true
+ artifacts:
+ paths:
+ - app/build/outputs
+ tags:
+ - docker
+
+buildDebug:
+ extends: .build_job
+ script:
+ - bundle exec fastlane buildDebug
+
+buildRelease:
+ extends: .build_job
+ script:
+ - bundle exec fastlane buildRelease
+ environment:
+ name: production
+ only:
+ - /^v[0-9]*\.[0-9]*\.[0-9]*$/i
+ except:
+ - branches
+
+testDebug:
+ image: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
+ stage: test
+ dependencies:
+ - buildDebug
+ script:
+ - bundle exec fastlane test
+ tags:
+ - docker
+
+publishGithub:
+ image: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
+ stage: internal
+ dependencies:
+ - buildRelease
+ when: manual
+ script:
+ - "export VERSION_CODE=`ls -f ./fastlane/metadata/android/en-US/changelogs | cut -d_ -f3 | sort -n | tail -1 | rev | cut -c5- | rev` && echo $VERSION_CODE"
+ - "export VERSION_SHA=`echo ${CI_COMMIT_SHA:0:8}` && echo $VERSION_SHA"
+ - "export VERSION_NAME=${VERSION_CODE:0:1}.${VERSION_CODE:1:1}.${VERSION_CODE:2} && echo $VERSION_NAME"
+ - ci-scripts/make-github-release.sh
+ tags:
+ - docker
+ only:
+ - /^v[0-9]*\.[0-9]*\.[0-9]*$/i
+
+publishInternal:
+ image: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
+ stage: internal
+ dependencies:
+ - buildRelease
+ when: manual
+ before_script:
+ - echo $google_play_service_account_api_key_json > ../google_play_api_key.json
+ - md5sum /builds/sschueller/google_play_api_key.json
+ after_script:
+ - rm -f ../google_play_api_key.json
+ script:
+ - bundle exec fastlane internal
+ tags:
+ - docker
+ only:
+ - /^v[0-9]*\.[0-9]*\.[0-9]*$/i
+
+.promote_job:
+ image: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
+ when: manual
+ dependencies: []
+ before_script:
+ - echo $google_play_service_account_api_key_json > ../google_play_api_key.json
+ - md5sum ../google_play_api_key.json
+ after_script:
+ - rm -f ../google_play_api_key.json
+
+promoteAlpha:
+ extends: .promote_job
+ stage: alpha
+ script:
+ - bundle exec fastlane promote_internal_to_alpha
+ tags:
+ - docker
+ only:
+ - /^v[0-9]*\.[0-9]*\.[0-9]*$/i
+
+promoteBeta:
+ extends: .promote_job
+ stage: beta
+ script:
+ - bundle exec fastlane promote_alpha_to_beta
+ tags:
+ - docker
+ only:
+ - /^v[0-9]*\.[0-9]*\.[0-9]*$/i
+
+promoteProduction:
+ extends: .promote_job
+ stage: production
+ # We only allow production promotion on `master` because
+ # it has its own production scoped secret variables
+ only:
+ - /^v[0-9]*\.[0-9]*\.[0-9]*$/i
+ script:
+ - bundle exec fastlane promote_beta_to_production
+ tags:
+ - docker
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f57e087..4c29d77 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,52 @@
+### Version 1.0.51 Tag: v1.0.51 (2021-01-14)
+ - fixed default app language on first start (@kosharskiy)
+ - Settings screen translations uk and ru languages (@kosharskiy)
+ - cleanup app/build.gradle file (@kosharskiy)
+ - fixed video meta data display issue (@kosharskiy)
+ - updated translations
+
+### Version 1.0.50 Tag: v1.0.50 (2020-11-22)
+ - add support for disabling SSL
+ - translations
+
+### Version 1.0.49 Tag: v1.0.49 (2020-09-26)
+ - add support of hypertext redirection in description (@freeboub)
+ - various crash fixes (@freeboub)
+ - avoid going to pip when leaving the app due to share button (@freeboub)
+ - Add ability to filter server list (@freeboub)
+ - Refactor Toast error management to split network error (@freeboub)
+ - keep video aspect ratio for pip (@freeboub)
+ - navigation bar was not restored when leaving landscape mode (@freeboub)
+
+### Version 1.0.48 Tag: v1.0.48 (2020-09-26)
+ - f-droid release to fix auto deployment
+
+### Version 1.0.47 Tag: v1.0.47 (2020-07-10)
+ * Authentication refresh
+
+### Version 1.0.46 Tag: v1.0.46 (2020-07-08)
+ * Revert broken auth
+
+### Version 1.0.45 Tag: v1.0.45 (2020-07-08)
+ * Added token refresh
+
+### Version 1.0.44 Tag: v1.0.44 (2020-07-05)
+ * Completed implementation of Likes & Dislikes (@Poslovitch)
+ * Added preview of the current playback speed and video quality in the VideoOptionsFragment (@Poslovitch)
+ * Lots of code cleanup
+ * Various translations
+
+### Version 1.0.43 Tag: v1.0.43 (2020-07-04)
+ * Fix back button issue
+
+### Version 1.0.42 Tag: v1.0.42 (2020-07-04)
+ * Added appbar at the top of the SettingsActivity (@Poslovitch)
+ * Improved and added some French translations (@Poslovitch)
+ * Removed translations for untranslatable strings (@Poslovitch)
+ * Add stop button to expanded notification, and stop and switch to audio in video window (@dhk2)
+ * More data in Server search
+ * VideoList timestamp fix
+
### Version 1.0.41 Tag: v1.0.41 (2020-06-28)
* Floating window player controls fix (@dhk2)
* Updated app icons
diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md
new file mode 100644
index 0000000..6aedc74
--- /dev/null
+++ b/DEPLOYMENT.md
@@ -0,0 +1,16 @@
+## Internal deployment notes
+
+ 1. merge pull-requests on github into develop
+ 2. Locally switch to develop
+ 3. Pull github develop
+ 4. Pull weblate develop
+ 5. Add change logs (fastlane/metadata/android/en-US/changelogs/XXX.txt)
+ 6. Run ci-script/update-changelog.sh
+ 7. Push to gitlab
+ 8. Merge request into master and merge
+ 9. Add Release Tag on master branch
+ 10. Release to play store
+ 11. Wait for gitlab -> github sync
+ 12. Run publishGithub
+
+
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..24e2d5c
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,45 @@
+FROM gradle:6.1.1-jdk8
+
+ENV ANDROID_SDK_URL https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip
+ENV ANDROID_SDK_CHECKSUM 444e22ce8ca0f67353bda4b85175ed3731cae3ffa695ca18119cbacef1c1bea0
+ENV ANDROID_BUILD_TOOLS_VERSION 29.0.3
+ENV ANDROID_HOME /usr/local/android-sdk-linux
+ENV ANDROID_VERSION 29
+ENV PATH ${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/platform-tools
+
+RUN mkdir "$ANDROID_HOME" .android && \
+ cd "$ANDROID_HOME" && \
+ curl -o sdk.zip $ANDROID_SDK_URL && \
+ echo "${ANDROID_SDK_CHECKSUM} sdk.zip" | sha256sum -c - && \
+ unzip sdk.zip && \
+ rm sdk.zip
+
+RUN yes | ${ANDROID_HOME}/tools/bin/sdkmanager --licenses
+RUN $ANDROID_HOME/tools/bin/sdkmanager --update
+RUN $ANDROID_HOME/tools/bin/sdkmanager "build-tools;${ANDROID_BUILD_TOOLS_VERSION}" \
+ "platforms;android-${ANDROID_VERSION}" \
+ "platform-tools"
+
+# install OS packages
+RUN apt-get --quiet update --yes
+
+# Installing build tools
+RUN apt-get update && \
+ apt-get install -y \
+ build-essential \
+ ruby \
+ jq \
+ ruby-dev
+
+# We use this for xxd hex->binary
+RUN apt-get --quiet install --yes vim-common
+
+# install FastLane
+COPY Gemfile.lock .
+COPY Gemfile .
+RUN gem update --system 3.0.8 # https://github.com/rubygems/rubygems/issues/3068
+RUN gem install bundler
+RUN bundle install
+
+# at least 1.5G memory is required for the gitlab runner to succeed
+#RUN echo "org.gradle.jvmargs=-Xmx1536m" >> local.properties
\ No newline at end of file
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..7a118b4
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,3 @@
+source "https://rubygems.org"
+
+gem "fastlane"
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 0000000..6e7ebae
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,178 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ CFPropertyList (3.0.2)
+ addressable (2.7.0)
+ public_suffix (>= 2.0.2, < 5.0)
+ atomos (0.1.3)
+ aws-eventstream (1.1.0)
+ aws-partitions (1.353.0)
+ aws-sdk-core (3.104.3)
+ aws-eventstream (~> 1, >= 1.0.2)
+ aws-partitions (~> 1, >= 1.239.0)
+ aws-sigv4 (~> 1.1)
+ jmespath (~> 1.0)
+ aws-sdk-kms (1.36.0)
+ aws-sdk-core (~> 3, >= 3.99.0)
+ aws-sigv4 (~> 1.1)
+ aws-sdk-s3 (1.76.0)
+ aws-sdk-core (~> 3, >= 3.104.1)
+ aws-sdk-kms (~> 1)
+ aws-sigv4 (~> 1.1)
+ aws-sigv4 (1.2.1)
+ aws-eventstream (~> 1, >= 1.0.2)
+ babosa (1.0.3)
+ claide (1.0.3)
+ colored (1.2)
+ colored2 (3.1.2)
+ commander-fastlane (4.4.6)
+ highline (~> 1.7.2)
+ declarative (0.0.20)
+ declarative-option (0.1.0)
+ digest-crc (0.6.1)
+ rake (~> 13.0)
+ domain_name (0.5.20190701)
+ unf (>= 0.0.5, < 1.0.0)
+ dotenv (2.7.6)
+ emoji_regex (3.0.0)
+ excon (0.76.0)
+ faraday (1.0.1)
+ multipart-post (>= 1.2, < 3)
+ faraday-cookie_jar (0.0.6)
+ faraday (>= 0.7.4)
+ http-cookie (~> 1.0.0)
+ faraday_middleware (1.0.0)
+ faraday (~> 1.0)
+ fastimage (2.2.0)
+ fastlane (2.155.3)
+ CFPropertyList (>= 2.3, < 4.0.0)
+ addressable (>= 2.3, < 3.0.0)
+ aws-sdk-s3 (~> 1.0)
+ babosa (>= 1.0.3, < 2.0.0)
+ bundler (>= 1.12.0, < 3.0.0)
+ colored
+ commander-fastlane (>= 4.4.6, < 5.0.0)
+ dotenv (>= 2.1.1, < 3.0.0)
+ emoji_regex (>= 0.1, < 4.0)
+ excon (>= 0.71.0, < 1.0.0)
+ faraday (~> 1.0)
+ faraday-cookie_jar (~> 0.0.6)
+ faraday_middleware (~> 1.0)
+ fastimage (>= 2.1.0, < 3.0.0)
+ gh_inspector (>= 1.1.2, < 2.0.0)
+ google-api-client (>= 0.37.0, < 0.39.0)
+ google-cloud-storage (>= 1.15.0, < 2.0.0)
+ highline (>= 1.7.2, < 2.0.0)
+ json (< 3.0.0)
+ jwt (>= 2.1.0, < 3)
+ mini_magick (>= 4.9.4, < 5.0.0)
+ multipart-post (~> 2.0.0)
+ plist (>= 3.1.0, < 4.0.0)
+ rubyzip (>= 2.0.0, < 3.0.0)
+ security (= 0.1.3)
+ simctl (~> 1.6.3)
+ slack-notifier (>= 2.0.0, < 3.0.0)
+ terminal-notifier (>= 2.0.0, < 3.0.0)
+ terminal-table (>= 1.4.5, < 2.0.0)
+ tty-screen (>= 0.6.3, < 1.0.0)
+ tty-spinner (>= 0.8.0, < 1.0.0)
+ word_wrap (~> 1.0.0)
+ xcodeproj (>= 1.13.0, < 2.0.0)
+ xcpretty (~> 0.3.0)
+ xcpretty-travis-formatter (>= 0.0.3)
+ gh_inspector (1.1.3)
+ google-api-client (0.38.0)
+ addressable (~> 2.5, >= 2.5.1)
+ googleauth (~> 0.9)
+ httpclient (>= 2.8.1, < 3.0)
+ mini_mime (~> 1.0)
+ representable (~> 3.0)
+ retriable (>= 2.0, < 4.0)
+ signet (~> 0.12)
+ google-cloud-core (1.5.0)
+ google-cloud-env (~> 1.0)
+ google-cloud-errors (~> 1.0)
+ google-cloud-env (1.3.3)
+ faraday (>= 0.17.3, < 2.0)
+ google-cloud-errors (1.0.1)
+ google-cloud-storage (1.27.0)
+ addressable (~> 2.5)
+ digest-crc (~> 0.4)
+ google-api-client (~> 0.33)
+ google-cloud-core (~> 1.2)
+ googleauth (~> 0.9)
+ mini_mime (~> 1.0)
+ googleauth (0.13.1)
+ faraday (>= 0.17.3, < 2.0)
+ jwt (>= 1.4, < 3.0)
+ memoist (~> 0.16)
+ multi_json (~> 1.11)
+ os (>= 0.9, < 2.0)
+ signet (~> 0.14)
+ highline (1.7.10)
+ http-cookie (1.0.3)
+ domain_name (~> 0.5)
+ httpclient (2.8.3)
+ jmespath (1.4.0)
+ json (2.3.1)
+ jwt (2.2.1)
+ memoist (0.16.2)
+ mini_magick (4.10.1)
+ mini_mime (1.0.2)
+ multi_json (1.15.0)
+ multipart-post (2.0.0)
+ nanaimo (0.3.0)
+ naturally (2.2.0)
+ os (1.1.1)
+ plist (3.5.0)
+ public_suffix (4.0.5)
+ rake (13.0.1)
+ representable (3.0.4)
+ declarative (< 0.1.0)
+ declarative-option (< 0.2.0)
+ uber (< 0.2.0)
+ retriable (3.1.2)
+ rouge (2.0.7)
+ rubyzip (2.3.0)
+ security (0.1.3)
+ signet (0.14.0)
+ addressable (~> 2.3)
+ faraday (>= 0.17.3, < 2.0)
+ jwt (>= 1.5, < 3.0)
+ multi_json (~> 1.10)
+ simctl (1.6.8)
+ CFPropertyList
+ naturally
+ slack-notifier (2.3.2)
+ terminal-notifier (2.0.0)
+ terminal-table (1.8.0)
+ unicode-display_width (~> 1.1, >= 1.1.1)
+ tty-cursor (0.7.1)
+ tty-screen (0.8.1)
+ tty-spinner (0.9.3)
+ tty-cursor (~> 0.7)
+ uber (0.1.0)
+ unf (0.1.4)
+ unf_ext
+ unf_ext (0.0.7.7)
+ unicode-display_width (1.7.0)
+ word_wrap (1.0.0)
+ xcodeproj (1.17.1)
+ CFPropertyList (>= 2.3.3, < 4.0)
+ atomos (~> 0.1.3)
+ claide (>= 1.0.2, < 2.0)
+ colored2 (~> 3.1)
+ nanaimo (~> 0.3.0)
+ xcpretty (0.3.0)
+ rouge (~> 2.0.7)
+ xcpretty-travis-formatter (1.0.0)
+ xcpretty (~> 0.2, >= 0.0.7)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ fastlane
+
+BUNDLED WITH
+ 2.1.4
diff --git a/README.md b/README.md
index 9babb0d..f401516 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
-
+
@@ -12,8 +12,9 @@
## Screenshots
-[ ](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_01.png)
-[ ](fastlane/metadata/android/en-US/images/phoneScreenshots/shot_02.png)
+[ ](fastlane/metadata/android/en-US/images/phoneScreenshots/1_en-US.png)
+[ ](fastlane/metadata/android/en-US/images/phoneScreenshots/2_en-US.png)
+[ ](fastlane/metadata/android/en-US/images/phoneScreenshots/3_en-US.png)
## Description
PeerTube is a federated video streaming platform that is community-owned and ad-free, with no vendor lock-in. This client allows you to watch and browse videos on a server of your choice in the PeerTube network.
@@ -27,6 +28,13 @@ Please note this is app is in beta and is still missing a lot of features.
* Beta Test on Google Play: https://play.google.com/store/apps/details?id=net.schueller.peertube
* F-Droid: https://f-droid.org/packages/net.schueller.peertube/
+## Releases
+Release Tags are automatically built and deployed to the play store but not released to production right away.
+To use the latest tagged release download it from github or fdroid (~1 day delay).
+
+## Reproducible Builds
+Reproducible builds currently does not work.
+
## Help Translate
* https://hosted.weblate.org/projects/peertube/
@@ -47,11 +55,11 @@ Please note this is app is in beta and is still missing a lot of features.
* Video speed selection
* Video quality selection
* Server selection
+* Video overlay play and draggable video window
## Coming soon
* Video Playback via WebRTC
-* Video overlay play and draggable video window
* Comment videos
* Report Videos
* User / Channel Overview Page
@@ -65,4 +73,4 @@ Whether you have ideas, translations, design changes, code cleaning, or real hea
-Bitcoin: 1LoTXo728HzYTtyfbkaf5ewSRvu8ABTDPm
+Bitcoin: 1LoTXo728HzYTtyfbkaf5ewSRvu8ABTDPm
diff --git a/REPRODUCIBLE_BUILDS.md b/REPRODUCIBLE_BUILDS.md
new file mode 100644
index 0000000..7be7bdf
--- /dev/null
+++ b/REPRODUCIBLE_BUILDS.md
@@ -0,0 +1,62 @@
+# Reproducible Builds
+
+Note: This does not work at this time
+
+## Install Docker
+
+Download and install [Docker](https://www.docker.com/).
+
+## Check your Thorium app version and build timestamp
+
+1. Open the Thorium app
+2. Go to Settings
+3. Check the app version listed under About 'Version' (e.g., 1.0.44), and record its value to be used later
+4. Check the build timestamp under About 'Build Time' (e.g., 1593942384524), and record its value to be used later
+
+## Download the App open-source code
+
+1. Make sure you have `git` installed
+2. Clone the Github repository
+3. Checkout the Tag that corresponds to the version of your Thorium app (e.g., 1.0.44)
+
+```shell
+git clone https://github.com/sschueller/peertube-android ~/peertube-android
+cd ~/peertube-android
+git checkout v1.0.44
+```
+
+## Build the project using Docker
+
+1. Build a Docker Image with the required Android Tools
+2. Build the App in the Docker Container while specifying the build timestamp that was recorded earlier (e.g., 1593942384524)
+3. Copy the freshly-built APK
+
+```shell
+cd ~/peertube-android
+docker build -t thorium-builder .
+docker run --rm -v ~/Private/peertube:/home/peertube -w /home/peertube thorium-builder gradle assembleRelease -PkeystorePassword=securePassword -PkeyAliasPassword=securePassword -PkeystoreFile=build.keystore -PbuildTimestamp=1593973044091
+cp app/build/outputs/apk/release/app-release-unsigned.apk thorium-built.apk
+```
+
+## Extract the Play Store APK from your phone
+
+1. Make sure you have `adb` installed
+2. Connect your phone to your computer
+3. Extract the APK from the phone
+
+```shell
+cd ~/peertube-android
+adb shell pm path net.schueller.peertube
+adb pull /data/app/net.schueller.peertube-mCeISw_AujlMBHyPfVhdSg==/base.apk thorium-store.apk
+```
+
+## Compare the two files
+
+1. Make sure you have `python` installed
+2. Use the `apkdiff` script to compare the APKs
+
+```shell
+cd ~/peertube-android
+./apkdiff.py thorium-built.apk thorium-store.apk
+```
+
diff --git a/apkdiff.py b/apkdiff.py
new file mode 100755
index 0000000..13df537
--- /dev/null
+++ b/apkdiff.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+# Taken from https://github.com/DrKLO/Telegram/blob/master/apkdiff.py on June 4th, 2020
+
+import sys
+from zipfile import ZipFile
+
+def compareFiles(first, second):
+ while True:
+ firstBytes = first.read(4096);
+ secondBytes = second.read(4096);
+ if firstBytes != secondBytes:
+ return False
+
+ if firstBytes == b"":
+ break
+
+ return True
+
+def compare(first, second):
+ FILES_TO_IGNORE = ["META-INF/MANIFEST.MF", "META-INF/CERT.RSA", "META-INF/CERT.SF"]
+
+ firstZip = ZipFile(first, 'r')
+ secondZip = ZipFile(second, 'r')
+
+ firstList = list(filter(lambda firstInfo: firstInfo.filename not in FILES_TO_IGNORE, firstZip.infolist()))
+ secondList = list(filter(lambda secondInfo: secondInfo.filename not in FILES_TO_IGNORE, secondZip.infolist()))
+
+ if len(firstList) != len(secondList):
+ print("APKs has different amount of files (%d != %d)" % (len(firstList), len(secondList)))
+ return False
+
+ for firstInfo in firstList:
+ found = False
+ for secondInfo in secondList:
+ if firstInfo.filename == secondInfo.filename:
+ found = True
+ firstFile = firstZip.open(firstInfo, 'r')
+ secondFile = secondZip.open(secondInfo, 'r')
+
+ if compareFiles(firstFile, secondFile) != True:
+ print("APK file %s does not match" % firstInfo.filename)
+ return False
+
+ secondList.remove(secondInfo)
+ break
+
+ if found == False:
+ print("file %s not found in second APK" % firstInfo.filename)
+ return False
+
+ if len(secondList) != 0:
+ for secondInfo in secondList:
+ print("file %s not found in first APK" % secondInfo.filename)
+ return False
+
+ return True
+
+if __name__ == '__main__':
+ if len(sys.argv) != 3:
+ print("Usage: apkdiff ")
+ sys.exit(1)
+
+ if sys.argv[1] == sys.argv[2] or compare(sys.argv[1], sys.argv[2]) == True:
+ print("APKs are the same!")
+ else:
+ print("APKs are different!")
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index dd038df..ef4901c 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,19 +1,54 @@
-apply plugin: 'com.android.application'
+plugins {
+ id 'com.android.application'
+ id 'kotlin-android'
+ id 'kotlin-parcelize'
+ id 'kotlin-kapt'
+}
+
+ext.readProperty = { paramName -> readPropertyWithDefault(paramName, null) }
+ext.readPropertyWithDefault = { paramName, defaultValue ->
+ if (project.hasProperty(paramName)) {
+ return project.getProperties().get(paramName)
+ } else {
+ Properties properties = new Properties()
+ if (project.rootProject.file('local.properties').exists()) {
+ properties.load(project.rootProject.file('local.properties').newDataInputStream())
+ }
+ if (properties.getProperty(paramName) != null) {
+ return properties.getProperty(paramName)
+ } else {
+ return defaultValue
+ }
+ }
+}
+
+// Try reading secrets from file
+def secretsPropertiesFile = rootProject.file("secrets.properties")
+def secretProperties = new Properties()
+
+if (secretsPropertiesFile.exists()) {
+ secretProperties.load(new FileInputStream(secretsPropertiesFile))
+}
+// Otherwise read from environment variables, this happens in CI
+else {
+ secretProperties.setProperty("signing_keystore_password", "${System.getenv('signing_keystore_password')}")
+ secretProperties.setProperty("signing_key_password", "${System.getenv('signing_key_password')}")
+ secretProperties.setProperty("signing_key_alias", "${System.getenv('signing_key_alias')}")
+}
android {
compileSdkVersion 29
+ buildToolsVersion "29.0.3"
+
defaultConfig {
applicationId "net.schueller.peertube"
minSdkVersion 21
targetSdkVersion 29
- versionCode 1041
- versionName "1.0.41"
+ versionCode Integer.valueOf(System.getenv("VERSION_CODE") ?: 1)
+ versionName System.getenv("VERSION_NAME") + "-" + System.getenv("VERSION_SHA")
+ buildConfigField "long", "BUILD_TIME", readPropertyWithDefault('buildTimestamp', System.currentTimeMillis()) + 'L'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
- ext {
- libVersions = [
- exoplayer: '2.11.6'
- ]
- }
+
javaCompileOptions {
annotationProcessorOptions {
arguments = [
@@ -22,56 +57,24 @@ android {
"room.expandProjection": "true"]
}
}
- dependencies {
- implementation fileTree(dir: 'libs', include: ['*.jar'])
-
- // Layouts and design
- implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
- implementation 'androidx.appcompat:appcompat:1.1.0'
- implementation 'androidx.cardview:cardview:1.0.0'
- implementation 'androidx.recyclerview:recyclerview:1.1.0'
- implementation 'androidx.legacy:legacy-support-v13:1.0.0'
- implementation 'com.google.android.material:material:1.1.0'
- implementation 'de.hdodenhof:circleimageview:3.0.0'
-
- // font awesome
- implementation "com.mikepenz:iconics-core:3.1.0"
- implementation 'com.mikepenz:fontawesome-typeface:5.3.1.1@aar'
-
- // http client / REST
- implementation 'com.squareup.okhttp3:okhttp:4.3.1'
- implementation 'com.squareup.retrofit2:retrofit:2.5.0'
-
- // image downloading and caching library
- implementation 'com.squareup.picasso:picasso:2.71828'
-
- // json decoder/encoder
- implementation 'com.google.code.gson:gson:2.8.6'
- implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
-
- // Torrents and WebRTC
- implementation 'com.github.TorrentStream:TorrentStream-Android:2.6.1'
-// implementation "com.github.TorrentStream:TorrentStreamServer-Android:1.0.1"
-// implementation 'org.webrtc:google-webrtc:1.0.+'
-
- // video player repo:jcenter()
- implementation "com.google.android.exoplayer:exoplayer-core:$libVersions.exoplayer"
- implementation "com.google.android.exoplayer:exoplayer-dash:$libVersions.exoplayer"
- implementation "com.google.android.exoplayer:exoplayer-ui:$libVersions.exoplayer"
- implementation "com.google.android.exoplayer:exoplayer-hls:$libVersions.exoplayer"
- implementation "com.google.android.exoplayer:exoplayer-smoothstreaming:$libVersions.exoplayer"
- implementation "com.google.android.exoplayer:extension-mediasession:$libVersions.exoplayer"
-
- // testing
- testImplementation 'junit:junit:4.12'
- androidTestImplementation 'androidx.test:runner:1.2.0'
- androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
+ }
+ signingConfigs {
+ release {
+ // You need to specify either an absolute path or include the
+ // keystore file in the same directory as the build.gradle file.
+ storeFile file("../android-signing-keystore.jks")
+ storePassword "${secretProperties['signing_keystore_password']}"
+ keyAlias "${secretProperties['signing_key_alias']}"
+ keyPassword "${secretProperties['signing_key_password']}"
}
}
+
buildTypes {
release {
minifyEnabled false
+ testCoverageEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ signingConfig signingConfigs.release
}
}
compileOptions {
@@ -82,28 +85,91 @@ android {
applicationVariants.all { variant ->
variant.resValue "string", "versionName", variant.versionName
}
+
+ buildFeatures{
+ viewBinding = true
+ }
+
}
+def room_version = "2.2.6"
+def lifecycleVersion = '2.2.0'
+def exoplayer = '2.12.3'
+def fragment_version = "1.2.5"
+
dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
- def room_version = "2.2.5"
- def archLifecycleVersion = '2.1.0'
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
- 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'
+ // Layouts and design
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
+ implementation 'androidx.appcompat:appcompat:1.2.0'
+ implementation 'com.google.android.material:material:1.2.1'
+ implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
+ implementation "androidx.fragment:fragment-ktx:$fragment_version"
+
+ implementation 'de.hdodenhof:circleimageview:3.0.0'
+
+ // font awesome
+ implementation "com.mikepenz:iconics-core:3.1.0"
+ implementation 'com.mikepenz:fontawesome-typeface:5.3.1.1@aar'
+
+ // http client / REST
+ implementation 'com.squareup.okhttp3:okhttp:4.9.0'
+ implementation 'com.squareup.retrofit2:retrofit:2.9.0'
+
+ // image downloading and caching library
+ implementation 'com.squareup.picasso:picasso:2.71828'
+
+ // json decoder/encoder
+ implementation 'com.google.code.gson:gson:2.8.6'
+ implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
+
+ // Torrents and WebRTC
+ implementation 'com.github.TorrentStream:TorrentStream-Android:2.7.0'
+// implementation "com.github.TorrentStream:TorrentStreamServer-Android:1.0.1"
+// implementation 'org.webrtc:google-webrtc:1.0.+'
+
+ // video player repo:jcenter()
+ implementation "com.google.android.exoplayer:exoplayer-core:$exoplayer"
+ implementation "com.google.android.exoplayer:exoplayer-dash:$exoplayer"
+ implementation "com.google.android.exoplayer:exoplayer-ui:$exoplayer"
+ implementation "com.google.android.exoplayer:exoplayer-hls:$exoplayer"
+ implementation "com.google.android.exoplayer:exoplayer-smoothstreaming:$exoplayer"
+ implementation "com.google.android.exoplayer:extension-mediasession:$exoplayer"
+ implementation "com.google.android.exoplayer:extension-okhttp:$exoplayer"
+
+ // date formatter
+ implementation 'org.ocpsoft.prettytime:prettytime:4.0.4.Final'
+
+ // Version comparison
+ implementation 'org.apache.maven:maven-artifact:3.5.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"
+ implementation "androidx.room:room-ktx:$room_version"
+ kapt "androidx.room:room-compiler:$room_version"
// Lifecycle components
- implementation "androidx.lifecycle:lifecycle-extensions:$archLifecycleVersion"
- annotationProcessor "androidx.lifecycle:lifecycle-common-java8:$archLifecycleVersion"
+ implementation "androidx.lifecycle:lifecycle-extensions:$lifecycleVersion"
+ kapt "androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion"
+ implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion"
+ implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion"
+ implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion"
- implementation 'androidx.preference:preference:1.1.1'
+
+ implementation 'androidx.preference:preference-ktx:1.1.1'
+
+ // testing
+ testImplementation 'junit:junit:4.13'
+ androidTestImplementation 'androidx.test:runner:1.3.0'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
+ androidTestImplementation "androidx.room:room-testing:$room_version"
}
+
+tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ee09a9b..3091705 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -49,7 +49,7 @@
android:label="@string/title_activity_settings"
android:theme="@style/AppTheme.NoActionBar" />
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.activity;
@@ -37,6 +36,7 @@ import net.schueller.peertube.R;
import net.schueller.peertube.adapter.ChannelAdapter;
import net.schueller.peertube.adapter.VideoAdapter;
import net.schueller.peertube.helper.APIUrlHelper;
+import net.schueller.peertube.helper.ErrorHelper;
import net.schueller.peertube.helper.MetaDataHelper;
import net.schueller.peertube.model.Account;
import net.schueller.peertube.model.Avatar;
@@ -96,7 +96,7 @@ public class AccountActivity extends CommonActivity {
apiBaseURL = APIUrlHelper.getUrlWithVersion(this);
- userService = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetUserService.class);
+ userService = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(this)).create(GetUserService.class);
recyclerViewVideos = findViewById(R.id.account_video_recyclerView);
recyclerViewChannels = findViewById(R.id.account_channel_recyclerView);
@@ -206,7 +206,7 @@ public class AccountActivity extends CommonActivity {
}
} else {
- Toast.makeText(AccountActivity.this, getString(R.string.api_error), Toast.LENGTH_SHORT).show();
+ ErrorHelper.showToastFromCommunicationError( AccountActivity.this, null );
}
@@ -215,7 +215,7 @@ public class AccountActivity extends CommonActivity {
@Override
public void onFailure(@NonNull Call call, @NonNull Throwable t) {
Log.wtf(TAG, t.fillInStackTrace());
- Toast.makeText(AccountActivity.this, getString(R.string.api_error), Toast.LENGTH_SHORT).show();
+ ErrorHelper.showToastFromCommunicationError( AccountActivity.this, t );
}
});
@@ -226,7 +226,7 @@ public class AccountActivity extends CommonActivity {
isLoadingVideos = false;
- GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class);
+ GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(this)).create(GetVideoDataService.class);
Call call;
call = service.getAccountVideosData(displayNameAndHost, videosStart, videosCount, videosSort);
@@ -247,8 +247,7 @@ public class AccountActivity extends CommonActivity {
}
} else{
- Toast.makeText(AccountActivity.this, getString(R.string.api_error), Toast.LENGTH_SHORT).show();
-
+ ErrorHelper.showToastFromCommunicationError( AccountActivity.this, null );
}
isLoadingVideos = false;
@@ -258,7 +257,7 @@ public class AccountActivity extends CommonActivity {
@Override
public void onFailure(@NonNull Call call, @NonNull Throwable t) {
Log.wtf("err", t.fillInStackTrace());
- Toast.makeText(AccountActivity.this, getString(R.string.api_error), Toast.LENGTH_SHORT).show();
+ ErrorHelper.showToastFromCommunicationError( AccountActivity.this, t );
isLoadingVideos = false;
swipeRefreshLayoutVideos.setRefreshing(false);
}
@@ -281,7 +280,7 @@ public class AccountActivity extends CommonActivity {
} else {
- Toast.makeText(AccountActivity.this, getString(R.string.api_error), Toast.LENGTH_SHORT).show();
+ ErrorHelper.showToastFromCommunicationError( AccountActivity.this, null );
}
@@ -290,7 +289,7 @@ public class AccountActivity extends CommonActivity {
@Override
public void onFailure(@NonNull Call call, @NonNull Throwable t) {
Log.wtf(TAG, t.fillInStackTrace());
- Toast.makeText(AccountActivity.this, getString(R.string.api_error), Toast.LENGTH_SHORT).show();
+ ErrorHelper.showToastFromCommunicationError( AccountActivity.this, t );
}
});
}
diff --git a/app/src/main/java/net/schueller/peertube/activity/AppCompatPreferenceActivity.java b/app/src/main/java/net/schueller/peertube/activity/AppCompatPreferenceActivity.java
deleted file mode 100644
index 36d5fe0..0000000
--- a/app/src/main/java/net/schueller/peertube/activity/AppCompatPreferenceActivity.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright 2018 Stefan Schüller
- *
- * 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 .
- */
-
-package net.schueller.peertube.activity;
-
-import android.content.SharedPreferences;
-import android.content.res.Configuration;
-import android.os.Bundle;
-import android.preference.PreferenceActivity;
-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.
- */
-public abstract class AppCompatPreferenceActivity extends PreferenceActivity {
-
- private AppCompatDelegate mDelegate;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- 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
- protected void onPostCreate(Bundle savedInstanceState) {
- super.onPostCreate(savedInstanceState);
- getDelegate().onPostCreate(savedInstanceState);
- }
-
- public ActionBar getSupportActionBar() {
- return getDelegate().getSupportActionBar();
- }
-
-// public void setSupportActionBar(@Nullable Toolbar toolbar) {
-// getDelegate().setSupportActionBar(toolbar);
-// }
-
- @Override
- public MenuInflater getMenuInflater() {
- return getDelegate().getMenuInflater();
- }
-
- @Override
- public void setContentView(@LayoutRes int layoutResID) {
- getDelegate().setContentView(layoutResID);
- }
-
- @Override
- public void setContentView(View view) {
- getDelegate().setContentView(view);
- }
-
- @Override
- public void setContentView(View view, ViewGroup.LayoutParams params) {
- getDelegate().setContentView(view, params);
- }
-
- @Override
- public void addContentView(View view, ViewGroup.LayoutParams params) {
- getDelegate().addContentView(view, params);
- }
-
- @Override
- protected void onPostResume() {
- super.onPostResume();
- getDelegate().onPostResume();
- }
-
- @Override
- protected void onTitleChanged(CharSequence title, int color) {
- super.onTitleChanged(title, color);
- getDelegate().setTitle(title);
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- getDelegate().onConfigurationChanged(newConfig);
- }
-
- @Override
- protected void onStop() {
- super.onStop();
- getDelegate().onStop();
- }
-
- @Override
- protected void onDestroy() {
- super.onDestroy();
- getDelegate().onDestroy();
- }
-
- public void invalidateOptionsMenu() {
- getDelegate().invalidateOptionsMenu();
- }
-
- private AppCompatDelegate getDelegate() {
- if (mDelegate == null) {
- mDelegate = AppCompatDelegate.create(this, null);
- }
- return mDelegate;
- }
-}
diff --git a/app/src/main/java/net/schueller/peertube/activity/CommonActivity.java b/app/src/main/java/net/schueller/peertube/activity/CommonActivity.java
index a733fca..d68ffe4 100644
--- a/app/src/main/java/net/schueller/peertube/activity/CommonActivity.java
+++ b/app/src/main/java/net/schueller/peertube/activity/CommonActivity.java
@@ -1,35 +1,34 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.activity;
import android.content.SharedPreferences;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.os.Bundle;
import android.preference.PreferenceManager;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.appcompat.app.AppCompatDelegate;
+import net.schueller.peertube.R;
import java.util.Locale;
-import static net.schueller.peertube.helper.Constants.DEFAULT_THEME;
-import static net.schueller.peertube.helper.Constants.THEME_PREF_KEY;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.app.AppCompatDelegate;
public class CommonActivity extends AppCompatActivity {
@@ -39,30 +38,45 @@ public class CommonActivity extends AppCompatActivity {
// Set Night Mode
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
- AppCompatDelegate.setDefaultNightMode(sharedPref.getBoolean("pref_dark_mode", false) ?
+ AppCompatDelegate.setDefaultNightMode(sharedPref.getBoolean(getString(R.string.pref_dark_mode_key), false) ?
AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO);
// Set theme
setTheme(getResources().getIdentifier(
- sharedPref.getString(THEME_PREF_KEY, DEFAULT_THEME),
+ sharedPref.getString(
+ getString(R.string.pref_theme_key),
+ getString(R.string.app_default_theme)
+ ),
"style",
getPackageName())
);
// Set language
- String countryCode=sharedPref.getString("pref_language_app","en");
- Locale locale=new Locale(countryCode);;
+ String countryCode = sharedPref.getString(getString(R.string.pref_language_app_key), null);
+
+ if (countryCode == null) {
+ return;
+ }
+
+ setLocale(countryCode);
+ }
+
+
+ public void setLocale(String languageCode) {
+
+ Locale locale = new Locale(languageCode);
+
//Neither Chinese language choice was working, found this fix on stack overflow
- if(countryCode.equals("zh-rCN"))
+ if (languageCode.equals("zh-rCN"))
locale = Locale.SIMPLIFIED_CHINESE;
- if(countryCode.equals("zh-rTW"))
+ if (languageCode.equals("zh-rTW"))
locale = Locale.TRADITIONAL_CHINESE;
Locale.setDefault(locale);
- Configuration config = getBaseContext().getResources().getConfiguration();
- config.locale = locale;
- getBaseContext().getResources().updateConfiguration(config,
- getBaseContext().getResources().getDisplayMetrics());
- }
+ Resources resources = getResources();
+ Configuration config = resources.getConfiguration();
+ config.setLocale(locale);
+ resources.updateConfiguration(config, resources.getDisplayMetrics());
+ }
}
diff --git a/app/src/main/java/net/schueller/peertube/activity/MeActivity.java b/app/src/main/java/net/schueller/peertube/activity/MeActivity.java
index 9e0c6da..36388af 100644
--- a/app/src/main/java/net/schueller/peertube/activity/MeActivity.java
+++ b/app/src/main/java/net/schueller/peertube/activity/MeActivity.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.activity;
@@ -31,6 +30,7 @@ import android.widget.TextView;
import net.schueller.peertube.R;
import net.schueller.peertube.helper.APIUrlHelper;
+import net.schueller.peertube.helper.ErrorHelper;
import net.schueller.peertube.model.Avatar;
import net.schueller.peertube.model.Me;
import net.schueller.peertube.network.GetUserService;
@@ -118,7 +118,7 @@ public class MeActivity extends CommonActivity {
String apiBaseURL = APIUrlHelper.getUrlWithVersion(this);
String baseURL = APIUrlHelper.getUrl(this);
- GetUserService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetUserService.class);
+ GetUserService service = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(this)).create(GetUserService.class);
Call call = service.getMe();
@@ -162,6 +162,7 @@ public class MeActivity extends CommonActivity {
@Override
public void onFailure(@NonNull Call call, @NonNull Throwable t) {
+ ErrorHelper.showToastFromCommunicationError( MeActivity.this, t );
account.setVisibility(View.GONE);
}
});
diff --git a/app/src/main/java/net/schueller/peertube/activity/SelectServerActivity.java b/app/src/main/java/net/schueller/peertube/activity/SearchServerActivity.java
similarity index 66%
rename from app/src/main/java/net/schueller/peertube/activity/SelectServerActivity.java
rename to app/src/main/java/net/schueller/peertube/activity/SearchServerActivity.java
index a4c6186..9d9463a 100644
--- a/app/src/main/java/net/schueller/peertube/activity/SelectServerActivity.java
+++ b/app/src/main/java/net/schueller/peertube/activity/SearchServerActivity.java
@@ -1,24 +1,22 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.activity;
import androidx.annotation.NonNull;
-import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -27,40 +25,37 @@ 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;
import android.util.Log;
-import android.util.Patterns;
+import android.view.KeyEvent;
import android.view.View;
-import android.widget.Button;
+import android.view.inputmethod.EditorInfo;
+import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import net.schueller.peertube.R;
-import net.schueller.peertube.adapter.ServerAdapter;
-import net.schueller.peertube.adapter.VideoAdapter;
+import net.schueller.peertube.adapter.ServerSearchAdapter;
import net.schueller.peertube.helper.APIUrlHelper;
+import net.schueller.peertube.helper.ErrorHelper;
import net.schueller.peertube.model.ServerList;
-import net.schueller.peertube.model.VideoList;
import net.schueller.peertube.network.GetServerListDataService;
-import net.schueller.peertube.network.GetVideoDataService;
import net.schueller.peertube.network.RetrofitInstance;
import java.util.ArrayList;
import java.util.Objects;
-import static net.schueller.peertube.helper.Constants.DEFAULT_THEME;
-import static net.schueller.peertube.helper.Constants.THEME_PREF_KEY;
+public class SearchServerActivity extends CommonActivity {
-public class SelectServerActivity extends CommonActivity {
-
- private ServerAdapter serverAdapter;
+ private ServerSearchAdapter serverAdapter;
private SwipeRefreshLayout swipeRefreshLayout;
+ private EditText searchTextView;
+
+ private final static String TAG = "SearchServerActivity";
private int currentStart = 0;
- private int count = 12;
+ private final int count = 12;
+ private String lastSearchtext = "";
private TextView emptyView;
private RecyclerView recyclerView;
@@ -76,7 +71,7 @@ public class SelectServerActivity extends CommonActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_server_selection);
+ setContentView(R.layout.activity_search_server);
// Attaching the layout to the toolbar object
Toolbar toolbar = findViewById(R.id.tool_bar_server_selection);
@@ -89,21 +84,30 @@ public class SelectServerActivity extends CommonActivity {
}
+ TextView.OnEditorActionListener onSearchTextValidated = ( textView, i, keyEvent ) -> {
+ if ( keyEvent != null && keyEvent.getKeyCode() == KeyEvent.KEYCODE_ENTER
+ || i == EditorInfo.IME_ACTION_GO ) {
+ loadServers(currentStart, count, textView.getText().toString());
+ }
+ return false;
+ };
private void loadList() {
recyclerView = findViewById(R.id.serverRecyclerView);
swipeRefreshLayout = findViewById(R.id.serversSwipeRefreshLayout);
+ searchTextView = findViewById(R.id.search_server_input_field );
+ searchTextView.setOnEditorActionListener( onSearchTextValidated );
emptyView = findViewById(R.id.empty_server_selection_view);
- RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(SelectServerActivity.this);
+ RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(SearchServerActivity.this);
recyclerView.setLayoutManager(layoutManager);
- serverAdapter = new ServerAdapter(new ArrayList<>(), this);
+ serverAdapter = new ServerSearchAdapter(new ArrayList<>(), this);
recyclerView.setAdapter(serverAdapter);
- loadServers(currentStart, count);
+ loadServers(currentStart, count, searchTextView.getText().toString() );
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
@@ -119,7 +123,7 @@ public class SelectServerActivity extends CommonActivity {
if (!recyclerView.canScrollVertically(RecyclerView.FOCUS_DOWN)) {
if (!isLoading) {
currentStart = currentStart + count;
- loadServers(currentStart, count);
+ loadServers(currentStart, count, searchTextView.getText().toString());
}
}
}
@@ -131,26 +135,29 @@ public class SelectServerActivity extends CommonActivity {
// Refresh items
if (!isLoading) {
currentStart = 0;
- loadServers(currentStart, count);
+ loadServers(currentStart, count, searchTextView.getText().toString());
}
});
}
-
-
- private void loadServers(int start, int count) {
+ private void loadServers(int start, int count, String searchtext) {
isLoading = true;
GetServerListDataService service = RetrofitInstance.getRetrofitInstance(
- APIUrlHelper.getServerIndexUrl(SelectServerActivity.this)
- ).create(GetServerListDataService.class);
+ APIUrlHelper.getServerIndexUrl(SearchServerActivity.this)
+ , APIUrlHelper.useInsecureConnection(this)).create(GetServerListDataService.class);
+ if ( !searchtext.equals( lastSearchtext ) )
+ {
+ currentStart = 0;
+ lastSearchtext = searchtext;
+ }
Call call;
- call = service.getInstancesData(start, count);
+ call = service.getInstancesData(start, count, searchtext);
Log.d("URL Called", call.request().url() + "");
@@ -183,7 +190,7 @@ public class SelectServerActivity extends CommonActivity {
@Override
public void onFailure(@NonNull Call call, @NonNull Throwable t) {
Log.wtf("err", t.fillInStackTrace());
- Toast.makeText(SelectServerActivity.this, getString(R.string.api_error), Toast.LENGTH_SHORT).show();
+ ErrorHelper.showToastFromCommunicationError( SearchServerActivity.this, t );
isLoading = false;
swipeRefreshLayout.setRefreshing(false);
}
diff --git a/app/src/main/java/net/schueller/peertube/activity/ServerAddressBookActivity.java b/app/src/main/java/net/schueller/peertube/activity/ServerAddressBookActivity.java
deleted file mode 100644
index a398b64..0000000
--- a/app/src/main/java/net/schueller/peertube/activity/ServerAddressBookActivity.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright 2018 Stefan Schüller
- *
- * 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 .
- */
-package net.schueller.peertube.activity;
-
-import android.app.AlertDialog;
-import android.net.Uri;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.View;
-import android.widget.EditText;
-
-import com.google.android.material.floatingactionbutton.FloatingActionButton;
-
-import androidx.annotation.NonNull;
-
-import androidx.appcompat.widget.Toolbar;
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.FragmentTransaction;
-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.Objects;
-
-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
- public boolean onSupportNavigateUp() {
- finish(); // close this activity as oppose to navigating up
- return false;
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_server_address_book);
-
- // Attaching the layout to the toolbar object
- Toolbar toolbar = findViewById(R.id.tool_bar_server_address_book);
- // Setting toolbar as the ActionBar with setSupportActionBar() call
- setSupportActionBar(toolbar);
- Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
- getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_baseline_close_24);
-
- 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) {
-
-
- new AlertDialog.Builder(ServerAddressBookActivity.this)
- .setTitle(getString(R.string.server_book_del_alert_title))
- .setMessage(getString(R.string.server_book_del_alert_msg))
- .setPositiveButton(android.R.string.yes, (dialog, which) -> {
- 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);
- })
- .setNegativeButton(android.R.string.no, (dialog, which) -> {
- adapter.notifyItemChanged(viewHolder.getAdapterPosition());
- })
- .setIcon(android.R.drawable.ic_dialog_alert)
- .show();
-
- }
- });
- 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()
- {
-
- }
-
-}
diff --git a/app/src/main/java/net/schueller/peertube/activity/ServerAddressBookActivity.kt b/app/src/main/java/net/schueller/peertube/activity/ServerAddressBookActivity.kt
new file mode 100644
index 0000000..3c55cfa
--- /dev/null
+++ b/app/src/main/java/net/schueller/peertube/activity/ServerAddressBookActivity.kt
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2020 Stefan Schüller
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package net.schueller.peertube.activity
+
+import android.app.Activity
+import android.app.AlertDialog
+import android.content.DialogInterface
+import android.content.Intent
+import android.os.Bundle
+import android.util.Log
+import android.widget.Toast
+import androidx.activity.viewModels
+import androidx.fragment.app.FragmentManager
+import androidx.preference.PreferenceManager
+import androidx.recyclerview.widget.ItemTouchHelper
+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.databinding.ActivityServerAddressBookBinding
+import net.schueller.peertube.fragment.AddServerFragment
+import net.schueller.peertube.helper.APIUrlHelper
+import net.schueller.peertube.network.Session
+import net.schueller.peertube.service.LoginService
+import java.util.*
+
+class ServerAddressBookActivity : CommonActivity() {
+
+ private val TAG = "ServerAddressBookActivity"
+
+ private val mServerViewModel: ServerViewModel by viewModels()
+ private var addServerFragment: AddServerFragment? = null
+
+ private val fragmentManager: FragmentManager by lazy { supportFragmentManager }
+
+
+ private lateinit var mBinding: ActivityServerAddressBookBinding
+
+
+ override fun onSupportNavigateUp(): Boolean {
+ finish() // close this activity as oppose to navigating up
+ return false
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ mBinding = ActivityServerAddressBookBinding.inflate(layoutInflater)
+ setContentView(mBinding.root)
+
+ // Setting toolbar as the ActionBar with setSupportActionBar() call
+ setSupportActionBar(mBinding.toolBarServerAddressBook)
+ supportActionBar?.apply {
+ setDisplayHomeAsUpEnabled(true)
+ setHomeAsUpIndicator(R.drawable.ic_baseline_close_24)
+ }
+
+
+ showServers()
+
+ mBinding.addServer.setOnClickListener {
+ Log.d(TAG, "Click")
+
+ val fragmentTransaction = fragmentManager.beginTransaction()
+ addServerFragment = AddServerFragment().also {
+ fragmentTransaction.replace(R.id.server_book, it)
+ fragmentTransaction.commit()
+ mBinding.addServer.hide()
+ }
+ }
+ }
+
+ private fun onServerClick(server: Server) {
+
+ val sharedPref = PreferenceManager.getDefaultSharedPreferences(this)
+ val editor = sharedPref.edit()
+ val serverUrl = APIUrlHelper.cleanServerUrl(server.serverHost)
+ editor.putString(getString(R.string.pref_api_base_key), serverUrl)
+ editor.apply()
+
+ // Logout if logged in
+ val session = Session.getInstance()
+ if (session.isLoggedIn) {
+ session.invalidate()
+ }
+
+ // attempt authentication if we have a username
+ if (server.username.isNullOrBlank().not()) {
+ LoginService.Authenticate(server.username, server.password)
+ }
+
+ // close this activity
+ finish()
+ Toast.makeText(this, getString(R.string.server_selection_set_server, serverUrl), Toast.LENGTH_LONG).show()
+ }
+
+ private fun onEditClick(server: Server) {
+ val fragmentTransaction = fragmentManager.beginTransaction()
+ addServerFragment = AddServerFragment.newInstance(server).also {
+ fragmentTransaction.replace(R.id.server_book, it)
+ fragmentTransaction.commit()
+ mBinding.addServer.hide()
+ }
+ }
+
+ private fun showServers() {
+ val adapter = ServerListAdapter(mutableListOf(), { onServerClick(it) }, { onEditClick(it) }).also {
+ mBinding.serverListRecyclerview.adapter = it
+ }
+
+ // Delete items on swipe
+ val helper = ItemTouchHelper(
+ object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
+ override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
+ return false
+ }
+
+ override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
+ AlertDialog.Builder(this@ServerAddressBookActivity)
+ .setTitle(getString(R.string.server_book_del_alert_title))
+ .setMessage(getString(R.string.server_book_del_alert_msg))
+ .setPositiveButton(android.R.string.yes) { _: DialogInterface?, _: Int ->
+ val position = viewHolder.adapterPosition
+ val server = adapter.getServerAtPosition(position)
+// Toast.makeText(ServerAddressBookActivity.this, "Deleting " +
+// server.getServerName(), Toast.LENGTH_LONG).show();
+ // Delete the server
+ mServerViewModel.delete(server)
+ }
+ .setNegativeButton(android.R.string.no) { _: DialogInterface?, _: Int -> adapter.notifyItemChanged(viewHolder.adapterPosition) }
+ .setIcon(android.R.drawable.ic_dialog_alert)
+ .show()
+ }
+ })
+ helper.attachToRecyclerView(mBinding.serverListRecyclerview)
+
+
+ // Update the cached copy of the words in the adapter.
+ mServerViewModel.allServers.observe(this, { servers: List ->
+ adapter.setServers(servers)
+
+ addServerFragment?.let {
+ val fragmentTransaction = fragmentManager.beginTransaction()
+ fragmentTransaction.remove(it)
+ fragmentTransaction.commit()
+ mBinding.addServer.show()
+ }
+ })
+ }
+
+ companion object {
+ const val EXTRA_REPLY = "net.schueller.peertube.room.REPLY"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/net/schueller/peertube/activity/SettingsActivity.java b/app/src/main/java/net/schueller/peertube/activity/SettingsActivity.java
index 52db457..147a3c6 100644
--- a/app/src/main/java/net/schueller/peertube/activity/SettingsActivity.java
+++ b/app/src/main/java/net/schueller/peertube/activity/SettingsActivity.java
@@ -1,32 +1,36 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.activity;
+import android.content.SharedPreferences;
import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.util.Log;
import androidx.appcompat.app.ActionBar;
+import androidx.appcompat.app.AlertDialog.Builder;
import androidx.appcompat.widget.Toolbar;
+import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
+import androidx.preference.SwitchPreference;
+import net.schueller.peertube.BuildConfig;
import net.schueller.peertube.R;
-import java.util.Objects;
-
public class SettingsActivity extends CommonActivity {
@Override
@@ -38,16 +42,72 @@ public class SettingsActivity extends CommonActivity {
.beginTransaction()
.replace(R.id.settings, new SettingsFragment())
.commit();
+
+ // Attaching the layout to the toolbar object
+ Toolbar toolbar = findViewById(R.id.tool_bar_settings);
+ // Setting toolbar as the ActionBar with setSupportActionBar() call
+ setSupportActionBar(toolbar);
+
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
+ actionBar.setHomeAsUpIndicator(R.drawable.ic_baseline_close_24);
}
}
+ @Override
+ public boolean onSupportNavigateUp() {
+ finish(); // close this activity as oppose to navigating up
+ return false;
+ }
+
public static class SettingsFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.root_preferences, rootKey);
+
+ // write Build Time into pref
+ Preference pref = findPreference("pref_buildtime");
+ assert pref != null;
+ pref.setSummary(Long.toString(BuildConfig.BUILD_TIME));
+
+ // double check disabling SSL
+ final SwitchPreference insecure = (SwitchPreference) findPreference("pref_accept_insecure");
+ if (insecure != null) {
+ insecure.setOnPreferenceChangeListener((preference, newValue) -> {
+
+ SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext());
+ SharedPreferences.Editor editor = sharedPref.edit();
+
+ boolean currentValue = sharedPref.getBoolean("pref_accept_insecure", false);
+
+ if (newValue instanceof Boolean && ((Boolean) newValue) != currentValue) {
+ final boolean enable = (Boolean) newValue;
+
+ Log.v("pref", "enable: " + enable);
+ Log.v("pref", "currentValue: " + currentValue);
+
+ if (enable) {
+ new Builder(preference.getContext())
+ .setTitle(R.string.pref_insecure_confirm_title)
+ .setMessage(R.string.pref_insecure_confirm_message)
+ .setIcon(R.drawable.ic_info_black_24dp)
+ .setNegativeButton(R.string.pref_insecure_confirm_no, (dialog, whichButton) -> {
+ // do nothing
+ })
+ .setPositiveButton(R.string.pref_insecure_confirm_yes, (dialog, whichButton) -> {
+ // OK has been pressed => force the new value and update the checkbox display
+ editor.putBoolean("pref_accept_insecure", true);
+ editor.apply();
+ insecure.setChecked(true);
+ }).create().show();
+ // by default ignore the pref change, which can only be validated when OK is pressed
+ return false;
+ }
+ }
+ return true;
+ });
+ }
}
}
}
\ No newline at end of file
diff --git a/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java b/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java
index c4ca315..a760c4a 100644
--- a/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java
+++ b/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.activity;
@@ -50,7 +49,6 @@ 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;
@@ -60,6 +58,8 @@ import com.mikepenz.iconics.IconicsDrawable;
import net.schueller.peertube.R;
import net.schueller.peertube.adapter.VideoAdapter;
import net.schueller.peertube.helper.APIUrlHelper;
+import net.schueller.peertube.helper.ErrorHelper;
+import net.schueller.peertube.model.Video;
import net.schueller.peertube.model.VideoList;
import net.schueller.peertube.network.GetUserService;
import net.schueller.peertube.network.GetVideoDataService;
@@ -70,6 +70,8 @@ import net.schueller.peertube.service.VideoPlayerService;
import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Locale;
import java.util.Set;
import retrofit2.Call;
@@ -320,17 +322,24 @@ public class VideoListActivity extends CommonActivity {
isLoading = true;
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
- String nsfw = sharedPref.getBoolean("pref_show_nsfw", false) ? "both" : "false";
- Set languages = sharedPref.getStringSet("pref_language", null);
+ String nsfw = sharedPref.getBoolean(getString(R.string.pref_show_nsfw_key), false) ? "both" : "false";
+
+ Locale locale = getResources().getConfiguration().locale;
+ String country = locale.getLanguage();
+
+ HashSet countries = new HashSet<>(1);
+ countries.add(country);
+
+ Set languages = sharedPref.getStringSet(getString(R.string.pref_video_language_key), countries);
String apiBaseURL = APIUrlHelper.getUrlWithVersion(this);
- GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class);
+ GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(this)).create(GetVideoDataService.class);
Call call;
if (!searchQuery.equals("")) {
call = service.searchVideosData(start, count, sort, nsfw, searchQuery, filter, languages);
} else if (subscriptions) {
- GetUserService userService = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetUserService.class);
+ GetUserService userService = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(this)).create(GetUserService.class);
call = userService.getVideosSubscripions(start, count, sort);
} else {
call = service.getVideosData(start, count, sort, nsfw, filter, languages);
@@ -349,7 +358,10 @@ public class VideoListActivity extends CommonActivity {
}
if (response.body() != null) {
- videoAdapter.setData(response.body().getVideoArrayList());
+ ArrayList videoList = response.body().getVideoArrayList();
+ if (videoList != null) {
+ videoAdapter.setData(response.body().getVideoArrayList());
+ }
}
// no results show no results message
@@ -369,7 +381,7 @@ public class VideoListActivity extends CommonActivity {
@Override
public void onFailure(@NonNull Call call, @NonNull Throwable t) {
Log.wtf("err", t.fillInStackTrace());
- Toast.makeText(VideoListActivity.this, getString(R.string.api_error), Toast.LENGTH_SHORT).show();
+ ErrorHelper.showToastFromCommunicationError( VideoListActivity.this, t );
isLoading = false;
swipeRefreshLayout.setRefreshing(false);
}
@@ -383,7 +395,7 @@ public class VideoListActivity extends CommonActivity {
// only check when we actually need the permission
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED &&
- sharedPref.getBoolean("pref_torrent_player", false)) {
+ sharedPref.getBoolean(getString(R.string.pref_torrent_player_key), false)) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
}
}
diff --git a/app/src/main/java/net/schueller/peertube/activity/VideoPlayActivity.java b/app/src/main/java/net/schueller/peertube/activity/VideoPlayActivity.java
index aa33eb1..f73041c 100644
--- a/app/src/main/java/net/schueller/peertube/activity/VideoPlayActivity.java
+++ b/app/src/main/java/net/schueller/peertube/activity/VideoPlayActivity.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.activity;
@@ -36,6 +35,7 @@ import android.os.Bundle;
import android.preference.PreferenceManager;
+import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
@@ -56,26 +56,25 @@ import net.schueller.peertube.service.VideoPlayerService;
import java.util.ArrayList;
-import java.util.Objects;
import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentTransaction;
-//import static net.schueller.peertube.helper.Constants.BACKGROUND_PLAY_PREF_KEY;
import static com.google.android.exoplayer2.ui.PlayerNotificationManager.ACTION_PAUSE;
import static com.google.android.exoplayer2.ui.PlayerNotificationManager.ACTION_PLAY;
import static com.google.android.exoplayer2.ui.PlayerNotificationManager.ACTION_STOP;
-import static net.schueller.peertube.helper.Constants.BACKGROUND_AUDIO;
-import static net.schueller.peertube.helper.Constants.DEFAULT_THEME;
-import static net.schueller.peertube.helper.Constants.THEME_PREF_KEY;
+import static net.schueller.peertube.helper.VideoHelper.canEnterPipMode;
public class VideoPlayActivity extends AppCompatActivity {
private static final String TAG = "VideoPlayActivity";
- private static boolean floatMode = false;
+ static boolean floatMode = false;
+
private static final int REQUEST_CODE = 101;
private BroadcastReceiver receiver;
+
//This can only be called when in entering pip mode which can't happen if the device doesn't support pip mode.
@SuppressLint("NewApi")
public void makePipControls() {
@@ -84,7 +83,7 @@ public class VideoPlayActivity extends AppCompatActivity {
ArrayList actions = new ArrayList<>();
- Intent actionIntent = new Intent(BACKGROUND_AUDIO);
+ Intent actionIntent = new Intent(getString(R.string.app_background_audio));
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), REQUEST_CODE, actionIntent, 0);
@SuppressLint({"NewApi", "LocalSuppress"}) Icon icon = Icon.createWithResource(getApplicationContext(), android.R.drawable.stat_sys_speakerphone);
@SuppressLint({"NewApi", "LocalSuppress"}) RemoteAction remoteAction = new RemoteAction(icon, "close pip", "from pip window custom command", pendingIntent);
@@ -96,21 +95,21 @@ public class VideoPlayActivity extends AppCompatActivity {
remoteAction = new RemoteAction(icon, "play", "stop the media", pendingIntent);
actions.add(remoteAction);
- if (videoPlayerFragment.isPaused()){
- Log.e(TAG,"setting actions with play button");
+ assert videoPlayerFragment != null;
+ if (videoPlayerFragment.isPaused()) {
+ Log.e(TAG, "setting actions with play button");
actionIntent = new Intent(ACTION_PLAY);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), REQUEST_CODE, actionIntent, 0);
icon = Icon.createWithResource(getApplicationContext(), com.google.android.exoplayer2.ui.R.drawable.exo_notification_play);
remoteAction = new RemoteAction(icon, "play", "play the media", pendingIntent);
- actions.add(remoteAction);
} else {
- Log.e(TAG,"setting actions with pause button");
+ Log.e(TAG, "setting actions with pause button");
actionIntent = new Intent(ACTION_PAUSE);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), REQUEST_CODE, actionIntent, 0);
icon = Icon.createWithResource(getApplicationContext(), com.google.android.exoplayer2.ui.R.drawable.exo_notification_pause);
remoteAction = new RemoteAction(icon, "pause", "pause the media", pendingIntent);
- actions.add(remoteAction);
}
+ actions.add(remoteAction);
//add custom actions to pip window
@@ -119,12 +118,13 @@ public class VideoPlayActivity extends AppCompatActivity {
.setActions(actions)
.build();
setPictureInPictureParams(params);
-
}
+
public void changedToPipMode() {
FragmentManager fragmentManager = getSupportFragmentManager();
VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment) fragmentManager.findFragmentById(R.id.video_player_fragment);
+ assert videoPlayerFragment != null;
videoPlayerFragment.showControls(false);
//create custom actions
makePipControls();
@@ -134,11 +134,12 @@ public class VideoPlayActivity extends AppCompatActivity {
filter.addAction(ACTION_STOP);
filter.addAction(ACTION_PAUSE);
filter.addAction(ACTION_PLAY);
- filter.addAction((BACKGROUND_AUDIO));
+ filter.addAction((getString(R.string.app_background_audio)));
receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
+ assert action != null;
if (action.equals(ACTION_PAUSE)) {
videoPlayerFragment.pauseVideo();
makePipControls();
@@ -148,7 +149,7 @@ public class VideoPlayActivity extends AppCompatActivity {
makePipControls();
}
- if (action.equals(BACKGROUND_AUDIO)) {
+ if (action.equals(getString(R.string.app_background_audio))) {
unregisterReceiver(receiver);
finish();
}
@@ -161,20 +162,23 @@ public class VideoPlayActivity extends AppCompatActivity {
registerReceiver(receiver, filter);
Log.v(TAG, "switched to pip ");
- floatMode=true;
+ floatMode = true;
videoPlayerFragment.showControls(false);
}
- public void changedToNormalMode(){
+
+ public void changedToNormalMode() {
FragmentManager fragmentManager = getSupportFragmentManager();
VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment) fragmentManager.findFragmentById(R.id.video_player_fragment);
+ assert videoPlayerFragment != null;
videoPlayerFragment.showControls(true);
if (receiver != null) {
unregisterReceiver(receiver);
}
- Log.v(TAG,"switched to normal");
- floatMode=false;
+ Log.v(TAG, "switched to normal");
+ floatMode = false;
}
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -182,7 +186,10 @@ public class VideoPlayActivity extends AppCompatActivity {
// Set theme
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
setTheme(getResources().getIdentifier(
- sharedPref.getString(THEME_PREF_KEY, DEFAULT_THEME),
+ sharedPref.getString(
+ getString(R.string.pref_theme_key),
+ getString(R.string.app_default_theme)
+ ),
"style",
getPackageName())
);
@@ -197,17 +204,17 @@ public class VideoPlayActivity extends AppCompatActivity {
assert videoPlayerFragment != null;
String playingVideo = videoPlayerFragment.getVideoUuid();
- Log.v(TAG, "oncreate click: " + videoUuid +" is trying to replace: "+playingVideo);
+ Log.v(TAG, "oncreate click: " + videoUuid + " is trying to replace: " + playingVideo);
- if (TextUtils.isEmpty(playingVideo)){
- Log.v(TAG,"oncreate no video currently playing");
+ if (TextUtils.isEmpty(playingVideo)) {
+ Log.v(TAG, "oncreate no video currently playing");
videoPlayerFragment.start(videoUuid);
- } else if(!playingVideo.equals(videoUuid)){
- Log.v(TAG,"oncreate different video playing currently");
+ } else if (!playingVideo.equals(videoUuid)) {
+ Log.v(TAG, "oncreate different video playing currently");
videoPlayerFragment.stopVideo();
videoPlayerFragment.start(videoUuid);
} else {
- Log.v(TAG,"oncreate same video playing currently");
+ Log.v(TAG, "oncreate same video playing currently");
}
// if we are in landscape set the video to fullscreen
@@ -225,19 +232,18 @@ public class VideoPlayActivity extends AppCompatActivity {
getSupportFragmentManager().findFragmentById(R.id.video_player_fragment);
assert videoPlayerFragment != null;
String videoUuid = intent.getStringExtra(VideoListActivity.EXTRA_VIDEOID);
- Log.v(TAG, "new intent click: " + videoUuid +" is trying to replace: "+videoPlayerFragment.getVideoUuid());
- assert videoPlayerFragment != null;
+ Log.v(TAG, "new intent click: " + videoUuid + " is trying to replace: " + videoPlayerFragment.getVideoUuid());
String playingVideo = videoPlayerFragment.getVideoUuid();
- if (TextUtils.isEmpty(playingVideo)){
- Log.v(TAG,"new intent no video currently playing");
+ if (TextUtils.isEmpty(playingVideo)) {
+ Log.v(TAG, "new intent no video currently playing");
videoPlayerFragment.start(videoUuid);
- } else if(!playingVideo.equals(videoUuid)){
- Log.v(TAG,"new intent different video playing currently");
+ } else if (!playingVideo.equals(videoUuid)) {
+ Log.v(TAG, "new intent different video playing currently");
videoPlayerFragment.stopVideo();
videoPlayerFragment.start(videoUuid);
} else {
- Log.v(TAG,"new intent same video playing currently");
+ Log.v(TAG, "new intent same video playing currently");
}
// if we are in landscape set the video to fullscreen
@@ -245,12 +251,10 @@ public class VideoPlayActivity extends AppCompatActivity {
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
setOrientation(true);
}
-
}
@Override
- public void onConfigurationChanged(Configuration newConfig) {
-
+ public void onConfigurationChanged(@NonNull Configuration newConfig) {
Log.v(TAG, "onConfigurationChanged()...");
super.onConfigurationChanged(newConfig);
@@ -263,58 +267,48 @@ public class VideoPlayActivity extends AppCompatActivity {
}
}
-
-
private void setOrientation(Boolean isLandscape) {
-
FragmentManager fragmentManager = getSupportFragmentManager();
VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment) fragmentManager.findFragmentById(R.id.video_player_fragment);
VideoMetaDataFragment videoMetaFragment = (VideoMetaDataFragment) fragmentManager.findFragmentById(R.id.video_meta_data_fragment);
- if (isLandscape) {
- assert videoPlayerFragment != null;
- RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) Objects.requireNonNull(videoPlayerFragment.getView()).getLayoutParams();
- params.width = FrameLayout.LayoutParams.MATCH_PARENT;
- params.height = FrameLayout.LayoutParams.MATCH_PARENT;
- videoPlayerFragment.getView().setLayoutParams(params);
+ assert videoPlayerFragment != null;
+ RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) videoPlayerFragment.requireView().getLayoutParams();
+ params.width = FrameLayout.LayoutParams.MATCH_PARENT;
+ params.height = isLandscape ? FrameLayout.LayoutParams.MATCH_PARENT : (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 250, getResources().getDisplayMetrics());
- if (videoMetaFragment != null) {
- fragmentManager.beginTransaction()
- .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)
- .hide(videoMetaFragment)
- .commit();
+ videoPlayerFragment.requireView().setLayoutParams(params);
+
+ if (videoMetaFragment != null) {
+ FragmentTransaction transaction = fragmentManager.beginTransaction()
+ .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
+
+ if (isLandscape) {
+ transaction.hide(videoMetaFragment);
+ } else {
+ transaction.show(videoMetaFragment);
}
- videoPlayerFragment.setIsFullscreen(true);
- } else {
- assert videoPlayerFragment != null;
- RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) Objects.requireNonNull(videoPlayerFragment.getView()).getLayoutParams();
- params.width = FrameLayout.LayoutParams.MATCH_PARENT;
- params.height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 250, getResources().getDisplayMetrics());
- videoPlayerFragment.getView().setLayoutParams(params);
-
- if (videoMetaFragment != null) {
- fragmentManager.beginTransaction()
- .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)
- .show(videoMetaFragment)
- .commit();
- }
- videoPlayerFragment.setIsFullscreen(false);
+ transaction.commit();
}
- getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ videoPlayerFragment.setIsFullscreen(isLandscape);
+
+ if ( isLandscape ) {
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ } else {
+ getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
+ }
}
@Override
protected void onDestroy() {
-
VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment)
getSupportFragmentManager().findFragmentById(R.id.video_player_fragment);
assert videoPlayerFragment != null;
videoPlayerFragment.destroyVideo();
-
super.onDestroy();
Log.v(TAG, "onDestroy...");
}
@@ -335,15 +329,6 @@ public class VideoPlayActivity extends AppCompatActivity {
protected void onStop() {
super.onStop();
-// SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
-//
-// Log.v(TAG, "" + sharedPref.getBoolean(BACKGROUND_PLAY_PREF_KEY, false));
-//
-// if (!sharedPref.getBoolean(BACKGROUND_PLAY_PREF_KEY, false)) {
-// Log.v(TAG, "BACKGROUND_PLAY_PREF_KEY...");
-// stopService(new Intent(this, VideoPlayerService.class));
-// }
-
VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment)
getSupportFragmentManager().findFragmentById(R.id.video_player_fragment);
@@ -362,120 +347,155 @@ public class VideoPlayActivity extends AppCompatActivity {
@SuppressLint("NewApi")
@Override
- public void onUserLeaveHint () {
+ public void onUserLeaveHint() {
+
+ Log.v(TAG, "onUserLeaveHint()...");
+
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
FragmentManager fragmentManager = getSupportFragmentManager();
VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment) fragmentManager.findFragmentById(R.id.video_player_fragment);
- VideoMetaDataFragment videoMetaFragment = (VideoMetaDataFragment) fragmentManager.findFragmentById(R.id.video_meta_data_fragment);
- String backgroundBehavior = sharedPref.getString("pref_background_behavior","backgroundStop");
+ VideoMetaDataFragment videoMetaDataFragment = (VideoMetaDataFragment) fragmentManager.findFragmentById(R.id.video_meta_data_fragment);
- switch(backgroundBehavior){
- case "backgroundStop":
- Log.v(TAG,"stop the video");
- videoPlayerFragment.pauseVideo();
- stopService(new Intent(this, VideoPlayerService.class));
- super.onBackPressed();
- break;
- case "backgroundAudio":
- Log.v(TAG,"play the Audio");
- super.onBackPressed();
- break;
- case "backgroundFloat":
- Log.v(TAG,"play in floating video");
- //canEnterPIPMode makes sure API level is high enough
- if (canEnterPipMode(this)) {
- Log.v(TAG, "enabling pip");
- enterPipMode();
- } else {
- Log.v(TAG, "unable to use pip");
- }
- break;
+ String backgroundBehavior = sharedPref.getString(getString(R.string.pref_background_behavior_key), getString(R.string.pref_background_stop_key));
+
+ assert videoPlayerFragment != null;
+ assert backgroundBehavior != null;
+ if ( videoMetaDataFragment.isLeaveAppExpected() )
+ {
+ super.onUserLeaveHint();
+ return;
}
- Log.v(TAG, "onUserLeaveHint()...");
+
+ if (backgroundBehavior.equals(getString(R.string.pref_background_stop_key))) {
+ Log.v(TAG, "stop the video");
+
+ videoPlayerFragment.pauseVideo();
+ stopService(new Intent(this, VideoPlayerService.class));
+ super.onBackPressed();
+
+ } else if (backgroundBehavior.equals(getString(R.string.pref_background_audio_key))) {
+ Log.v(TAG, "play the Audio");
+ super.onBackPressed();
+
+ } else if (backgroundBehavior.equals(getString(R.string.pref_background_float_key))) {
+ Log.v(TAG, "play in floating video");
+ //canEnterPIPMode makes sure API level is high enough
+ if (canEnterPipMode(this)) {
+ Log.v(TAG, "enabling pip");
+ enterPipMode();
+ } else {
+ Log.v(TAG, "unable to use pip");
+ }
+
+ } else {
+ // Deal with bad entries from older version
+ Log.v(TAG, "No setting, fallback");
+ super.onBackPressed();
+
+ }
+
+
}
- // @RequiresApi(api = Build.VERSION_CODES.O)
+ // @RequiresApi(api = Build.VERSION_CODES.O)
@SuppressLint("NewApi")
public void onBackPressed() {
+ Log.v(TAG, "onBackPressed()...");
+
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment)
getSupportFragmentManager().findFragmentById(R.id.video_player_fragment);
- //copying Youtube behavior to have back button exit full screen.
- if (videoPlayerFragment.getIsFullscreen()){
- Log.v(TAG,"exiting full screen");
+ assert videoPlayerFragment != null;
+
+ // copying Youtube behavior to have back button exit full screen.
+ if (videoPlayerFragment.getIsFullscreen()) {
+ Log.v(TAG, "exiting full screen");
videoPlayerFragment.fullScreenToggle();
return;
}
-
- if (sharedPref.getBoolean("pref_back_pause", true)) {
- assert videoPlayerFragment != null;
+ // pause video if pref is enabled
+ if (sharedPref.getBoolean(getString(R.string.pref_back_pause_key), true)) {
videoPlayerFragment.pauseVideo();
}
- String backgroundBehavior = sharedPref.getString("pref_background_behavior","backgroundStop");
- switch (backgroundBehavior){
- case "backgroundStop":
- Log.v(TAG,"stop the video");
- videoPlayerFragment.pauseVideo();
- stopService(new Intent(this, VideoPlayerService.class));
+ String backgroundBehavior = sharedPref.getString(getString(R.string.pref_background_behavior_key), getString(R.string.pref_background_stop_key));
+
+ assert backgroundBehavior != null;
+
+ if (backgroundBehavior.equals(getString(R.string.pref_background_stop_key))) {
+ Log.v(TAG, "stop the video");
+ videoPlayerFragment.pauseVideo();
+ stopService(new Intent(this, VideoPlayerService.class));
+ super.onBackPressed();
+
+ } else if (backgroundBehavior.equals(getString(R.string.pref_background_audio_key))) {
+ Log.v(TAG, "play the Audio");
+ super.onBackPressed();
+
+ } else if (backgroundBehavior.equals(getString(R.string.pref_background_float_key))) {
+ Log.v(TAG, "play in floating video");
+ //canEnterPIPMode makes sure API level is high enough
+ if (canEnterPipMode(this)) {
+ Log.v(TAG, "enabling pip");
+ enterPipMode();
+ //fixes problem where back press doesn't bring up video list after returning from PIP mode
+ Intent intentSettings = new Intent(this, VideoListActivity.class);
+ this.startActivity(intentSettings);
+ } else {
+ Log.v(TAG, "Unable to enter PIP mode");
super.onBackPressed();
- break;
- case "backgroundAudio":
- Log.v(TAG,"play the Audio");
- super.onBackPressed();
- break;
- case "backgroundFloat":
- Log.v(TAG,"play in floating video");
- //canEnterPIPMode makes sure API level is high enough
- if (canEnterPipMode(this)) {
- Log.v(TAG, "enabling pip");
- enterPipMode();
- //fixes problem where back press doesn't bring up video list after returning from PIP mode
- Intent intentSettings = new Intent(this, VideoListActivity.class);
- this.startActivity(intentSettings);
- } else {
- Log.v(TAG,"Unable to enter PIP mode");
- super.onBackPressed();
- }
- break;
+ }
+
+ } else {
+ // Deal with bad entries from older version
+ Log.v(TAG, "No setting, fallback");
+ super.onBackPressed();
+
}
- Log.v(TAG, "onBackPressed()...");
- }
- public boolean canEnterPipMode(Context context) {
- Log.v(TAG,"api version "+Build.VERSION.SDK_INT);
- if (Build.VERSION.SDK_INT<28){
- return false;
- }
- AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
- return (AppOpsManager.MODE_ALLOWED== appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_PICTURE_IN_PICTURE, android.os.Process.myUid(), context.getPackageName()));
+
+
}
+
@RequiresApi(api = Build.VERSION_CODES.O)
public void enterPipMode() {
- Rational rational = new Rational(239, 100);
- Log.v(TAG,rational.toString());
- PictureInPictureParams mParams =
- new PictureInPictureParams.Builder()
- .setAspectRatio(rational)
-// .setSourceRectHint(new Rect(0,500,400,600))
- .build();
+ final FragmentManager fragmentManager = getSupportFragmentManager();
+ final VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment) fragmentManager.findFragmentById( R.id.video_player_fragment );
- enterPictureInPictureMode(mParams);
+ if ( videoPlayerFragment.getVideoAspectRatio() == 0 ) {
+ Log.i( TAG, "impossible to switch to pip" );
+ } else {
+ Rational rational = new Rational( (int) ( videoPlayerFragment.getVideoAspectRatio() * 100 ), 100 );
+ PictureInPictureParams mParams =
+ new PictureInPictureParams.Builder()
+ .setAspectRatio( rational )
+// .setSourceRectHint(new Rect(0,500,400,600))
+ .build();
+
+ enterPictureInPictureMode( mParams );
+ }
}
+
@Override
- public void onPictureInPictureModeChanged (boolean isInPictureInPictureMode, Configuration newConfig) {
+ public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig) {
FragmentManager fragmentManager = getSupportFragmentManager();
VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment) fragmentManager.findFragmentById(R.id.video_player_fragment);
- if (isInPictureInPictureMode) {
- changedToPipMode();
- Log.v(TAG,"switched to pip ");
- videoPlayerFragment.useController(false);
+ if (videoPlayerFragment != null) {
+
+ if (isInPictureInPictureMode) {
+ changedToPipMode();
+ Log.v(TAG, "switched to pip ");
+ videoPlayerFragment.useController(false);
+ } else {
+ changedToNormalMode();
+ Log.v(TAG, "switched to normal");
+ videoPlayerFragment.useController(true);
+ }
+
} else {
- changedToNormalMode();
- Log.v(TAG,"switched to normal");
- videoPlayerFragment.useController(true);
+ Log.e(TAG, "videoPlayerFragment is NULL");
}
}
diff --git a/app/src/main/java/net/schueller/peertube/adapter/ChannelAdapter.java b/app/src/main/java/net/schueller/peertube/adapter/ChannelAdapter.java
index ed4f2ea..3e92433 100644
--- a/app/src/main/java/net/schueller/peertube/adapter/ChannelAdapter.java
+++ b/app/src/main/java/net/schueller/peertube/adapter/ChannelAdapter.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.adapter;
@@ -160,7 +159,7 @@ public class ChannelAdapter extends RecyclerView.Adapter
- *
- * 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 .
- */
-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 {
-
-
- private final LayoutInflater mInflater;
- private List 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 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);
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/net/schueller/peertube/adapter/ServerListAdapter.kt b/app/src/main/java/net/schueller/peertube/adapter/ServerListAdapter.kt
new file mode 100644
index 0000000..e749ffe
--- /dev/null
+++ b/app/src/main/java/net/schueller/peertube/adapter/ServerListAdapter.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 Stefan Schüller
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package net.schueller.peertube.adapter
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import net.schueller.peertube.adapter.ServerListAdapter.ServerViewHolder
+import net.schueller.peertube.database.Server
+import net.schueller.peertube.databinding.RowServerAddressBookBinding
+import net.schueller.peertube.utils.visibleIf
+
+class ServerListAdapter(private val mServers: MutableList, private val onClick: (Server) -> Unit, private val onEditClick: (Server) -> Unit) : RecyclerView.Adapter() {
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ServerViewHolder {
+
+ val binding = RowServerAddressBookBinding.inflate(LayoutInflater.from(parent.context), parent, false)
+
+ return ServerViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: ServerViewHolder, position: Int) {
+ holder.bind(mServers[position])
+ }
+
+ fun setServers(servers: List) {
+ mServers.clear()
+ mServers.addAll(servers)
+
+ notifyDataSetChanged()
+ }
+
+ override fun getItemCount(): Int {
+ return mServers.size
+ }
+
+ inner class ServerViewHolder (private val binding: RowServerAddressBookBinding) : RecyclerView.ViewHolder(binding.root) {
+
+ fun bind(server: Server) {
+
+ binding.serverLabelRow.text = server.serverName
+ binding.serverUrlRow.text = server.serverHost
+ binding.sbRowHasLoginIcon.visibleIf { server.username.isNullOrBlank().not() }
+
+ binding.root.setOnClickListener { onClick(server) }
+ binding.editIcon.setOnClickListener { onEditClick(server) }
+ }
+ }
+
+ fun getServerAtPosition(position: Int): Server {
+ return mServers[position]
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/net/schueller/peertube/adapter/ServerAdapter.java b/app/src/main/java/net/schueller/peertube/adapter/ServerSearchAdapter.java
similarity index 56%
rename from app/src/main/java/net/schueller/peertube/adapter/ServerAdapter.java
rename to app/src/main/java/net/schueller/peertube/adapter/ServerSearchAdapter.java
index 7bde807..6a2c74f 100644
--- a/app/src/main/java/net/schueller/peertube/adapter/ServerAdapter.java
+++ b/app/src/main/java/net/schueller/peertube/adapter/ServerSearchAdapter.java
@@ -1,35 +1,32 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
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;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import net.schueller.peertube.R;
-import net.schueller.peertube.activity.SelectServerActivity;
+import net.schueller.peertube.activity.SearchServerActivity;
import net.schueller.peertube.helper.APIUrlHelper;
import net.schueller.peertube.model.Server;
@@ -38,17 +35,19 @@ import java.util.ArrayList;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
+import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
+
import static android.app.Activity.RESULT_OK;
-public class ServerAdapter extends RecyclerView.Adapter {
+public class ServerSearchAdapter extends RecyclerView.Adapter {
private ArrayList serverList;
- private SelectServerActivity activity;
+ private SearchServerActivity activity;
private String baseUrl;
- public ServerAdapter(ArrayList serverList, SelectServerActivity activity) {
+ public ServerSearchAdapter(ArrayList serverList, SearchServerActivity activity) {
this.serverList = serverList;
this.activity = activity;
}
@@ -57,7 +56,7 @@ public class ServerAdapter extends RecyclerView.Adapter= 0) {
+ // show NSFW Icon
+ if (serverList.get(position).getNSFW()) {
+ holder.isNSFW.setVisibility(View.VISIBLE);
+ }
+ }
+
+
+ // select server
holder.itemView.setOnClickListener(v -> {
-// 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();
-//
-//
-
Toast.makeText(activity, activity.getString(R.string.server_selection_set_server, serverUrl), Toast.LENGTH_LONG).show();
Intent intent = new Intent();
@@ -138,17 +155,19 @@ public class ServerAdapter extends RecyclerView.Adapter
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.adapter;
@@ -63,7 +62,7 @@ public class VideoAdapter extends RecyclerView.Adapter
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.application;
diff --git a/app/src/main/java/net/schueller/peertube/database/AppDatabase.java b/app/src/main/java/net/schueller/peertube/database/AppDatabase.java
index bc1643e..79833de 100644
--- a/app/src/main/java/net/schueller/peertube/database/AppDatabase.java
+++ b/app/src/main/java/net/schueller/peertube/database/AppDatabase.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.database;
diff --git a/app/src/main/java/net/schueller/peertube/database/Server.java b/app/src/main/java/net/schueller/peertube/database/Server.java
deleted file mode 100644
index 5c0f7e1..0000000
--- a/app/src/main/java/net/schueller/peertube/database/Server.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright 2018 Stefan Schüller
- *
- * 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 .
- */
-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;
- }
-}
diff --git a/app/src/main/java/net/schueller/peertube/database/Server.kt b/app/src/main/java/net/schueller/peertube/database/Server.kt
new file mode 100644
index 0000000..19f9d7f
--- /dev/null
+++ b/app/src/main/java/net/schueller/peertube/database/Server.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2020 Stefan Schüller
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package net.schueller.peertube.database
+
+import android.os.Parcelable
+import androidx.room.PrimaryKey
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import kotlinx.android.parcel.Parcelize
+
+@Parcelize
+@Entity(tableName = "server_table")
+data class Server(
+
+ @PrimaryKey(autoGenerate = true)
+ var id: Int = 0,
+
+ @ColumnInfo(name = "server_name")
+ var serverName: String,
+
+ @ColumnInfo(name = "server_host")
+ var serverHost: String? = null,
+
+ @ColumnInfo(name = "username")
+ var username: String? = null,
+
+ @ColumnInfo(name = "password")
+ var password: String? = null
+
+) : Parcelable
\ No newline at end of file
diff --git a/app/src/main/java/net/schueller/peertube/database/ServerDao.java b/app/src/main/java/net/schueller/peertube/database/ServerDao.java
deleted file mode 100644
index e01ef5f..0000000
--- a/app/src/main/java/net/schueller/peertube/database/ServerDao.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2018 Stefan Schüller
- *
- * 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 .
- */
-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> getAllServers();
-}
\ No newline at end of file
diff --git a/app/src/main/java/net/schueller/peertube/database/ServerDao.kt b/app/src/main/java/net/schueller/peertube/database/ServerDao.kt
new file mode 100644
index 0000000..a8d42ee
--- /dev/null
+++ b/app/src/main/java/net/schueller/peertube/database/ServerDao.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2020 Stefan Schüller
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package net.schueller.peertube.database
+
+import androidx.lifecycle.LiveData
+import androidx.room.*
+
+@Dao
+interface ServerDao {
+
+ @Insert
+ suspend fun insert(server: Server)
+
+ @Update
+ suspend fun update(server: Server)
+
+ @Query("DELETE FROM server_table")
+ suspend fun deleteAll()
+
+ @Delete
+ suspend fun delete(server: Server)
+
+ @get:Query("SELECT * from server_table ORDER BY server_name DESC")
+ val allServers: LiveData>
+}
\ No newline at end of file
diff --git a/app/src/main/java/net/schueller/peertube/database/ServerRepository.java b/app/src/main/java/net/schueller/peertube/database/ServerRepository.java
deleted file mode 100644
index 001cb7c..0000000
--- a/app/src/main/java/net/schueller/peertube/database/ServerRepository.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2018 Stefan Schüller
- *
- * 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 .
- */
-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> mAllServers;
-
- ServerRepository(Application application) {
- ServerRoomDatabase db = ServerRoomDatabase.getDatabase(application);
- mServerDao = db.serverDao();
- mAllServers = mServerDao.getAllServers();
-
- }
-
- LiveData> 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 {
-
- 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 {
- private ServerDao mAsyncTaskDao;
-
- deleteServerAsyncTask(ServerDao dao) {
- mAsyncTaskDao = dao;
- }
-
- @Override
- protected Void doInBackground(final Server... params) {
- mAsyncTaskDao.delete(params[0]);
- return null;
- }
- }
-}
diff --git a/app/src/main/java/net/schueller/peertube/database/ServerRepository.kt b/app/src/main/java/net/schueller/peertube/database/ServerRepository.kt
new file mode 100644
index 0000000..871b9a9
--- /dev/null
+++ b/app/src/main/java/net/schueller/peertube/database/ServerRepository.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2020 Stefan Schüller
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package net.schueller.peertube.database
+
+import android.app.Application
+import android.os.AsyncTask
+import androidx.lifecycle.LiveData
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+
+internal class ServerRepository(application: Application) {
+
+ private val mServerDao: ServerDao
+
+ val allServers: LiveData>
+ get() = mServerDao.allServers
+
+ init {
+ val db = ServerRoomDatabase.getDatabase(application)
+ mServerDao = db.serverDao()
+ }
+
+ suspend fun update(server: Server) = withContext(Dispatchers.IO) {
+ mServerDao.update(server)
+ }
+
+ suspend fun insert(server: Server) = withContext(Dispatchers.IO) {
+ mServerDao.insert(server)
+ }
+
+ suspend fun delete(server: Server) = withContext(Dispatchers.IO){
+ mServerDao.delete(server)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/net/schueller/peertube/database/ServerRoomDatabase.java b/app/src/main/java/net/schueller/peertube/database/ServerRoomDatabase.java
index deb79a2..b6b9281 100644
--- a/app/src/main/java/net/schueller/peertube/database/ServerRoomDatabase.java
+++ b/app/src/main/java/net/schueller/peertube/database/ServerRoomDatabase.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.database;
diff --git a/app/src/main/java/net/schueller/peertube/database/ServerViewModel.java b/app/src/main/java/net/schueller/peertube/database/ServerViewModel.java
deleted file mode 100644
index bdd9b1c..0000000
--- a/app/src/main/java/net/schueller/peertube/database/ServerViewModel.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2018 Stefan Schüller
- *
- * 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 .
- */
-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> mAllServers;
-
- public ServerViewModel (Application application) {
- super(application);
- mRepository = new ServerRepository(application);
- mAllServers = mRepository.getAllServers();
- }
-
- public LiveData> getAllServers() { return mAllServers; }
-
- public void insert(Server server) { mRepository.insert(server); }
-
- public void delete(Server server) {mRepository.delete(server);}
-
-}
diff --git a/app/src/main/java/net/schueller/peertube/database/ServerViewModel.kt b/app/src/main/java/net/schueller/peertube/database/ServerViewModel.kt
new file mode 100644
index 0000000..da17ef9
--- /dev/null
+++ b/app/src/main/java/net/schueller/peertube/database/ServerViewModel.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2020 Stefan Schüller
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package net.schueller.peertube.database
+
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.viewModelScope
+import kotlinx.coroutines.launch
+
+class ServerViewModel(application: Application) : AndroidViewModel(application) {
+
+ private val mRepository: ServerRepository = ServerRepository(application)
+ val allServers: LiveData> = mRepository.allServers
+
+ fun insert(server: Server) {
+ viewModelScope.launch {
+ mRepository.insert(server)
+ }
+ }
+
+ fun update(server: Server) {
+ viewModelScope.launch {
+ mRepository.update(server)
+ }
+ }
+
+ fun delete(server: Server) {
+ viewModelScope.launch {
+ mRepository.delete(server)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/net/schueller/peertube/fragment/AddServerFragment.java b/app/src/main/java/net/schueller/peertube/fragment/AddServerFragment.java
deleted file mode 100644
index 6e15a2b..0000000
--- a/app/src/main/java/net/schueller/peertube/fragment/AddServerFragment.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright 2018 Stefan Schüller
- *
- * 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 .
- */
-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);
- }
-}
diff --git a/app/src/main/java/net/schueller/peertube/fragment/AddServerFragment.kt b/app/src/main/java/net/schueller/peertube/fragment/AddServerFragment.kt
new file mode 100644
index 0000000..2bfc3be
--- /dev/null
+++ b/app/src/main/java/net/schueller/peertube/fragment/AddServerFragment.kt
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2020 Stefan Schüller
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package net.schueller.peertube.fragment
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import android.util.Log
+import android.util.Patterns
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Toast
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
+import net.schueller.peertube.R
+import net.schueller.peertube.activity.SearchServerActivity
+import net.schueller.peertube.database.Server
+import net.schueller.peertube.database.ServerViewModel
+import net.schueller.peertube.databinding.FragmentAddServerBinding
+import net.schueller.peertube.helper.APIUrlHelper
+import net.schueller.peertube.utils.hideKeyboard
+
+class AddServerFragment : Fragment() {
+
+
+ private lateinit var mBinding: FragmentAddServerBinding
+
+ private val mServerViewModel: ServerViewModel by activityViewModels()
+
+ private var mServer: Server? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ arguments?.let {
+ mServer = it.getParcelable(SERVER_ARG)
+ }
+ }
+
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ mBinding = FragmentAddServerBinding.inflate(inflater, container, false)
+ return mBinding.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ initServerEdit()
+
+ mBinding.addServerButton.setOnClickListener {
+ var formValid = true
+
+ hideKeyboard()
+
+ if (mBinding.serverLabel.text.toString().isBlank()) {
+ mBinding.serverLabel.error = getString(R.string.server_book_label_is_required)
+ Toast.makeText(context, R.string.invalid_url, Toast.LENGTH_LONG).show()
+ formValid = false
+ }
+
+ // validate url
+ mBinding.serverUrl.apply {
+ APIUrlHelper.cleanServerUrl(text.toString())?.let {
+
+ setText(it)
+
+ if (!Patterns.WEB_URL.matcher(it).matches()) {
+ error = getString(R.string.server_book_valid_url_is_required)
+ Toast.makeText(context, R.string.invalid_url, Toast.LENGTH_LONG).show()
+ formValid = false
+ }
+ }
+ }
+
+
+ if (formValid) {
+ mServer?.apply {
+ mBinding.let {
+ serverName = it.serverLabel.text.toString()
+ serverHost = it.serverUrl.text.toString()
+ username = it.serverUsername.text.toString()
+ password = it.serverPassword.text.toString()
+
+ mServerViewModel.update(this)
+ }
+ return@setOnClickListener
+ }
+
+ mBinding.apply {
+ val server = Server(serverName = serverLabel.text.toString())
+
+ server.serverHost = serverUrl.text.toString()
+ server.username = serverUsername.text.toString()
+ server.password = serverPassword.text.toString()
+
+ mServerViewModel.insert(server)
+ }
+ }
+ }
+
+ mBinding.pickServerUrl.setOnClickListener {
+ val intentServer = Intent(activity, SearchServerActivity::class.java)
+ this.startActivityForResult(intentServer, PICK_SERVER)
+ }
+ }
+
+ private fun initServerEdit() {
+ mServer?.let {
+ mBinding.apply {
+ serverLabel.setText(it.serverName)
+ serverUrl.setText(it.serverHost)
+ serverUsername.setText(it.username)
+ serverPassword.setText(it.password)
+
+ addServerButton.text = getString(R.string.server_book_add_save_button)
+ }
+ }
+ }
+
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+
+ if (requestCode != PICK_SERVER) {
+ return
+ }
+
+ if (resultCode != Activity.RESULT_OK) {
+ return
+ }
+
+ val serverUrlTest = data?.getStringExtra("serverUrl")
+ //Log.d(TAG, "serverUrl " + serverUrlTest);
+
+ mBinding.serverUrl.setText(serverUrlTest)
+
+ mBinding.serverLabel.apply {
+ if (text.toString().isBlank()) {
+ setText(data?.getStringExtra("serverName"))
+ }
+ }
+
+ }
+
+ companion object {
+ private const val TAG = "AddServerFragment"
+ private const val PICK_SERVER = 1
+
+ private const val SERVER_ARG = "server"
+
+ fun newInstance(server: Server) = AddServerFragment().apply {
+ arguments = Bundle().also {
+ it.putParcelable(SERVER_ARG, server)
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/net/schueller/peertube/fragment/VideoMenuQualityFragment.java b/app/src/main/java/net/schueller/peertube/fragment/VideoMenuQualityFragment.java
index 45420d9..d1de80f 100644
--- a/app/src/main/java/net/schueller/peertube/fragment/VideoMenuQualityFragment.java
+++ b/app/src/main/java/net/schueller/peertube/fragment/VideoMenuQualityFragment.java
@@ -1,22 +1,22 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.fragment;
+import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
@@ -44,7 +44,7 @@ public class VideoMenuQualityFragment extends BottomSheetDialogFragment {
public static final String TAG = "VideoMenuQuality";
private static File autoQualityFile;
- public static VideoMenuQualityFragment newInstance(ArrayList files) {
+ public static VideoMenuQualityFragment newInstance(Context context, ArrayList files) {
mFiles = files;
@@ -53,7 +53,7 @@ public class VideoMenuQualityFragment extends BottomSheetDialogFragment {
autoQualityFile = new File();
Resolution autoQualityResolution = new Resolution();
autoQualityResolution.setId(0);
- autoQualityResolution.setLabel("Auto");
+ autoQualityResolution.setLabel(context.getString(R.string.menu_video_options_quality_automated));
autoQualityFile.setId(0);
autoQualityFile.setResolution(autoQualityResolution);
}
@@ -74,11 +74,11 @@ public class VideoMenuQualityFragment extends BottomSheetDialogFragment {
false);
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext());
- Integer videoQuality = sharedPref.getInt("pref_quality", 0);
+ Integer videoQuality = sharedPref.getInt(getString(R.string.pref_quality_key), 0);
for (File file : mFiles) {
- LinearLayout menuRow = (LinearLayout) inflater.inflate(R.layout.row_popup_menu, null);
+ LinearLayout menuRow = (LinearLayout) inflater.inflate(R.layout.row_popup_menu, container);
TextView iconView = menuRow.findViewById(R.id.video_quality_icon);
iconView.setId(file.getResolution().getId());
@@ -90,7 +90,7 @@ public class VideoMenuQualityFragment extends BottomSheetDialogFragment {
textView.setOnClickListener(view1 -> {
// Log.v(TAG, file.getResolution().getLabel());
SharedPreferences.Editor editor = sharedPref.edit();
- editor.putInt("pref_quality", file.getResolution().getId());
+ editor.putInt(getString(R.string.pref_quality_key), file.getResolution().getId());
editor.apply();
for (File fileV : mFiles) {
diff --git a/app/src/main/java/net/schueller/peertube/fragment/VideoMenuSpeedFragment.java b/app/src/main/java/net/schueller/peertube/fragment/VideoMenuSpeedFragment.java
index 7cf8218..da7a2fa 100644
--- a/app/src/main/java/net/schueller/peertube/fragment/VideoMenuSpeedFragment.java
+++ b/app/src/main/java/net/schueller/peertube/fragment/VideoMenuSpeedFragment.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.fragment;
diff --git a/app/src/main/java/net/schueller/peertube/fragment/VideoMetaDataFragment.java b/app/src/main/java/net/schueller/peertube/fragment/VideoMetaDataFragment.java
index 17558af..d7f30f7 100644
--- a/app/src/main/java/net/schueller/peertube/fragment/VideoMetaDataFragment.java
+++ b/app/src/main/java/net/schueller/peertube/fragment/VideoMetaDataFragment.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.fragment;
@@ -39,6 +38,7 @@ import com.squareup.picasso.Picasso;
import net.schueller.peertube.R;
import net.schueller.peertube.helper.APIUrlHelper;
+import net.schueller.peertube.helper.ErrorHelper;
import net.schueller.peertube.helper.MetaDataHelper;
import net.schueller.peertube.intents.Intents;
import net.schueller.peertube.model.Account;
@@ -65,25 +65,41 @@ public class VideoMetaDataFragment extends Fragment {
private static final String TAG = "VideoMetaDataFragment";
+ private static final String RATING_NONE = "none";
+ private static final String RATING_LIKE = "like";
+ private static final String RATING_DISLIKE = "dislike";
+
private Rating videoRating;
private ColorStateList defaultTextColor;
+ private boolean leaveAppExpected = false;
+
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
-
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_video_meta, container, false);
}
- public void updateVideoMeta(Video video, VideoPlayerService mService) {
+ @Override
+ public void onPause()
+ {
+ leaveAppExpected = false;
+ super.onPause();
+ }
+ public boolean isLeaveAppExpected()
+ {
+ return leaveAppExpected;
+ }
+
+ public void updateVideoMeta(Video video, VideoPlayerService mService) {
Context context = getContext();
Activity activity = getActivity();
String apiBaseURL = APIUrlHelper.getUrlWithVersion(context);
- GetVideoDataService videoDataService = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class);
+ GetVideoDataService videoDataService = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(context)).create(GetVideoDataService.class);
// Thumbs up
Button thumbsUpButton = activity.findViewById(R.id.video_thumbs_up);
@@ -91,26 +107,23 @@ public class VideoMetaDataFragment extends Fragment {
thumbsUpButton.setText(R.string.video_thumbs_up_icon);
new Iconics.IconicsBuilder().ctx(context).on(thumbsUpButton).build();
thumbsUpButton.setOnClickListener(v -> {
- rateVideo(true, video.getId());
+ rateVideo(true, video);
});
- TextView thumbsUpButtonTotal = activity.findViewById(R.id.video_thumbs_up_total);
- thumbsUpButtonTotal.setText(video.getLikes().toString());
-
// Thumbs Down
Button thumbsDownButton = activity.findViewById(R.id.video_thumbs_down);
thumbsDownButton.setText(R.string.video_thumbs_down_icon);
new Iconics.IconicsBuilder().ctx(context).on(thumbsDownButton).build();
thumbsDownButton.setOnClickListener(v -> {
- rateVideo(false, video.getId());
+ rateVideo(false, video);
});
-
// video rating
videoRating = new Rating();
- videoRating.setRating("none"); // default
- updateVideoRating();
+ videoRating.setRating(RATING_NONE); // default
+ updateVideoRating(video);
+ // Retrieve which rating the user gave to this video
if (Session.getInstance().isLoggedIn()) {
Call call = videoDataService.getVideoRating(video.getId());
call.enqueue(new Callback() {
@@ -118,25 +131,26 @@ public class VideoMetaDataFragment extends Fragment {
@Override
public void onResponse(Call call, Response response) {
videoRating = response.body();
- updateVideoRating();
+ updateVideoRating(video);
}
@Override
public void onFailure(Call call, Throwable t) {
-// Toast.makeText(context, "Rating Failed", Toast.LENGTH_SHORT).show();
+ ErrorHelper.showToastFromCommunicationError( getActivity(), t );
+ // Do nothing.
}
});
}
-
- TextView thumbsDownButtonTotal = activity.findViewById(R.id.video_thumbs_down_total);
- thumbsDownButtonTotal.setText(video.getDislikes().toString());
-
// Share
Button videoShareButton = activity.findViewById(R.id.video_share);
videoShareButton.setText(R.string.video_share_icon);
new Iconics.IconicsBuilder().ctx(context).on(videoShareButton).build();
- videoShareButton.setOnClickListener(v -> Intents.Share(context, video));
+ videoShareButton.setOnClickListener(v ->
+ {
+ leaveAppExpected = true;
+ Intents.Share( context, video );
+ } );
// Download
Button videoDownloadButton = activity.findViewById(R.id.video_download);
@@ -145,6 +159,7 @@ public class VideoMetaDataFragment extends Fragment {
videoDownloadButton.setOnClickListener(v -> {
// get permission to store file
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
+ leaveAppExpected = true;
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
Intents.Download(context, video);
@@ -156,7 +171,6 @@ public class VideoMetaDataFragment extends Fragment {
}
});
-
Account account = video.getAccount();
// owner / creator Avatar
@@ -172,7 +186,7 @@ public class VideoMetaDataFragment extends Fragment {
// title / name
- TextView videoName = activity.findViewById(R.id.name);
+ TextView videoName = activity.findViewById(R.id.sl_row_name);
videoName.setText(video.getName());
// created at / views
@@ -198,7 +212,6 @@ public class VideoMetaDataFragment extends Fragment {
TextView videoDescription = activity.findViewById(R.id.description);
videoDescription.setText(video.getDescription());
-
// video privacy
TextView videoPrivacy = activity.findViewById(R.id.video_privacy);
videoPrivacy.setText(video.getPrivacy().getLabel());
@@ -211,7 +224,7 @@ public class VideoMetaDataFragment extends Fragment {
TextView videoLicense = activity.findViewById(R.id.video_license);
videoLicense.setText(video.getLicence().getLabel());
- // video langauge
+ // video language
TextView videoLanguage = activity.findViewById(R.id.video_language);
videoLanguage.setText(video.getLanguage().getLabel());
@@ -219,7 +232,6 @@ public class VideoMetaDataFragment extends Fragment {
TextView videoTags = activity.findViewById(R.id.video_tags);
videoTags.setText(android.text.TextUtils.join(", ", video.getTags()));
-
// more button
TextView moreButton = activity.findViewById(R.id.moreButton);
moreButton.setText(R.string.video_more_icon);
@@ -259,8 +271,7 @@ public class VideoMetaDataFragment extends Fragment {
}
-
- void updateVideoRating() {
+ void updateVideoRating(Video video) {
Button thumbsUpButton = getActivity().findViewById(R.id.video_thumbs_up);
Button thumbsDownButton = getActivity().findViewById(R.id.video_thumbs_down);
@@ -269,68 +280,94 @@ public class VideoMetaDataFragment extends Fragment {
TypedArray a = getContext().obtainStyledAttributes(typedValue.data, new int[]{R.attr.colorPrimary});
int accentColor = a.getColor(0, 0);
- if (videoRating.getRating().equals(getString(R.string.video_rating_none))) {
- thumbsUpButton.setTextColor(defaultTextColor);
- thumbsDownButton.setTextColor(defaultTextColor);
- //Log.v(TAG, getString(R.string.video_rating_none));
-
- } else if (videoRating.getRating().equals(getString(R.string.video_rating_like))) {
- thumbsUpButton.setTextColor(accentColor);
- thumbsDownButton.setTextColor(defaultTextColor);
- //Log.v(TAG, getString(R.string.video_rating_like));
-
- } else if (videoRating.getRating().equals(getString(R.string.video_rating_dislike))) {
- thumbsUpButton.setTextColor(defaultTextColor);
- thumbsDownButton.setTextColor(accentColor);
- //Log.v(TAG, getString(R.string.video_rating_dislike));
-
+ // Change the color of the thumbs
+ switch (videoRating.getRating()) {
+ case RATING_NONE:
+ thumbsUpButton.setTextColor(defaultTextColor);
+ thumbsDownButton.setTextColor(defaultTextColor);
+ break;
+ case RATING_LIKE:
+ thumbsUpButton.setTextColor(accentColor);
+ thumbsDownButton.setTextColor(defaultTextColor);
+ break;
+ case RATING_DISLIKE:
+ thumbsUpButton.setTextColor(defaultTextColor);
+ thumbsDownButton.setTextColor(accentColor);
+ break;
}
+ // Update the texts
+ TextView thumbsDownTotal = getActivity().findViewById(R.id.video_thumbs_down_total);
+ TextView thumbsUpTotal = getActivity().findViewById(R.id.video_thumbs_up_total);
+ thumbsUpTotal.setText(String.valueOf(video.getLikes()));
+ thumbsDownTotal.setText(String.valueOf(video.getDislikes()));
+
a.recycle();
}
- void rateVideo(Boolean rate, Integer videoId) {
-
- // TODO cleanup
-
+ void rateVideo(Boolean like, Video video) {
if (Session.getInstance().isLoggedIn()) {
+ final String ratePayload;
- String ratePayload = getString(R.string.video_rating_none);
-
- if (rate) {
- // thumbsup
- if (videoRating.getRating().equals(getString(R.string.video_rating_none))) {
- ratePayload = getString(R.string.video_rating_like);
- }
- } else {
- // thumbsdown
- if (videoRating.getRating().equals(getString(R.string.video_rating_none))) {
- ratePayload = getString(R.string.video_rating_dislike);
- }
+ switch (videoRating.getRating()) {
+ case RATING_LIKE:
+ ratePayload = like ? RATING_NONE : RATING_DISLIKE;
+ break;
+ case RATING_DISLIKE:
+ ratePayload = like ? RATING_LIKE : RATING_NONE;
+ break;
+ case RATING_NONE:
+ default:
+ ratePayload = like ? RATING_LIKE : RATING_DISLIKE;
+ break;
}
RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json"), "{\"rating\":\"" + ratePayload + "\"}");
String apiBaseURL = APIUrlHelper.getUrlWithVersion(getContext());
- GetVideoDataService videoDataService = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class);
+ GetVideoDataService videoDataService = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(getContext())).create(GetVideoDataService.class);
- Call call = videoDataService.rateVideo(videoId, body);
-
- final String newRating = ratePayload;
+ Call call = videoDataService.rateVideo(video.getId(), body);
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
-
//Log.v(TAG, response.toString());
- // if 20x update likes
+ // if 20x, update likes/dislikes
if (response.isSuccessful()) {
- videoRating.setRating(newRating);
- updateVideoRating();
+ String previousRating = videoRating.getRating();
- // TODO: update count under thumb
+ // Update the likes/dislikes count of the video, if needed.
+ // This is only a visual trick, as the actual like/dislike count has
+ // already been modified on the PeerTube instance.
+ if (!previousRating.equals(ratePayload)) {
+ switch (previousRating) {
+ case RATING_NONE:
+ if (ratePayload.equals(RATING_LIKE)) {
+ video.setLikes(video.getLikes() + 1);
+ } else {
+ video.setDislikes(video.getDislikes() + 1);
+ }
+ break;
+ case RATING_LIKE:
+ video.setLikes(video.getLikes() - 1);
+ if (ratePayload.equals(RATING_DISLIKE)) {
+ video.setDislikes(video.getDislikes() + 1);
+ }
+ break;
+ case RATING_DISLIKE:
+ video.setDislikes(video.getDislikes() - 1);
+ if (ratePayload.equals(RATING_LIKE)) {
+ video.setLikes(video.getLikes() + 1);
+ }
+ break;
+ }
+ }
+
+ videoRating.setRating(ratePayload);
+ updateVideoRating(video);
}
}
@@ -341,9 +378,7 @@ public class VideoMetaDataFragment extends Fragment {
});
} else {
Toast.makeText(getContext(), getString(R.string.video_login_required_for_service), Toast.LENGTH_SHORT).show();
-
}
-
}
}
diff --git a/app/src/main/java/net/schueller/peertube/fragment/VideoOptionsFragment.java b/app/src/main/java/net/schueller/peertube/fragment/VideoOptionsFragment.java
index 212c2d2..6f66fe9 100644
--- a/app/src/main/java/net/schueller/peertube/fragment/VideoOptionsFragment.java
+++ b/app/src/main/java/net/schueller/peertube/fragment/VideoOptionsFragment.java
@@ -1,25 +1,24 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.fragment;
-import android.annotation.SuppressLint;
+import android.content.SharedPreferences;
import android.os.Bundle;
-import android.util.Log;
+import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -28,6 +27,7 @@ import android.widget.TextView;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import com.mikepenz.iconics.Iconics;
+
import net.schueller.peertube.R;
import net.schueller.peertube.model.File;
import net.schueller.peertube.service.VideoPlayerService;
@@ -35,6 +35,7 @@ import net.schueller.peertube.service.VideoPlayerService;
import java.util.ArrayList;
import androidx.annotation.Nullable;
+import androidx.annotation.StringRes;
public class VideoOptionsFragment extends BottomSheetDialogFragment {
@@ -62,32 +63,41 @@ public class VideoOptionsFragment extends BottomSheetDialogFragment {
LinearLayout menuHolder = view.findViewById(R.id.video_options_popup);
// Video Speed
- LinearLayout menuRow = (LinearLayout) inflater.inflate(R.layout.row_popup_menu, null);
+ LinearLayout menuRow = (LinearLayout) inflater.inflate(R.layout.row_popup_menu, container);
TextView iconView = menuRow.findViewById(R.id.video_quality_icon);
TextView textView = menuRow.findViewById(R.id.video_quality_text);
- textView.setText(getString(R.string.menu_video_options_playback_speed));
+
+ textView.setText(
+ getString(
+ R.string.menu_video_options_playback_speed,
+ getCurrentVideoPlaybackSpeedString(videoPlayerService.getPlayBackSpeed()
+ )
+ )
+ );
+
+
iconView.setText(R.string.video_option_speed_icon);
new Iconics.IconicsBuilder().ctx(getContext()).on(iconView).build();
textView.setOnClickListener(view1 -> {
VideoMenuSpeedFragment videoMenuSpeedFragment =
VideoMenuSpeedFragment.newInstance(videoPlayerService);
- videoMenuSpeedFragment.show(getActivity().getSupportFragmentManager(),
+ videoMenuSpeedFragment.show(requireActivity().getSupportFragmentManager(),
VideoMenuSpeedFragment.TAG);
});
menuHolder.addView(menuRow);
// Video Quality
- LinearLayout menuRow2 = (LinearLayout) inflater.inflate(R.layout.row_popup_menu, null);
+ LinearLayout menuRow2 = (LinearLayout) inflater.inflate(R.layout.row_popup_menu, container);
TextView iconView2 = menuRow2.findViewById(R.id.video_quality_icon);
TextView textView2 = menuRow2.findViewById(R.id.video_quality_text);
- textView2.setText(getString(R.string.menu_video_options_quality));
+ textView2.setText(String.format(getString(R.string.menu_video_options_quality), getCurrentVideoQuality(files)));
iconView2.setText(R.string.video_option_quality_icon);
new Iconics.IconicsBuilder().ctx(getContext()).on(iconView2).build();
textView2.setOnClickListener(view1 -> {
VideoMenuQualityFragment videoMenuQualityFragment =
- VideoMenuQualityFragment.newInstance(files);
- videoMenuQualityFragment.show(getActivity().getSupportFragmentManager(),
- videoMenuQualityFragment.TAG);
+ VideoMenuQualityFragment.newInstance(getContext(), files);
+ videoMenuQualityFragment.show(requireActivity().getSupportFragmentManager(),
+ VideoMenuQualityFragment.TAG);
});
menuHolder.addView(menuRow2);
@@ -95,4 +105,26 @@ public class VideoOptionsFragment extends BottomSheetDialogFragment {
}
+ private String getCurrentVideoQuality(ArrayList files) {
+ SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext());
+ Integer videoQuality = sharedPref.getInt(getString(R.string.pref_quality_key), 0);
+
+ for (File file : files) {
+ if (videoQuality.equals(file.getResolution().getId())) {
+ return file.getResolution().getLabel();
+ }
+ }
+ // Returning Automated as a placeholder
+ return getString(R.string.menu_video_options_quality_automated);
+ }
+
+ private String getCurrentVideoPlaybackSpeedString(float playbackSpeed) {
+ String speed = String.valueOf(playbackSpeed);
+ // Remove all non-digit characters from the string
+ speed = speed.replaceAll("[^0-9]", "");
+
+ // Dynamically get the localized string corresponding to the speed
+ @StringRes int stringId = getResources().getIdentifier("video_speed_" + speed, "string", videoPlayerService.getPackageName());
+ return getString(stringId);
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/net/schueller/peertube/fragment/VideoPlayerFragment.java b/app/src/main/java/net/schueller/peertube/fragment/VideoPlayerFragment.java
index 9fad3b3..f63f3de 100644
--- a/app/src/main/java/net/schueller/peertube/fragment/VideoPlayerFragment.java
+++ b/app/src/main/java/net/schueller/peertube/fragment/VideoPlayerFragment.java
@@ -1,24 +1,22 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.fragment;
import android.app.Activity;
-import android.app.AppOpsManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -60,21 +58,23 @@ import com.mikepenz.iconics.Iconics;
import net.schueller.peertube.R;
import net.schueller.peertube.helper.APIUrlHelper;
+import net.schueller.peertube.helper.ErrorHelper;
import net.schueller.peertube.model.File;
import net.schueller.peertube.model.Video;
import net.schueller.peertube.network.GetVideoDataService;
import net.schueller.peertube.network.RetrofitInstance;
import net.schueller.peertube.service.VideoPlayerService;
-import java.util.Objects;
-
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.fragment.app.Fragment;
+
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
+import static net.schueller.peertube.helper.VideoHelper.canEnterPipMode;
+
public class VideoPlayerFragment extends Fragment implements VideoRendererEventListener {
private String mVideoUuid;
@@ -86,6 +86,7 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
private VideoPlayerService mService;
private TorrentStream torrentStream;
private LinearLayout torrentStatus;
+ private float aspectRatio;
private static final String TAG = "VideoPlayerFragment";
private GestureDetector mDetector;
@@ -112,6 +113,14 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
mBound = false;
}
};
+ private AspectRatioFrameLayout.AspectRatioListener aspectRatioListerner = new AspectRatioFrameLayout.AspectRatioListener()
+ {
+ @Override
+ public void onAspectRatioUpdated( float targetAspectRatio, float naturalAspectRatio, boolean aspectRatioMismatch )
+ {
+ aspectRatio = targetAspectRatio;
+ }
+ };
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
@@ -134,6 +143,7 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
progressBar = activity.findViewById(R.id.torrent_progress);
progressBar.setMax(100);
+ assert context != null;
simpleExoPlayerView = new PlayerView(context);
simpleExoPlayerView = activity.findViewById(R.id.video_view);
@@ -143,6 +153,8 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
mDetector = new GestureDetector(context, new MyGestureListener());
simpleExoPlayerView.setOnTouchListener(touchListener);
+ simpleExoPlayerView.setAspectRatioListener( aspectRatioListerner );
+
torrentStatus = activity.findViewById(R.id.exo_torrent_status);
// Full screen Icon
@@ -171,7 +183,7 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
// get video details from api
String apiBaseURL = APIUrlHelper.getUrlWithVersion(context);
- GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class);
+ GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(context)).create(GetVideoDataService.class);
Call call = service.getVideoData(mVideoUuid);
@@ -195,30 +207,31 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
@Override
public void onFailure(@NonNull Call call, @NonNull Throwable t) {
Log.wtf(TAG, t.fillInStackTrace());
- Toast.makeText(context, "Something went wrong: "+t.getLocalizedMessage(), Toast.LENGTH_LONG).show();
+ ErrorHelper.showToastFromCommunicationError( getActivity(), t );
}
});
}
- public void useController(boolean value){
- if (mBound){
+
+ public void useController(boolean value) {
+ if (mBound) {
simpleExoPlayerView.setUseController(value);
}
}
+
private void playVideo(Video video) {
Context context = getContext();
// video Meta fragment
- assert getFragmentManager() != null;
VideoMetaDataFragment videoMetaDataFragment = (VideoMetaDataFragment)
- getFragmentManager().findFragmentById(R.id.video_meta_data_fragment);
+ requireActivity().getSupportFragmentManager().findFragmentById(R.id.video_meta_data_fragment);
assert videoMetaDataFragment != null;
videoMetaDataFragment.updateVideoMeta(video, mService);
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
- if (sharedPref.getBoolean("pref_torrent_player", false)) {
+ if (sharedPref.getBoolean(getString(R.string.pref_torrent_player_key), false)) {
torrentStatus.setVisibility(View.VISIBLE);
String stream = video.getFiles().get(0).getTorrentUrl();
Log.v(TAG, "getTorrentUrl : " + video.getFiles().get(0).getTorrentUrl());
@@ -226,20 +239,25 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
torrentStream.startStream(stream);
} else {
- Integer videoQuality = sharedPref.getInt("pref_quality", 0);
+ Integer videoQuality = sharedPref.getInt(getString(R.string.pref_quality_key), 0);
//get video qualities
- String urlToPlay = video.getFiles().get(0).getFileUrl();
- for (File file :video.getFiles()) {
- // Set quality if it matches
- if (file.getResolution().getId().equals(videoQuality)) {
- urlToPlay = file.getFileUrl();
+ /// #
+ if (video.getFiles().size() > 0) {
+ String urlToPlay = video.getFiles().get( 0 ).getFileUrl();
+ for ( File file : video.getFiles() ) {
+ // Set quality if it matches
+ if ( file.getResolution().getId().equals( videoQuality ) ) {
+ urlToPlay = file.getFileUrl();
+ }
}
+ mService.setCurrentStreamUrl( urlToPlay );
+ torrentStatus.setVisibility(View.GONE);
+ startPlayer();
+ } else {
+ stopVideo();
+ Toast.makeText(context, R.string.api_error, Toast.LENGTH_LONG).show();
}
- mService.setCurrentStreamUrl(urlToPlay);
-
- torrentStatus.setVisibility(View.GONE);
- startPlayer();
}
Log.v(TAG, "end of load Video");
@@ -247,7 +265,7 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
}
private void startPlayer() {
- Util.startForegroundService(Objects.requireNonNull(getContext()), videoPlayerIntent);
+ Util.startForegroundService(requireContext(), videoPlayerIntent);
}
@@ -259,30 +277,37 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
}
public void pauseVideo() {
- if (mBound){
+ if (mBound) {
mService.player.setPlayWhenReady(false);
}
}
+
public void pauseToggle() {
if (mBound) {
mService.player.setPlayWhenReady(!mService.player.getPlayWhenReady());
}
}
+
public void unPauseVideo() {
if (mBound) {
mService.player.setPlayWhenReady(true);
}
}
- public boolean isPaused(){
+
+ public float getVideoAspectRatio() { return aspectRatio; }
+
+ public boolean isPaused() {
return !mService.player.getPlayWhenReady();
}
- public void showControls(boolean value){
+
+ public void showControls(boolean value) {
simpleExoPlayerView.setUseController(value);
}
+
public void stopVideo() {
if (mBound) {
- Objects.requireNonNull(getContext()).unbindService(mConnection);
+ requireContext().unbindService(mConnection);
mBound = false;
}
}
@@ -290,7 +315,7 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
public void setIsFullscreen(Boolean fullscreen) {
isFullscreen = fullscreen;
- TextView fullscreenButton = getActivity().findViewById(R.id.exo_fullscreen);
+ TextView fullscreenButton = requireActivity().findViewById(R.id.exo_fullscreen);
if (fullscreen) {
fullscreenButton.setText(R.string.video_compress_icon);
} else {
@@ -302,15 +327,17 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
public Boolean getIsFullscreen() {
return isFullscreen;
}
+
public void fullScreenToggle() {
if (!isFullscreen) {
setIsFullscreen(true);
- getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+ requireActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else {
setIsFullscreen(false);
- getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
+ requireActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
+
/**
* Torrent Playback
*
@@ -404,18 +431,6 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
Log.v(TAG, "onVideoDisabled()...");
}
- public static boolean canEnterPipMode(Context context) {
- Log.v(TAG,"api version "+Build.VERSION.SDK_INT);
- if (Build.VERSION.SDK_INT<28){
- return false;
- }
- SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
- if (!"BackgroundFloat".equals(sharedPref.getString("pref_background_behavior","backgroundStop"))){
- return false;
- }
- AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
- return (AppOpsManager.MODE_ALLOWED== appOpsManager.checkOpNoThrow(AppOpsManager.OPSTR_PICTURE_IN_PICTURE, android.os.Process.myUid(), context.getPackageName()));
- }
View.OnTouchListener touchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
@@ -423,62 +438,64 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
}
};
- public String getVideoUuid(){
+
+ public String getVideoUuid() {
return mVideoUuid;
}
+
class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
-/*
- @Override
- public boolean onDown(MotionEvent event) {
- Log.d("TAG","onDown: ");
- return true;
- }
+ /*
+ @Override
+ public boolean onDown(MotionEvent event) {
+ Log.d("TAG","onDown: ");
+ return true;
+ }
- @Override
- public boolean onSingleTapConfirmed(MotionEvent e) {
- Log.i("TAG", "onSingleTapConfirmed: ");
- pauseToggle();
- return true;
- }
+ @Override
+ public boolean onSingleTapConfirmed(MotionEvent e) {
+ Log.i("TAG", "onSingleTapConfirmed: ");
+ pauseToggle();
+ return true;
+ }
- @Override
- public void onLongPress(MotionEvent e) {
- Log.i("TAG", "onLongPress: ");
- }
+ @Override
+ public void onLongPress(MotionEvent e) {
+ Log.i("TAG", "onLongPress: ");
+ }
- @Override
- public boolean onDoubleTap(MotionEvent e) {
- Log.i("TAG", "onDoubleTap: ");
- return true;
- }
+ @Override
+ public boolean onDoubleTap(MotionEvent e) {
+ Log.i("TAG", "onDoubleTap: ");
+ return true;
+ }
- @Override
- public boolean onScroll(MotionEvent e1, MotionEvent e2,
- float distanceX, float distanceY) {
- Log.i("TAG", "onScroll: ");
- return true;
- }
-*/
+ @Override
+ public boolean onScroll(MotionEvent e1, MotionEvent e2,
+ float distanceX, float distanceY) {
+ Log.i("TAG", "onScroll: ");
+ return true;
+ }
+ */
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public boolean onFling(MotionEvent event1, MotionEvent event2,
float velocityX, float velocityY) {
- Log.d(TAG ,event1.toString());
- Log.d(TAG,event2.toString());
+ Log.d(TAG, event1.toString());
+ Log.d(TAG, event2.toString());
Log.d(TAG, String.valueOf(velocityX));
- Log.d(TAG , String.valueOf(velocityY));
+ Log.d(TAG, String.valueOf(velocityY));
//arbitrarily velocity speeds that seem to work to differentiate events.
- if (velocityY>4000){
- Log.d(TAG,"we have a drag down event");
+ if (velocityY > 4000) {
+ Log.d(TAG, "we have a drag down event");
if (canEnterPipMode(getContext())) {
- getActivity().enterPictureInPictureMode();
+ requireActivity().enterPictureInPictureMode();
}
}
- if ((velocityX>2000) && (Math.abs(velocityY) <2000)){
- Log.d(TAG,"swipe right "+velocityY);
+ if ((velocityX > 2000) && (Math.abs(velocityY) < 2000)) {
+ Log.d(TAG, "swipe right " + velocityY);
}
- if ((velocityX<2000) && (Math.abs(velocityY)<2000)){
- Log.d(TAG,"swipe left "+velocityY);
+ if ((velocityX < 2000) && (Math.abs(velocityY) < 2000)) {
+ Log.d(TAG, "swipe left " + velocityY);
}
return true;
}
diff --git a/app/src/main/java/net/schueller/peertube/helper/APIUrlHelper.java b/app/src/main/java/net/schueller/peertube/helper/APIUrlHelper.java
index cf24b2f..368427b 100644
--- a/app/src/main/java/net/schueller/peertube/helper/APIUrlHelper.java
+++ b/app/src/main/java/net/schueller/peertube/helper/APIUrlHelper.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.helper;
@@ -32,7 +31,7 @@ public class APIUrlHelper{
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
// validate URL is valid
- String URL = sharedPref.getString("pref_api_base", context.getResources().getString(R.string.pref_default_api_base_url));
+ String URL = sharedPref.getString(context.getString(R.string.pref_api_base_key), context.getResources().getString(R.string.pref_default_api_base_url));
if (!URLUtil.isValidUrl(URL)) {
return "http://invalid";
}
@@ -43,6 +42,11 @@ public class APIUrlHelper{
return APIUrlHelper.getUrl(context) + "/api/v1/";
}
+ public static Boolean useInsecureConnection(Context context) {
+ SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
+ return sharedPref.getBoolean(context.getString(R.string.pref_accept_insecure), false);
+ }
+
public static String getShareUrl(Context context, String videoUuid) {
return APIUrlHelper.getUrl(context) + "/videos/watch/" + videoUuid;
}
diff --git a/app/src/main/java/net/schueller/peertube/helper/Constants.java b/app/src/main/java/net/schueller/peertube/helper/Constants.java
deleted file mode 100644
index 0e87a3f..0000000
--- a/app/src/main/java/net/schueller/peertube/helper/Constants.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2018 Stefan Schüller
- *
- * 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 .
- */
-package net.schueller.peertube.helper;
-
-public class Constants {
- public static final String THEME_PREF_KEY = "pref_theme";
- public static final String DEFAULT_THEME = "AppTheme.BLUE";
- public static final String BACKGROUND_PLAY_PREF_KEY = "pref_background_play";
- public static final String BACKGROUND_AUDIO = "BACKGROUND_AUDIO";
-}
diff --git a/app/src/main/java/net/schueller/peertube/helper/ErrorHelper.java b/app/src/main/java/net/schueller/peertube/helper/ErrorHelper.java
new file mode 100644
index 0000000..e50d701
--- /dev/null
+++ b/app/src/main/java/net/schueller/peertube/helper/ErrorHelper.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 Stefan Schüller
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package net.schueller.peertube.helper;
+
+import android.content.Context;
+import android.widget.Toast;
+
+import net.schueller.peertube.R;
+
+import java.io.IOException;
+
+import retrofit2.HttpException;
+
+public class ErrorHelper {
+
+ public static void showToastFromCommunicationError( Context context, Throwable throwable ) {
+ if (throwable instanceof IOException ) {
+ //handle network error
+ Toast.makeText( context, context.getString( R.string.network_error), Toast.LENGTH_SHORT).show();
+ } else if (throwable instanceof HttpException ) {
+ //handle HTTP error response code
+ Toast.makeText(context, context.getString(R.string.api_error), Toast.LENGTH_SHORT).show();
+ } else {
+ //handle other exceptions
+ Toast.makeText(context, context.getString(R.string.api_error), Toast.LENGTH_SHORT).show();
+ }
+ }
+}
diff --git a/app/src/main/java/net/schueller/peertube/helper/MetaDataHelper.java b/app/src/main/java/net/schueller/peertube/helper/MetaDataHelper.java
index 84e9de9..6546e1c 100644
--- a/app/src/main/java/net/schueller/peertube/helper/MetaDataHelper.java
+++ b/app/src/main/java/net/schueller/peertube/helper/MetaDataHelper.java
@@ -1,34 +1,44 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.helper;
import android.content.Context;
+
import android.text.format.DateUtils;
+
import net.schueller.peertube.R;
-import java.time.Duration;
-import java.time.Period;
+import org.ocpsoft.prettytime.PrettyTime;
+
import java.util.Date;
+import java.util.Locale;
+
public class MetaDataHelper {
+
public static String getMetaString(Date getCreatedAt, Integer viewCount, Context context) {
- return (DateUtils.getRelativeTimeSpanString(context,getCreatedAt.getTime(),false).toString() +
+
+ // Compatible with SDK 21+
+ String currentLanguage = Locale.getDefault().getDisplayLanguage();
+ PrettyTime p = new PrettyTime(currentLanguage);
+ String relativeTime = p.format(new Date(getCreatedAt.getTime()));
+
+ return (relativeTime +
context.getResources().getString(R.string.meta_data_seperator) +
viewCount + context.getResources().getString(R.string.meta_data_views));
}
diff --git a/app/src/main/java/net/schueller/peertube/helper/VideoHelper.java b/app/src/main/java/net/schueller/peertube/helper/VideoHelper.java
new file mode 100644
index 0000000..0482e37
--- /dev/null
+++ b/app/src/main/java/net/schueller/peertube/helper/VideoHelper.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2020 Stefan Schüller
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package net.schueller.peertube.helper;
+
+import android.app.AppOpsManager;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Build;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import net.schueller.peertube.R;
+
+public class VideoHelper {
+
+ private static final String TAG = "VideoHelper";
+
+ public static boolean canEnterPipMode(Context context) {
+
+ SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
+
+ context.getString(R.string.pref_background_float_key);
+
+ // pref is disabled
+ if (!context.getString(R.string.pref_background_float_key).equals(
+ sharedPref.getString(
+ context.getString(R.string.pref_background_behavior_key),
+ context.getString(R.string.pref_background_float_key))
+ )
+ ) {
+ return false;
+ }
+
+ // api does not support it
+ Log.v(TAG, "api version " + Build.VERSION.SDK_INT);
+ if (Build.VERSION.SDK_INT > 27) {
+ AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+ return (AppOpsManager.MODE_ALLOWED == appOpsManager.checkOp(AppOpsManager.OPSTR_PICTURE_IN_PICTURE, android.os.Process.myUid(), context.getPackageName()));
+ }
+ return false;
+ }
+}
diff --git a/app/src/main/java/net/schueller/peertube/intents/Intents.java b/app/src/main/java/net/schueller/peertube/intents/Intents.java
index 6b2dfe3..e813a16 100644
--- a/app/src/main/java/net/schueller/peertube/intents/Intents.java
+++ b/app/src/main/java/net/schueller/peertube/intents/Intents.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.intents;
@@ -27,6 +26,7 @@ import android.os.Build;
import android.os.Environment;
import android.webkit.MimeTypeMap;
import android.webkit.URLUtil;
+import android.widget.Toast;
import com.github.se_bastiaan.torrentstream.TorrentOptions;
@@ -40,6 +40,7 @@ import androidx.core.app.ActivityCompat;
public class Intents {
+ private static final String TAG = "Intents";
/**
* https://troll.tv/videos/watch/6edbd9d1-e3c5-4a6c-8491-646e2020469c
@@ -68,20 +69,25 @@ public class Intents {
// TODO, offer which version to download
public static void Download(Context context, Video video) {
- String url = video.getFiles().get(0).getFileDownloadUrl();
- // make sure it is a valid filename
- String destFilename = video.getName().replaceAll("[^a-zA-Z0-9]", "_") + "." + MimeTypeMap.getFileExtensionFromUrl(URLUtil.guessFileName(url,null,null));
+ if (video.getFiles().size() > 0)
+ {
+ String url = video.getFiles().get( 0 ).getFileDownloadUrl();
+ // make sure it is a valid filename
+ String destFilename = video.getName().replaceAll( "[^a-zA-Z0-9]", "_" ) + "." + MimeTypeMap.getFileExtensionFromUrl( URLUtil.guessFileName( url, null, null ) );
- //Toast.makeText(context, destFilename, Toast.LENGTH_LONG).show();
- DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
- request.setDescription(video.getDescription());
- request.setTitle(video.getName());
- request.allowScanningByMediaScanner();
- request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
- request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, destFilename);
+ //Toast.makeText(context, destFilename, Toast.LENGTH_LONG).show();
+ DownloadManager.Request request = new DownloadManager.Request( Uri.parse( url ) );
+ request.setDescription( video.getDescription() );
+ request.setTitle( video.getName() );
+ request.allowScanningByMediaScanner();
+ request.setNotificationVisibility( DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED );
+ request.setDestinationInExternalPublicDir( Environment.DIRECTORY_DOWNLOADS, destFilename );
- // get download service and enqueue file
- DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
- manager.enqueue(request);
+ // get download service and enqueue file
+ DownloadManager manager = (DownloadManager) context.getSystemService( Context.DOWNLOAD_SERVICE );
+ manager.enqueue( request );
+ } else {
+ Toast.makeText( context, R.string.api_error, Toast.LENGTH_LONG ).show();
+ }
}
}
diff --git a/app/src/main/java/net/schueller/peertube/model/Account.java b/app/src/main/java/net/schueller/peertube/model/Account.java
index 54c5282..c85b008 100644
--- a/app/src/main/java/net/schueller/peertube/model/Account.java
+++ b/app/src/main/java/net/schueller/peertube/model/Account.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.model;
diff --git a/app/src/main/java/net/schueller/peertube/model/Avatar.java b/app/src/main/java/net/schueller/peertube/model/Avatar.java
index 356816d..dfe0fae 100644
--- a/app/src/main/java/net/schueller/peertube/model/Avatar.java
+++ b/app/src/main/java/net/schueller/peertube/model/Avatar.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.model;
diff --git a/app/src/main/java/net/schueller/peertube/model/Category.java b/app/src/main/java/net/schueller/peertube/model/Category.java
index 505da79..a9edc08 100644
--- a/app/src/main/java/net/schueller/peertube/model/Category.java
+++ b/app/src/main/java/net/schueller/peertube/model/Category.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.model;
diff --git a/app/src/main/java/net/schueller/peertube/model/Channel.java b/app/src/main/java/net/schueller/peertube/model/Channel.java
index 28f0aa5..d55097a 100644
--- a/app/src/main/java/net/schueller/peertube/model/Channel.java
+++ b/app/src/main/java/net/schueller/peertube/model/Channel.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.model;
diff --git a/app/src/main/java/net/schueller/peertube/model/ChannelList.java b/app/src/main/java/net/schueller/peertube/model/ChannelList.java
index fbb2a96..bd5204b 100644
--- a/app/src/main/java/net/schueller/peertube/model/ChannelList.java
+++ b/app/src/main/java/net/schueller/peertube/model/ChannelList.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.model;
diff --git a/app/src/main/java/net/schueller/peertube/model/Config.java b/app/src/main/java/net/schueller/peertube/model/Config.java
index 9aa3904..0d6c371 100644
--- a/app/src/main/java/net/schueller/peertube/model/Config.java
+++ b/app/src/main/java/net/schueller/peertube/model/Config.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.model;
diff --git a/app/src/main/java/net/schueller/peertube/model/File.java b/app/src/main/java/net/schueller/peertube/model/File.java
index 4cf30c9..1bdb917 100644
--- a/app/src/main/java/net/schueller/peertube/model/File.java
+++ b/app/src/main/java/net/schueller/peertube/model/File.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.model;
diff --git a/app/src/main/java/net/schueller/peertube/model/Language.java b/app/src/main/java/net/schueller/peertube/model/Language.java
index f1abc74..c3f05ce 100644
--- a/app/src/main/java/net/schueller/peertube/model/Language.java
+++ b/app/src/main/java/net/schueller/peertube/model/Language.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.model;
diff --git a/app/src/main/java/net/schueller/peertube/model/Licence.java b/app/src/main/java/net/schueller/peertube/model/Licence.java
index 11f8330..af68007 100644
--- a/app/src/main/java/net/schueller/peertube/model/Licence.java
+++ b/app/src/main/java/net/schueller/peertube/model/Licence.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.model;
diff --git a/app/src/main/java/net/schueller/peertube/model/Me.java b/app/src/main/java/net/schueller/peertube/model/Me.java
index 1a0c96e..2e843fd 100644
--- a/app/src/main/java/net/schueller/peertube/model/Me.java
+++ b/app/src/main/java/net/schueller/peertube/model/Me.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2020 Stefan Schüller
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
package net.schueller.peertube.model;
public class Me {
diff --git a/app/src/main/java/net/schueller/peertube/model/OauthClient.java b/app/src/main/java/net/schueller/peertube/model/OauthClient.java
index 9dd016f..d744373 100644
--- a/app/src/main/java/net/schueller/peertube/model/OauthClient.java
+++ b/app/src/main/java/net/schueller/peertube/model/OauthClient.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.model;
diff --git a/app/src/main/java/net/schueller/peertube/model/Privacy.java b/app/src/main/java/net/schueller/peertube/model/Privacy.java
index 6de6798..0bbcb32 100644
--- a/app/src/main/java/net/schueller/peertube/model/Privacy.java
+++ b/app/src/main/java/net/schueller/peertube/model/Privacy.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.model;
diff --git a/app/src/main/java/net/schueller/peertube/model/Rating.java b/app/src/main/java/net/schueller/peertube/model/Rating.java
index 05c4b01..090e241 100644
--- a/app/src/main/java/net/schueller/peertube/model/Rating.java
+++ b/app/src/main/java/net/schueller/peertube/model/Rating.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2020 Stefan Schüller
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
package net.schueller.peertube.model;
import com.google.gson.annotations.SerializedName;
diff --git a/app/src/main/java/net/schueller/peertube/model/Resolution.java b/app/src/main/java/net/schueller/peertube/model/Resolution.java
index 815d96e..3f2af0c 100644
--- a/app/src/main/java/net/schueller/peertube/model/Resolution.java
+++ b/app/src/main/java/net/schueller/peertube/model/Resolution.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.model;
diff --git a/app/src/main/java/net/schueller/peertube/model/Server.java b/app/src/main/java/net/schueller/peertube/model/Server.java
index 2cc17e1..2fe2d66 100644
--- a/app/src/main/java/net/schueller/peertube/model/Server.java
+++ b/app/src/main/java/net/schueller/peertube/model/Server.java
@@ -1,22 +1,24 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.model;
+import java.util.ArrayList;
+import java.util.Date;
+
public class Server {
private Integer id;
@@ -26,16 +28,20 @@ public class Server {
private String version;
private Boolean signupAllowed;
private Double userVideoQuota;
+ private Category category;
+ private ArrayList languages;
+ private Boolean autoBlacklistUserVideosEnabled;
+ private String defaultNSFWPolicy;
+ private Boolean isNSFW;
private Integer totalUsers;
private Integer totalVideos;
private Integer totalLocalVideos;
private Integer totalInstanceFollowers;
private Integer totalInstanceFollowing;
-
private Boolean supportsIPv6;
private String country;
-
private Integer health;
+ private Date createdAt;
public Integer getId() {
return id;
@@ -93,6 +99,46 @@ public class Server {
this.userVideoQuota = userVideoQuota;
}
+ public Category getCategory() {
+ return category;
+ }
+
+ public void setCategory(Category category) {
+ this.category = category;
+ }
+
+ public ArrayList getLanguages() {
+ return languages;
+ }
+
+ public void setLanguages(ArrayList languages) {
+ this.languages = languages;
+ }
+
+ public Boolean getAutoBlacklistUserVideosEnabled() {
+ return autoBlacklistUserVideosEnabled;
+ }
+
+ public void setAutoBlacklistUserVideosEnabled(Boolean autoBlacklistUserVideosEnabled) {
+ this.autoBlacklistUserVideosEnabled = autoBlacklistUserVideosEnabled;
+ }
+
+ public String getDefaultNSFWPolicy() {
+ return defaultNSFWPolicy;
+ }
+
+ public void setDefaultNSFWPolicy(String defaultNSFWPolicy) {
+ this.defaultNSFWPolicy = defaultNSFWPolicy;
+ }
+
+ public Boolean getNSFW() {
+ return isNSFW;
+ }
+
+ public void setNSFW(Boolean NSFW) {
+ isNSFW = NSFW;
+ }
+
public Integer getTotalUsers() {
return totalUsers;
}
@@ -156,4 +202,12 @@ public class Server {
public void setHealth(Integer health) {
this.health = health;
}
+
+ public Date getCreatedAt() {
+ return createdAt;
+ }
+
+ public void setCreatedAt(Date createdAt) {
+ this.createdAt = createdAt;
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/net/schueller/peertube/model/ServerList.java b/app/src/main/java/net/schueller/peertube/model/ServerList.java
index 941c34c..6eb8d95 100644
--- a/app/src/main/java/net/schueller/peertube/model/ServerList.java
+++ b/app/src/main/java/net/schueller/peertube/model/ServerList.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.model;
diff --git a/app/src/main/java/net/schueller/peertube/model/Token.java b/app/src/main/java/net/schueller/peertube/model/Token.java
index f43bad0..87db5da 100644
--- a/app/src/main/java/net/schueller/peertube/model/Token.java
+++ b/app/src/main/java/net/schueller/peertube/model/Token.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.model;
diff --git a/app/src/main/java/net/schueller/peertube/model/Video.java b/app/src/main/java/net/schueller/peertube/model/Video.java
index 11bf4ad..f82d2c1 100644
--- a/app/src/main/java/net/schueller/peertube/model/Video.java
+++ b/app/src/main/java/net/schueller/peertube/model/Video.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.model;
diff --git a/app/src/main/java/net/schueller/peertube/model/VideoList.java b/app/src/main/java/net/schueller/peertube/model/VideoList.java
index 336a0cb..df02ac6 100644
--- a/app/src/main/java/net/schueller/peertube/model/VideoList.java
+++ b/app/src/main/java/net/schueller/peertube/model/VideoList.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.model;
diff --git a/app/src/main/java/net/schueller/peertube/network/AccessTokenAuthenticator.java b/app/src/main/java/net/schueller/peertube/network/AccessTokenAuthenticator.java
new file mode 100644
index 0000000..3756224
--- /dev/null
+++ b/app/src/main/java/net/schueller/peertube/network/AccessTokenAuthenticator.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2020 Stefan Schüller
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package net.schueller.peertube.network;
+
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import okhttp3.Authenticator;
+import okhttp3.Request;
+import okhttp3.Response;
+import okhttp3.Route;
+
+public class AccessTokenAuthenticator implements Authenticator {
+
+ private static final String TAG = "ATAuthenticator";
+
+ public AccessTokenAuthenticator() {
+ }
+
+ @Nullable
+ @Override
+ public Request authenticate(Route route, @NonNull Response response) {
+ Session session = Session.getInstance();
+
+ // check if we are using tokens
+ final String accessToken = session.getToken();
+ if (!isRequestWithAccessToken(response) || accessToken == null) {
+ return null;
+ }
+ synchronized (this) {
+ final String newAccessToken = session.getToken();
+ // Access token is refreshed in another thread.
+ if (!accessToken.equals(newAccessToken)) {
+ Log.v(TAG, "Access token is refreshed in another thread");
+ return newRequestWithAccessToken(response.request(), newAccessToken);
+ }
+
+ // do we have a refresh token?
+ if (session.getRefreshToken() == null) {
+ Log.v(TAG, "No refresh token available");
+ return null;
+ }
+
+ Log.v(TAG, "refresh token: " + session.getRefreshToken());
+
+ // Need to refresh an access token
+ Log.v(TAG, "Need to refresh an access token");
+ final String updatedAccessToken = session.refreshAccessToken();
+ if (updatedAccessToken != null) {
+ return newRequestWithAccessToken(response.request(), updatedAccessToken);
+ }
+ Log.v(TAG, "Refresh failed");
+ return null;
+ }
+ }
+
+ private boolean isRequestWithAccessToken(@NonNull Response response) {
+ String header = response.request().header("Authorization");
+ return header != null && header.startsWith("Bearer");
+ }
+
+ @NonNull
+ private Request newRequestWithAccessToken(@NonNull Request request, @NonNull String accessToken) {
+ return request.newBuilder()
+ .header("Authorization", accessToken)
+ .build();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/net/schueller/peertube/network/AuthenticationService.java b/app/src/main/java/net/schueller/peertube/network/AuthenticationService.java
index 898c9bd..eb12d9b 100644
--- a/app/src/main/java/net/schueller/peertube/network/AuthenticationService.java
+++ b/app/src/main/java/net/schueller/peertube/network/AuthenticationService.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.network;
@@ -42,4 +41,14 @@ public interface AuthenticationService {
@Field("password") String password
);
+ @POST("users/token")
+ @FormUrlEncoded
+ Call refreshToken(
+ @Field("client_id") String clientId,
+ @Field("client_secret") String clientSecret,
+ @Field("grant_type") String grantType,
+ @Field("response_type") String responseType,
+ @Field("username") String username,
+ @Field("refresh_token") String refreshToken
+ );
}
\ No newline at end of file
diff --git a/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java b/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java
index 13b2925..90868ff 100644
--- a/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java
+++ b/app/src/main/java/net/schueller/peertube/network/AuthorizationInterceptor.java
@@ -1,25 +1,26 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.network;
import android.util.Log;
+import androidx.annotation.NonNull;
+
import java.io.IOException;
import okhttp3.Interceptor;
@@ -31,8 +32,7 @@ public class AuthorizationInterceptor implements Interceptor {
public AuthorizationInterceptor() {
}
-
-
+ @NonNull
@Override
public Response intercept(Chain chain) throws IOException {
diff --git a/app/src/main/java/net/schueller/peertube/network/GetConfigDataService.java b/app/src/main/java/net/schueller/peertube/network/GetConfigDataService.java
index b8a4279..7c4e42c 100644
--- a/app/src/main/java/net/schueller/peertube/network/GetConfigDataService.java
+++ b/app/src/main/java/net/schueller/peertube/network/GetConfigDataService.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.network;
diff --git a/app/src/main/java/net/schueller/peertube/network/GetServerListDataService.java b/app/src/main/java/net/schueller/peertube/network/GetServerListDataService.java
index bdb8a26..a573b3a 100644
--- a/app/src/main/java/net/schueller/peertube/network/GetServerListDataService.java
+++ b/app/src/main/java/net/schueller/peertube/network/GetServerListDataService.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.network;
@@ -27,7 +26,8 @@ public interface GetServerListDataService {
@GET("instances/")
Call getInstancesData(
@Query("start") int start,
- @Query("count") int count
+ @Query("count") int count,
+ @Query("search") String text
);
}
\ No newline at end of file
diff --git a/app/src/main/java/net/schueller/peertube/network/GetUserService.java b/app/src/main/java/net/schueller/peertube/network/GetUserService.java
index 1a2d445..3ff3e4b 100644
--- a/app/src/main/java/net/schueller/peertube/network/GetUserService.java
+++ b/app/src/main/java/net/schueller/peertube/network/GetUserService.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2020 Stefan Schüller
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
package net.schueller.peertube.network;
import net.schueller.peertube.model.Account;
diff --git a/app/src/main/java/net/schueller/peertube/network/GetVideoDataService.java b/app/src/main/java/net/schueller/peertube/network/GetVideoDataService.java
index 53bf0cd..d4390cd 100644
--- a/app/src/main/java/net/schueller/peertube/network/GetVideoDataService.java
+++ b/app/src/main/java/net/schueller/peertube/network/GetVideoDataService.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.network;
diff --git a/app/src/main/java/net/schueller/peertube/network/RetrofitInstance.java b/app/src/main/java/net/schueller/peertube/network/RetrofitInstance.java
index 23e38da..4f12db7 100644
--- a/app/src/main/java/net/schueller/peertube/network/RetrofitInstance.java
+++ b/app/src/main/java/net/schueller/peertube/network/RetrofitInstance.java
@@ -1,22 +1,26 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.network;
+import static net.schueller.peertube.network.UnsafeOkHttpClient.getUnsafeOkHttpClientBuilder;
+
+import android.content.SharedPreferences;
+import android.preference.PreferenceManager;
+import net.schueller.peertube.R;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
@@ -26,13 +30,20 @@ public class RetrofitInstance {
private static Retrofit retrofit;
private static String baseUrl;
- public static Retrofit getRetrofitInstance(String newBaseUrl) {
+ public static Retrofit getRetrofitInstance(String newBaseUrl, boolean insecure) {
if (retrofit == null || !newBaseUrl.equals(baseUrl)) {
baseUrl = newBaseUrl;
- OkHttpClient.Builder okhttpClientBuilder = new OkHttpClient.Builder();
+ OkHttpClient.Builder okhttpClientBuilder;
+
+ if (!insecure) {
+ okhttpClientBuilder = new OkHttpClient.Builder();
+ } else {
+ okhttpClientBuilder = getUnsafeOkHttpClientBuilder();
+ }
okhttpClientBuilder.addInterceptor(new AuthorizationInterceptor());
+ okhttpClientBuilder.authenticator(new AccessTokenAuthenticator());
retrofit = new retrofit2.Retrofit.Builder()
.client(okhttpClientBuilder.build())
diff --git a/app/src/main/java/net/schueller/peertube/network/Session.java b/app/src/main/java/net/schueller/peertube/network/Session.java
index 525cbb9..2c4a3ad 100644
--- a/app/src/main/java/net/schueller/peertube/network/Session.java
+++ b/app/src/main/java/net/schueller/peertube/network/Session.java
@@ -1,43 +1,43 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.network;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
-import android.util.Log;
import net.schueller.peertube.R;
import net.schueller.peertube.application.AppApplication;
+import static net.schueller.peertube.service.LoginService.refreshToken;
+
public class Session {
private static volatile Session sSoleInstance;
private static SharedPreferences sharedPreferences;
//private constructor.
- private Session(){
+ private Session() {
Context context = AppApplication.getContext();
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
//Prevent form the reflection api.
- if (sSoleInstance != null){
+ if (sSoleInstance != null) {
throw new RuntimeException("Use getInstance() method to get the single instance of this class.");
}
}
@@ -58,7 +58,6 @@ public class Session {
}
-
public boolean isLoggedIn() {
// check if token exist or not
// return true if exist otherwise false
@@ -69,13 +68,6 @@ public class Session {
return getToken() != null;
}
- public void saveToken(String token) {
- // save the token
- SharedPreferences.Editor editor = sharedPreferences.edit();
- editor.putString(AppApplication.getContext().getString(R.string.pref_token_access), token);
- editor.commit();
- }
-
public String getToken() {
// return the token that was saved earlier
@@ -89,27 +81,24 @@ public class Session {
return null;
}
- public void saveUsername(String username) {
- SharedPreferences.Editor editor = sharedPreferences.edit();
- editor.putString(AppApplication.getContext().getString(R.string.pref_auth_username), username);
- editor.commit();
- }
-
- public String getEmail() {
- return sharedPreferences.getString(AppApplication.getContext().getString(R.string.pref_auth_username), null);
- }
-
- public void savePassword(String password) {
- SharedPreferences.Editor editor = sharedPreferences.edit();
- editor.putString(AppApplication.getContext().getString(R.string.pref_auth_password), password);
- editor.commit();
- }
-
public String getPassword() {
return sharedPreferences.getString(AppApplication.getContext().getString(R.string.pref_auth_password), null);
}
+ public String getRefreshToken() {
+ return sharedPreferences.getString(AppApplication.getContext().getString(R.string.pref_token_refresh), null);
+
+ }
+
+ public String refreshAccessToken() {
+
+ refreshToken();
+ // refresh token
+
+ return this.getToken();
+ }
+
public void invalidate() {
// get called when user become logged out
// delete token and other user info
@@ -122,6 +111,7 @@ public class Session {
editor.putString(context.getString(R.string.pref_auth_password), null);
editor.putString(context.getString(R.string.pref_auth_username), null);
editor.putString(context.getString(R.string.pref_token_access), null);
+ editor.putString(context.getString(R.string.pref_token_refresh), null);
editor.commit();
}
diff --git a/app/src/main/java/net/schueller/peertube/network/UnsafeOkHttpClient.java b/app/src/main/java/net/schueller/peertube/network/UnsafeOkHttpClient.java
new file mode 100644
index 0000000..1961178
--- /dev/null
+++ b/app/src/main/java/net/schueller/peertube/network/UnsafeOkHttpClient.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 Stefan Schüller
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+package net.schueller.peertube.network;
+
+import android.annotation.SuppressLint;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import okhttp3.OkHttpClient;
+import okhttp3.OkHttpClient.Builder;
+
+// Take from https://stackoverflow.com/questions/25509296/trusting-all-certificates-with-okhttp/25992879#25992879
+public class UnsafeOkHttpClient {
+ public static Builder getUnsafeOkHttpClientBuilder() {
+ try {
+ // Create a trust manager that does not validate certificate chains
+ final TrustManager[] trustAllCerts = new TrustManager[] {
+ new X509TrustManager() {
+ @SuppressLint("TrustAllX509TrustManager")
+ @Override
+ public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
+ }
+
+ @SuppressLint("TrustAllX509TrustManager")
+ @Override
+ public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
+ }
+
+ @Override
+ public java.security.cert.X509Certificate[] getAcceptedIssuers() {
+ return new java.security.cert.X509Certificate[]{};
+ }
+ }
+ };
+
+ // Install the all-trusting trust manager
+ final SSLContext sslContext = SSLContext.getInstance("SSL");
+ sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
+
+ // Create an ssl socket factory with our all-trusting manager
+ final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
+
+ OkHttpClient.Builder builder = new OkHttpClient.Builder();
+ builder.sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]);
+ builder.hostnameVerifier((hostname, session) -> true);
+
+ return builder;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/net/schueller/peertube/provider/SearchSuggestionsProvider.java b/app/src/main/java/net/schueller/peertube/provider/SearchSuggestionsProvider.java
index 8532e8c..9fa6a76 100644
--- a/app/src/main/java/net/schueller/peertube/provider/SearchSuggestionsProvider.java
+++ b/app/src/main/java/net/schueller/peertube/provider/SearchSuggestionsProvider.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.provider;
diff --git a/app/src/main/java/net/schueller/peertube/service/LoginService.java b/app/src/main/java/net/schueller/peertube/service/LoginService.java
index 6891c92..ebed554 100644
--- a/app/src/main/java/net/schueller/peertube/service/LoginService.java
+++ b/app/src/main/java/net/schueller/peertube/service/LoginService.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.service;
@@ -26,6 +25,7 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import net.schueller.peertube.R;
+import net.schueller.peertube.application.AppApplication;
import net.schueller.peertube.helper.APIUrlHelper;
import net.schueller.peertube.model.OauthClient;
import net.schueller.peertube.model.Token;
@@ -42,15 +42,14 @@ public class LoginService {
private static final String TAG = "LoginService";
- public static void Authenticate(String username, String password)
- {
+ public static void Authenticate(String username, String password) {
Context context = getContext();
String apiBaseURL = APIUrlHelper.getUrlWithVersion(context);
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
- AuthenticationService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(AuthenticationService.class);
+ AuthenticationService service = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(context)).create(AuthenticationService.class);
Call call = service.getOauthClientLocal();
@@ -62,6 +61,14 @@ public class LoginService {
OauthClient oauthClient = response.body();
+ SharedPreferences.Editor editor = sharedPref.edit();
+
+ assert oauthClient != null;
+
+ editor.putString(context.getString(R.string.pref_client_id), oauthClient.getClientId());
+ editor.putString(context.getString(R.string.pref_client_secret), oauthClient.getClientSecret());
+ editor.apply();
+
Call call2 = service.getAuthenticationToken(
oauthClient.getClientId(),
oauthClient.getClientSecret(),
@@ -79,13 +86,9 @@ public class LoginService {
Token token = response2.body();
- SharedPreferences.Editor editor = sharedPref.edit();
-
- // TODO: calc expiration
- //editor.putInt(getString(R.string.pref_token_expiration), token.getRefreshToken());
-
+ assert token != null;
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_refresh), token.getRefreshToken());
editor.putString(context.getString(R.string.pref_token_type), token.getTokenType());
editor.apply();
@@ -124,4 +127,62 @@ public class LoginService {
}
});
}
+
+ public static void refreshToken() {
+ Context context = getContext();
+
+ String apiBaseURL = APIUrlHelper.getUrlWithVersion(context);
+ SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
+ AuthenticationService service = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(context)).create(AuthenticationService.class);
+
+ String refreshToken = sharedPreferences.getString(AppApplication.getContext().getString(R.string.pref_token_refresh), null);
+ String userName = sharedPreferences.getString(AppApplication.getContext().getString(R.string.pref_auth_username), null);
+ String clientId = sharedPreferences.getString(AppApplication.getContext().getString(R.string.pref_client_id), null);
+ String clientSecret = sharedPreferences.getString(AppApplication.getContext().getString(R.string.pref_client_secret), null);
+
+
+ Call call = service.refreshToken(
+ clientId,
+ clientSecret,
+ "refresh_token",
+ "code",
+ userName,
+ refreshToken
+ );
+ call.enqueue(new Callback() {
+ @Override
+ public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) {
+
+ if (response.isSuccessful()) {
+
+ Token token = response.body();
+
+ SharedPreferences.Editor editor = sharedPreferences.edit();
+
+ assert token != null;
+ editor.putString(context.getString(R.string.pref_token_access), token.getAccessToken());
+ editor.putString(context.getString(R.string.pref_token_refresh), token.getRefreshToken());
+ editor.putString(context.getString(R.string.pref_token_type), token.getTokenType());
+ editor.apply();
+
+ Log.wtf(TAG, "Logged in");
+
+ Toast.makeText(context, context.getString(R.string.authentication_token_refresh_success), Toast.LENGTH_LONG).show();
+
+
+ } else {
+ Log.wtf(TAG, response.toString());
+ Toast.makeText(context, context.getString(R.string.authentication_token_refresh_failed), Toast.LENGTH_LONG).show();
+
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call call2, @NonNull Throwable t2) {
+ Log.wtf("err", t2.fillInStackTrace());
+ Toast.makeText(context, context.getString(R.string.authentication_token_refresh_failed), Toast.LENGTH_LONG).show();
+
+ }
+ });
+ }
}
diff --git a/app/src/main/java/net/schueller/peertube/service/VideoPlayerService.java b/app/src/main/java/net/schueller/peertube/service/VideoPlayerService.java
index d3aa9a8..905aa98 100644
--- a/app/src/main/java/net/schueller/peertube/service/VideoPlayerService.java
+++ b/app/src/main/java/net/schueller/peertube/service/VideoPlayerService.java
@@ -1,19 +1,18 @@
/*
- * Copyright 2018 Stefan Schüller
+ * Copyright (C) 2020 Stefan Schüller
*
- * 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.
+ * it under the terms of the GNU Affero 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.
+ * GNU Affero 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 .
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
*/
package net.schueller.peertube.service;
@@ -33,6 +32,7 @@ import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
+import android.webkit.URLUtil;
import androidx.annotation.Nullable;
import android.support.v4.media.MediaDescriptionCompat;
@@ -50,6 +50,8 @@ import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.audio.AudioAttributes;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator;
+import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSource;
+import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSourceFactory;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.ui.PlayerNotificationManager;
@@ -59,32 +61,39 @@ import com.google.android.exoplayer2.util.Util;
import net.schueller.peertube.R;
import net.schueller.peertube.activity.VideoPlayActivity;
+import net.schueller.peertube.helper.APIUrlHelper;
import net.schueller.peertube.helper.MetaDataHelper;
import net.schueller.peertube.model.Video;
+import okhttp3.OkHttpClient;
import static android.media.session.PlaybackState.ACTION_PAUSE;
import static android.media.session.PlaybackState.ACTION_PLAY;
import static com.google.android.exoplayer2.ui.PlayerNotificationManager.ACTION_STOP;
import static net.schueller.peertube.activity.VideoListActivity.EXTRA_VIDEOID;
+import static net.schueller.peertube.network.UnsafeOkHttpClient.getUnsafeOkHttpClientBuilder;
public class VideoPlayerService extends Service {
private static final String TAG = "VideoPlayerService";
+
private static final String MEDIA_SESSION_TAG = "peertube_player";
private final IBinder mBinder = new LocalBinder();
private static final String PLAYBACK_CHANNEL_ID = "playback_channel";
+
private static final Integer PLAYBACK_NOTIFICATION_ID = 1;
public SimpleExoPlayer player;
private Video currentVideo;
+
private String currentStreamUrl;
private PlayerNotificationManager playerNotificationManager;
private IntentFilter becomeNoisyIntentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
+
private BecomingNoisyReceiver myNoisyAudioStreamReceiver = new BecomingNoisyReceiver();
@Override
@@ -105,13 +114,13 @@ public class VideoPlayerService extends Service {
registerReceiver(myNoisyAudioStreamReceiver, becomeNoisyIntentFilter);
}
- if (playbackState == ACTION_PLAY) { // this means that play is available, hence the audio is paused or stopped
+ if (playbackState
+ == ACTION_PLAY) { // this means that play is available, hence the audio is paused or stopped
Log.v(TAG, "ACTION_PAUSE: " + playbackState);
- unregisterReceiver(myNoisyAudioStreamReceiver);
- myNoisyAudioStreamReceiver=null;
+ safeUnregisterReceiver();
}
}
- } );
+ });
}
@@ -131,14 +140,9 @@ public class VideoPlayerService extends Service {
if (playerNotificationManager != null) {
playerNotificationManager.setPlayer(null);
}
- //Was seeing an error when exiting the program about about not unregistering the receiver.
- try {
- if (null!=myNoisyAudioStreamReceiver) {
- this.unregisterReceiver(myNoisyAudioStreamReceiver);
- }
- } catch (Exception e) {
- Log.e("VideoPlayerService", "attempted to unregister a nonregistered service");
- }
+ //Was seeing an error when exiting the program about not unregistering the receiver.
+ safeUnregisterReceiver();
+
if (player != null) {
player.release();
player = null;
@@ -146,6 +150,15 @@ public class VideoPlayerService extends Service {
super.onDestroy();
}
+ private void safeUnregisterReceiver()
+ {
+ try {
+ unregisterReceiver(myNoisyAudioStreamReceiver);
+ } catch (Exception e) {
+ Log.e("VideoPlayerService", "attempted to unregister a nonregistered service");
+ }
+ }
+
@Nullable
@Override
public IBinder onBind(Intent intent) {
@@ -156,41 +169,62 @@ public class VideoPlayerService extends Service {
public int onStartCommand(Intent intent, int flags, int startId) {
Context context = this;
Log.v(TAG, "onStartCommand...");
- if(currentStreamUrl == null){
- Toast.makeText(context, "currentStreamUrl must not null", Toast.LENGTH_SHORT).show();
+
+ if (!URLUtil.isValidUrl(currentStreamUrl)) {
+ Toast.makeText(context, "Invalid URL provided. Unable to play video.", Toast.LENGTH_SHORT).show();
+ return START_NOT_STICKY;
+ } else {
+ playVideo();
+ return START_STICKY;
}
- playVideo();
- return START_STICKY;
}
- public void setCurrentVideo(Video video)
- {
+ public void setCurrentVideo(Video video) {
Log.v(TAG, "setCurrentVideo...");
currentVideo = video;
}
- public void setCurrentStreamUrl(String streamUrl)
- {
+ public void setCurrentStreamUrl(String streamUrl) {
Log.v(TAG, "setCurrentStreamUrl..." + streamUrl);
currentStreamUrl = streamUrl;
}
//Playback speed control
public void setPlayBackSpeed(float speed) {
-
Log.v(TAG, "setPlayBackSpeed...");
player.setPlaybackParameters(new PlaybackParameters(speed));
}
+ /**
+ * Returns the current playback speed of the player.
+ *
+ * @return the current playback speed of the player.
+ */
+ public float getPlayBackSpeed() {
+ return player.getPlaybackParameters().speed;
+ }
+
public void playVideo() {
Context context = this;
+ // We need a valid URL
+
Log.v(TAG, "playVideo...");
// Produces DataSource instances through which media data is loaded.
- DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getApplicationContext(),
- Util.getUserAgent(getApplicationContext(), "PeerTube"), null);
+// DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getApplicationContext(),
+// Util.getUserAgent(getApplicationContext(), "PeerTube"), null);
+
+ OkHttpClient.Builder okhttpClientBuilder;
+
+ if (!APIUrlHelper.useInsecureConnection(this)) {
+ okhttpClientBuilder = new OkHttpClient.Builder();
+ } else {
+ okhttpClientBuilder = getUnsafeOkHttpClientBuilder();
+ }
+
+ DataSource.Factory dataSourceFactory = new OkHttpDataSourceFactory(okhttpClientBuilder.build(), Util.getUserAgent(getApplicationContext(), "PeerTube"));
// This is the MediaSource representing the media to be played.
ExtractorMediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory)
@@ -235,7 +269,8 @@ public class VideoPlayerService extends Service {
@Nullable
@Override
- public Bitmap getCurrentLargeIcon(Player player, PlayerNotificationManager.BitmapCallback callback) {
+ public Bitmap getCurrentLargeIcon(Player player,
+ PlayerNotificationManager.BitmapCallback callback) {
return null;
}
}
@@ -290,15 +325,16 @@ public class VideoPlayerService extends Service {
// Audio Focus
AudioAttributes audioAttributes = new AudioAttributes.Builder()
- .setUsage(C.USAGE_MEDIA)
- .setContentType(C.CONTENT_TYPE_MOVIE)
- .build();
- player.setAudioAttributes(audioAttributes,true);
+ .setUsage(C.USAGE_MEDIA)
+ .setContentType(C.CONTENT_TYPE_MOVIE)
+ .build();
+ player.setAudioAttributes(audioAttributes, true);
}
// pause playback on audio output change
private class BecomingNoisyReceiver extends BroadcastReceiver {
+
@Override
public void onReceive(Context context, Intent intent) {
if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals(intent.getAction())) {
diff --git a/app/src/main/java/net/schueller/peertube/utils/Extensions.kt b/app/src/main/java/net/schueller/peertube/utils/Extensions.kt
new file mode 100644
index 0000000..6a4600a
--- /dev/null
+++ b/app/src/main/java/net/schueller/peertube/utils/Extensions.kt
@@ -0,0 +1,58 @@
+package net.schueller.peertube.utils
+
+import android.content.Context
+import android.view.View
+import android.view.inputmethod.InputMethodManager
+import androidx.appcompat.app.AppCompatActivity
+import androidx.fragment.app.Fragment
+
+fun View.gone() {
+ this.visibility = View.GONE
+}
+
+fun View.visible() {
+ this.visibility = View.VISIBLE
+}
+
+fun View.invisible() {
+ this.visibility = View.INVISIBLE
+}
+
+fun View.visibleIf(predicate: () -> Boolean) {
+ when (predicate.invoke()) {
+ true -> visible()
+ else -> gone()
+ }
+}
+
+fun View.goneIf(predicate: () -> Boolean) {
+ when (predicate.invoke()) {
+ true -> gone()
+ else -> visible()
+ }
+}
+
+fun View.invisibleIf(predicate: () -> Boolean) {
+ when (predicate.invoke()) {
+ true -> invisible()
+ else -> visible()
+ }
+}
+
+fun Fragment.hideKeyboard(): Boolean {
+ activity?.currentFocus?.let {
+ val imm = context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ imm.hideSoftInputFromWindow(it.windowToken, 0)
+ return true
+ }
+ return false
+}
+
+fun AppCompatActivity.hideKeyboard(): Boolean {
+ currentFocus?.let {
+ val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
+ imm.hideSoftInputFromWindow(it.windowToken, 0)
+ return true
+ }
+ return false
+}
diff --git a/app/src/main/res/drawable/ic_baseline_remove_red_eye_24.xml b/app/src/main/res/drawable/ic_baseline_remove_red_eye_24.xml
new file mode 100644
index 0000000..a3e222a
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_remove_red_eye_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_edit_24.xml b/app/src/main/res/drawable/ic_edit_24.xml
new file mode 100644
index 0000000..2844baf
--- /dev/null
+++ b/app/src/main/res/drawable/ic_edit_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/layout/activity_server_selection.xml b/app/src/main/res/layout/activity_search_server.xml
similarity index 78%
rename from app/src/main/res/layout/activity_server_selection.xml
rename to app/src/main/res/layout/activity_search_server.xml
index 9a91455..991e091 100644
--- a/app/src/main/res/layout/activity_server_selection.xml
+++ b/app/src/main/res/layout/activity_search_server.xml
@@ -4,7 +4,12 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context=".activity.SelectServerActivity">
+ tools:context=".activity.SearchServerActivity">
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_server_address_book.xml b/app/src/main/res/layout/activity_server_address_book.xml
index 5de5eb8..d09f244 100644
--- a/app/src/main/res/layout/activity_server_address_book.xml
+++ b/app/src/main/res/layout/activity_server_address_book.xml
@@ -31,7 +31,25 @@
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@drawable/ic_baseline_add_24" />
-
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml
index de6591a..4fb6dcc 100644
--- a/app/src/main/res/layout/activity_settings.xml
+++ b/app/src/main/res/layout/activity_settings.xml
@@ -1,6 +1,21 @@
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+
+
+
+
+
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_add_server.xml b/app/src/main/res/layout/fragment_add_server.xml
index e55bba1..91e0a6b 100644
--- a/app/src/main/res/layout/fragment_add_server.xml
+++ b/app/src/main/res/layout/fragment_add_server.xml
@@ -19,28 +19,29 @@
android:hint="@string/server_book_add_label"
android:inputType="textPersonName" />
-
+ android:layout_width="match_parent"
+ android:orientation="horizontal"
+ >
+ />
-
+
-
@@ -194,6 +195,7 @@
android:layout_marginStart="18dp"
android:layout_marginTop="12dp"
android:layout_marginEnd="12dp"
+ android:autoLink="web"
android:textAppearance="@style/Base.TextAppearance.AppCompat.Body1" />
+ android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption"
+ tools:text="@tools:sample/lorem/random"
+ android:lines="2"
+ />
@@ -238,7 +242,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
-
+ android:gravity="bottom"
android:orientation="horizontal">
+ android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption"
+ tools:text="@tools:sample/lorem/random"
+ android:lines="2"
+ />
@@ -266,7 +272,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
-
+ android:gravity="bottom"
android:orientation="horizontal">
+ android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption"
+ tools:text="@tools:sample/lorem"
+ android:lines="2"
+ />
@@ -295,7 +303,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
-
+ android:gravity="bottom"
android:orientation="horizontal">
+ android:textAppearance="@style/Base.TextAppearance.AppCompat.Caption"
+ tools:text="@tools:sample/lorem/random"
+ android:lines="2"
+ />
@@ -323,7 +333,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
-
+ android:gravity="bottom"
android:orientation="horizontal">
diff --git a/app/src/main/res/layout/row_account_about.xml b/app/src/main/res/layout/row_account_about.xml
index a02de1c..cb86831 100644
--- a/app/src/main/res/layout/row_account_about.xml
+++ b/app/src/main/res/layout/row_account_about.xml
@@ -50,7 +50,7 @@
android:paddingEnd="12dp" />
+
+
-
+ android:orientation="vertical">
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/row_server_address_book.xml b/app/src/main/res/layout/row_server_address_book.xml
new file mode 100644
index 0000000..7c935cf
--- /dev/null
+++ b/app/src/main/res/layout/row_server_address_book.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/row_serverbook.xml b/app/src/main/res/layout/row_serverbook.xml
deleted file mode 100644
index aa0911e..0000000
--- a/app/src/main/res/layout/row_serverbook.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/row_video.xml b/app/src/main/res/layout/row_video_list.xml
similarity index 96%
rename from app/src/main/res/layout/row_video.xml
rename to app/src/main/res/layout/row_video_list.xml
index 170c104..398db17 100644
--- a/app/src/main/res/layout/row_video.xml
+++ b/app/src/main/res/layout/row_video_list.xml
@@ -58,7 +58,7 @@
android:paddingEnd="12dp" />
خادوم PeerTube
- \u0020 مشاهدات
+ " مشاهدات"
الصورة المصغرة للفيديو
الصورة الرمزية للحساب
عرض NSFW
@@ -143,8 +143,8 @@
الرخصة
اللغة
العلامات
- سرعة التشغيل
- الجودة
+ سرعة التشغيل (%1$s)
+ (%1$s) الجودة
الفيديو
القنوات
حول
@@ -305,4 +305,51 @@
الخادوم الحالي
0.75x
1.25x
+ حدد اللغة لواجهة التطبيق. أعد تشغيل التطبيق حتى يسري التغيير.
+ الآلي
+ مقاطع الفيديو: %s، مقاطع الفيديو المحلية: %s
+ خادم NSFW
+ الشكل والمظهر
+ حول
+ تشغيل الفيديو
+ قائمة الفيديو
+ إعدادات النشاط2
+ حساب
+ خادم البحث
+ هل تريد بالتأكيد إزالة هذا الملقم من دفتر العناوين؟
+ إزالة الملقم
+ دليل العناوين
+ لديه تسجيل الدخول
+ إضافة
+ كلمة المرور
+ اسم المستخدم
+ بحث
+ عنوان URL للملقم
+ تسميه
+ المساعدة والتعليقات
+ تسجيل الخروج
+ مطلوب URL صالح
+ تسمية الملقم مطلوبة
+ فشل تسجيل الدخول!
+ تم تسجيل الدخول
+ مرحبا جزء فارغ
+ البنغالية (بنغلاديش)
+ هل تريد حذف سجل البحث بشكل دائم؟
+ مسح سجل البحث
+ كيف يستجيب الفيديو أثناء التشغيل عند الانتقال إلى الخلفية
+ تم تعطيل إذن صورة في صورة لهذا التطبيق في إعدادات Android
+ إصدار Android لا يدعم الفيديو العائم
+ استمر في تشغيل الفيديو في النافذة العائمة
+ لغة التطبيق
+ أوقف التشغيل في الخلفية مؤقتًا عند الضغط على رجوع أثناء تشغيل الفيديو.
+ ايقاف عند الضغط على زر العودة
+ تاريخ ووقت البناء
+ خطأ في الوصول للشبكة، تحقق من اتصالك
+ فلترة القائمة
+ إعدادات التشغيل في الخلفية
+ إيقاف تشغيل الكل
+ تابع تشغيل الصوت في الخلفية
+ تم تحديث الرمز
+ تعذر تحديث الرمز المميز
+ كتب الخادم فارغة
\ No newline at end of file
diff --git a/app/src/main/res/values-bn-rBD/strings.xml b/app/src/main/res/values-bn-rBD/strings.xml
index a8b8e54..8891644 100644
--- a/app/src/main/res/values-bn-rBD/strings.xml
+++ b/app/src/main/res/values-bn-rBD/strings.xml
@@ -30,10 +30,10 @@
নিষিদ্ধ কন্টেন্ট দেখাও
নিষিদ্ধ কন্টেন্ট
সংস্করণ
- "
-\n<b>গাহ্নু অফেরও সাধারণ গণ অনুমতিপত্র সং.৩.০</b>
+
+\nগাহ্নু অফেরও সাধারণ গণ অনুমতিপত্র সং.৩.০
\n
-\nএই শক্তিশালী কপিলেফট লাইসেন্সের অনুমতি এই চুক্তির উপর নির্ভরশীল যে অনুমতিপত্রের দ্বারা আবদ্ধ সকল কাজ ও পরিবর্তনের সোর্স কোড উপলব্ধ করার মাধ্যমে, যার আওতায় পড়ে অনুমতিপত্রের দ্বারা আবদ্ধ কাজের বৃহত্তর অংশ একই অনুমতিপত্রের আওতায় আনার মাধ্যমে। কপিরাইট এবং লাইসেন্স নোটিশ সংরক্ষণ করা আবশ্যক। অবদানকারীগণ তাদের পেটেন্টর অধিকার অবশ্যই দেয়, যখন একটি পরিমার্জিত সংস্করণ ব্যবহার করে একটি পরিসেবা একটি নেটওয়ার্ক দিয়ে দেয়া হয়, সম্পূর্ণ সোর্স কোড এর পরিমার্জিত সংস্করণ উপলব্ধ তৈরি করা আবশ্যক।"GNU Affero General Public License v3.0 \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.
+\nএই শক্তিশালী কপিলেফট লাইসেন্সের অনুমতি এই চুক্তির উপর নির্ভরশীল যে অনুমতিপত্রের দ্বারা আবদ্ধ সকল কাজ ও পরিবর্তনের সোর্স কোড উপলব্ধ করার মাধ্যমে, যার আওতায় পড়ে অনুমতিপত্রের দ্বারা আবদ্ধ কাজের বৃহত্তর অংশ একই অনুমতিপত্রের আওতায় আনার মাধ্যমে। কপিরাইট এবং লাইসেন্স নোটিশ সংরক্ষণ করা আবশ্যক। অবদানকারীগণ তাদের পেটেন্টর অধিকার অবশ্যই দেয়, যখন একটি পরিমার্জিত সংস্করণ ব্যবহার করে একটি পরিসেবা একটি নেটওয়ার্ক দিয়ে দেয়া হয়, সম্পূর্ণ সোর্স কোড এর পরিমার্জিত সংস্করণ উপলব্ধ তৈরি করা আবশ্যক।
একটি টরেন্ট স্ট্রিমের মাধ্যমে ভিডিও প্লেব্যাক করুন। এর জন্য স্টোরেজ অনুমতির প্রয়োজন । (আলফা, স্থিতিশীল নয়!)
টরেন্ট ভিডিও প্লেয়ার
থিমটি কার্যকর হওয়ার জন্য অ্যাপ্লিকেশন পুনরায় চালু করো।
@@ -72,4 +72,279 @@
সার্ভার
সাইন ইন
সেটিংস
+ টোকেন রিফ্রেশ হয়েছে
+ টোকেন রিফ্রেশ করা যায় নি
+ বিল্ড এর সময়
+ স্বয়ংক্রিয়
+ ভিডিওঃ %s, স্থানীয় ভিডিওঃ %s
+ NSFW ইন্সটান্স
+ লুক এবং ফিল
+ সম্পর্কিত
+ ভিডিও প্লেব্যাক
+ ভিডিও এর লিস্ট
+ সেটিংস কার্যকলাপ ২
+ আকাউন্ট
+ সার্ভার অনুসন্ধান করুন
+ আপনি কি এই সার্ভার রিমুভ করতে চান সার্ভার বই থেকে\?
+ সার্ভার রিমুভ করুন
+ 1.25x
+ 0.75x
+ এড্রেস বই
+ বর্তমান সার্ভার
+ লগইন আছে
+ যোগ
+ পাসওয়ার্ড
+ ইউজারনেম
+ সার্চ
+ সার্ভার ইউআরএল
+ লেবেল
+ সাহায্য ও মতামত
+ লগ আউট
+ সঠিক ইউ আর এল দরকার
+ সার্ভার লেবেল দরকার
+ সার্ভার বই খালি আছে
+ লগইন সফল হয় নি!
+ লগইন হয়েছে
+ হ্যালো ফাঁকা টুকরা
+ সার্ভার নির্বাচন করুন
+ নেটওয়ার্ক ত্রটি, দয়া করে সংযোগ দেখো
+ কিছু সমস্যা হয়েছে, অনুগ্রহ করে পরে চেষ্টা করুন!
+ যুক্ত হয়েছেন:
+ বিবরণ:
+ গ্রাহক সমূহ:
+ একাউন্ট:
+ সম্পর্কিত
+ চ্যানেলগুলি
+ ভিডিও
+ কোয়ালিটি (%1$s)
+ প্লেব্যাক এর গতি (%1$s)
+ Tags
+ ভাষা
+ অনুমতিপত্র
+ বিভাগ
+ Privacy
+ ডাউনলোড
+ শেয়ার
+ এই সেবা ব্যবহারের জন্য লগ ইন করুন
+ রেটিং ব্যর্থ
+ লেখার অনুমতি ছাড়া ভিডিও ডাউনলোড করা যাবে না
+ নিষিদ্ধ তালিকা
+ রিপোর্ট
+ একাউন্ট
+ ফিল্টার তালিকা
+ পিয়ারটিউব সার্ভার URL
+ নিচের তালিকা থেকে একটি সার্ভার নিন অথবা সরাসরি একটি সার্ভার দিন।
+ সেট করা সার্ভার: %s
+ না
+ হ্যা
+ সাইন আপ করা যাবে: %s
+ সার্ভার পছন্দ করুন
+ 2x
+ ১.৫x
+ Normal
+ ০.৫x
+ নীলচে ধূসর
+ ধুসর
+ বাদামী
+ গাড় কমলা
+ কমলা
+ কমলা-হলুদ
+ হলুদ
+ হালকা সবুজ
+ হালকা সবুজ
+ সবুজ
+ সবজে নীল
+ হালকা সবজে নীল
+ হালকা নীল
+ নীল
+ Indigo
+ গাঢ় বেগুনি
+ বেগুনি
+ গোলাপি
+ লাল
+ Zulu
+ Zhuang
+ Yoruba
+ Yiddish
+ Xhosa
+ Wolof
+ পশ্চিম ফ্রিসিয়ান
+ Welsh
+ Walloon
+ Vietnamese
+ Venda
+ Uzbek
+ Urdu
+ Ukrainian
+ Uighur
+ Twi
+ Turkmen
+ Turkish
+ Tswana
+ Tsonga
+ Tonga (Tonga Islands)
+ Tigrinya
+ Tibetan
+ Thai
+ Telugu
+ Tatar
+ Tamil
+ Tajik
+ Tahitian
+ Tagalog
+ সুইডিশ সাংকেতিক ভাষা
+ Swedish
+ Swati
+ Swahili (macrolanguage)
+ Sundanese
+ Spanish
+ দক্ষিণ সোথো
+ দক্ষিণ ডেবেলে
+ দক্ষিণ আফ্রিকান সাংকেতিক ভাষা
+ Somali
+ Slovenian
+ Slovak
+ Sinhala
+ Sindhi
+ Sichuan Yi
+ Shona
+ Serbo-Croatian
+ Serbian
+ Scottish Gaelic
+ সৌদি আরবীয় সাংকেতিক ভাষা
+ Sardinian
+ Sango
+ Samoan
+ রাশিয়ান সাংকেতিক ভাষা
+ Russian
+ Rundi
+ Romansh
+ Romanian
+ Quechua
+ Pushto
+ Portuguese
+ Polish
+ Persian
+ Panjabi
+ পাকিস্তানি সাংকেতিক ভাষা
+ Ossetian
+ Oromo
+ Oriya (macrolanguage)
+ Ojibwa
+ Occitan
+ Nyanja
+ Norwegian Nynorsk
+ Norwegian Bokmål
+ Norwegian
+ উত্তর সামি
+ উত্তর ডেবেলে
+ Nepali (macrolanguage)
+ Ndonga
+ Navajo
+ Nauru
+ Mongolian
+ Modern Greek (1453-)
+ Marshallese
+ Marathi
+ মাওরি
+ মান্ক্স
+ মাল্টিজ
+ মালায়ালাম
+ মালয় (বড়ভাষা)
+ মালাগাসি
+ ম্যাসিডোনিয়
+ লাক্সেমবোর্গীয়
+ লুবা-কাতাঙ্গা
+ লোজবান
+ লিথুনীয়
+ লিনগালা
+ লিমবুরগান
+ লাটভীয়
+ লাও
+ কুর্ডিশ
+ কুয়ানইয়ামা
+ কোটাভা
+ কোরিয়ান
+ কঙ্গো
+ কোমি
+ ক্লিন্টোন
+ কিরঘিয
+ কিনয়ারওয়ান্ডা
+ কিকুয়ু
+ খমার
+ কাযাখ
+ কাশমিরি
+ কানুরি
+ কান্নাডা
+ কালাল্লিসুট
+ জাভানিজ
+ জাপানি সাইন ভাষা
+ জাপানিজ
+ ইতালিয়
+ আইরিশ
+ ইনুপিয়াক
+ ইনুক্টিটুট
+ ইন্দোনেশীয়
+ ইগবো
+ আইসল্যান্ডিক
+ হানগেরীয়
+ হিরি মোটু
+ হিন্দি
+ হেরেরো
+ হিব্রু
+ হাওসা
+ হাইতান
+ গুজরাটি
+ গুরানি
+ জার্মান সাংকেতিক ভাষা
+ জার্মান
+ জর্জিয়
+ গানডা
+ গালিসীয়
+ ফুলাহ
+ ফরাসি সাংকেতিক ভাষা
+ ফরাসি
+ ফিনিশ
+ ফিজান
+ ফারোয়েস
+ ইওয়ি
+ এসটোনীয়
+ এসপেরানটা
+ ইংরেজি
+ জংখ্যা
+ ডাচ
+ ধিভেহি
+ ড্যানিশ সাংকেতিক ভাষা
+ ড্যানিশ
+ চেক সাইন ভাষা
+ চেক
+ ক্রোয়েশীয়
+ ক্রি
+ কোর্সিকান
+ কর্ণিশ
+ চুভাশ
+ চীনা সাইন ভাষা
+ চাইনিজ
+ চেচেন
+ চামোরো
+ কাটালান
+ বার্মিজ
+ বুলগারিয়ানে
+ ব্রিটিশ সাইন ভাষা
+ বাংলা (বাংলাদেশ)
+ আপনি কি পুরোপুরি সার্চ ইতিহাস মুছে ফেলতে চান\?
+ সার্চ ইতিহাস মুছে ফেলুন
+ চালু ভিডিও কি করবে যখন পেছনে যাবে
+ অ্যান্ড্রয়েড সেটিং এ পিকচার ইন পিকচার পারমিশন বন্ধ আছে এই আয়াপ এ
+ অ্যান্ড্রয়েড ভার্সন ভাসমান ভিডিও সাপোর্ট করে
+ ব্যাকগ্রউন্ড প্লে এর কনফিগারেশন
+ ভাসমান উইন্ডো তে ভিডিও চালু রাখুন
+ সব প্লেব্যাক বন্ধ করুন
+ পেছনে অডিও স্ট্রিম হিসেবে চালু রাখুন
+ ভাষা পছন্দ করুন অ্যাপ্লিকেশান এর জন্য। রিস্টার্ট করুন পরিবর্তন দেখার জন্য।
+ অ্যাপ্লিকেশান এর ভাষা
+ ভিডিও চলার সময় ব্যাকগ্রাউন্ড প্লে পজ হবে ব্যাক বাটন প্রেস করলে।
+ ব্যাক বাটন এ পজ
+ পিয়ারটিউব সার্ভার
+ অনুমতিপত্র
\ No newline at end of file
diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml
index 7e410c0..ec25df3 100644
--- a/app/src/main/res/values-bn/strings.xml
+++ b/app/src/main/res/values-bn/strings.xml
@@ -37,8 +37,8 @@
একটি টরেন্ট স্ট্রিমের মাধ্যমে ভিডিও প্লেব্যাক করুন। এর জন্য স্টোরেজ অনুমতির প্রয়োজন । (আলফা, স্থিতিশীল নয়!)
অনুমতিপত্র
-\nগাহ্নু অফেরও সাধারণ গণ অনুমতিপত্র সং.৩.০
-\n
+\nগাহ্নু অফেরও সাধারণ গণ অনুমতিপত্র সং.৩.০
+\n
\nএই শক্তিশালী কপিলেফট লাইসেন্সের অনুমতি এই চুক্তির উপর নির্ভরশীল যে অনুমতিপত্রের দ্বারা আবদ্ধ সকল কাজ ও পরিবর্তনের সোর্স কোড উপলব্ধ করার মাধ্যমে, যার আওতায় পড়ে অনুমতিপত্রের দ্বারা আবদ্ধ কাজের বৃহত্তর অংশ একই অনুমতিপত্রের আওতায় আনার মাধ্যমে। কপিরাইট এবং লাইসেন্স নোটিশ সংরক্ষণ করা আবশ্যক। অবদানকারীগণ তাদের পেটেন্টর অধিকার অবশ্যই দেয়, যখন একটি পরিমার্জিত সংস্করণ ব্যবহার করে একটি পরিসেবা একটি নেটওয়ার্ক দিয়ে দেয়া হয়, সম্পূর্ণ সোর্স কোড এর পরিমার্জিত সংস্করণ উপলব্ধ তৈরি করা আবশ্যক।
সংস্করণ
সার্চ পিয়ারটিউব
@@ -150,7 +150,7 @@
লিনগালা
লিথুনীয়
লোজবান
-
+ লুবা-কাতাঙ্গা
লাক্সেমবোর্গীয়
ম্যাসিডোনিয়
মালাগাসি
@@ -285,8 +285,8 @@
গাঢ় বেগুনি
অ্যাকাউন্ট
সাম্প্রতিক
- প্লেব্যাক এর গতি
- কোয়ালিটি
+ প্লেব্যাক এর গতি (%1$s)
+ কোয়ালিটি (%1$s)
ভিডিও
চ্যানেলগুলি
সম্পর্কিত
@@ -306,4 +306,51 @@
নিচের তালিকা থেকে একটি সার্ভার নিন অথবা সরাসরি একটি সার্ভার দিন।
0.75x
1.25x
+ ব্যাকগ্রউন্ড প্লে এর কনফিগারেশন
+ লুক এবং ফিল
+ লগইন আছে
+ পেছনে অডিও স্ট্রিম হিসেবে চালু রাখুন
+ সম্পর্কিত
+ ভিডিও প্লেব্যাক
+ ভিডিও এর লিস্ট
+ আকাউন্ট
+ সার্ভার অনুসন্ধান করুন
+ আপনি কি এই সার্ভার রিমুভ করতে চান সার্ভার বই থেকে\?
+ সার্ভার রিমুভ করুন
+ এড্রেস বই
+ যোগ
+ পাসওয়ার্ড
+ ইউজারনেম
+ সার্চ
+ সার্ভার ইউআরএল
+ লেবেল
+ সাহায্য ও মতামত
+ লগ আউট
+ সঠিক ইউ আর এল দরকার
+ সার্ভার লেবেল দরকার
+ সার্ভার বই খালি আছে
+ লগইন সফল হয় নি!
+ লগইন হয়েছে
+ বাংলা (বাংলাদেশ)
+ আপনি কি পুরোপুরি সার্চ ইতিহাস মুছে ফেলতে চান\?
+ সার্চ ইতিহাস মুছে ফেলুন
+ চালু ভিডিও কি করবে যখন পেছনে যাবে
+ অ্যান্ড্রয়েড সেটিং এ পিকচার ইন পিকচার পারমিশন বন্ধ আছে এই আয়াপ এ
+ অ্যান্ড্রয়েড ভার্সন ভাসমান ভিডিও সাপোর্ট করে
+ ভাসমান উইন্ডো তে ভিডিও চালু রাখুন
+ সব প্লেব্যাক বন্ধ করুন
+ ভাষা পছন্দ করুন অ্যাপ্লিকেশান এর জন্য। রিস্টার্ট করুন পরিবর্তন দেখার জন্য।
+ অ্যাপ্লিকেশান এর ভাষা
+ ভিডিও চলার সময় ব্যাকগ্রাউন্ড প্লে পজ হবে ব্যাক বাটন প্রেস করলে।
+ ব্যাক বাটন এ পজ
+ NSFW ইন্সটান্স
+ সেটিংস কার্যকলাপ ২
+ ভিডিওঃ %s, স্থানীয় ভিডিওঃ %s
+ হ্যালো ফাঁকা টুকরা
+ বিল্ড এর সময়
+ স্বয়ংক্রিয়
+ টোকেন রিফ্রেশ হয়েছে
+ টোকেন রিফ্রেশ করা যায় নি
+ নেটওয়ার্ক ত্রটি, দয়া করে সংযোগ দেখো
+ ফিল্টার তালিকা
\ No newline at end of file
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index aae549c..c05bea4 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -20,7 +20,7 @@
Dieses Passwort ist falsch
Einstellungen
Aktuell
- " Abrufe"
+ " Aufrufe"
Video-Vorschaubild
Konto-Avatar
NSFW-Inhalt
@@ -36,7 +36,7 @@
Ungültige URL.
Dunkler Modus
Farbschema
- Dieses Feld ist erforderlich
+ Dieses Feld wird benötigt
Trends
Ein Neustart ist erforderlich, um diese Änderung durchzuführen.
Ein Neustart ist erforderlich, um diese Änderung durchzuführen.
@@ -276,8 +276,8 @@
Lizenz
Sprache
Tags
- Wiedergabegeschwindigkeit
- Qualität
+ Wiedergabegeschwindigkeit (%1$s)
+ Qualität (%1$s)
Videos
Kanäle
Über
@@ -287,7 +287,7 @@
Mitglied seit:
Etwas ist schiefgelaufen, bitte versuche es später noch einmal!
Server auswählen
- Kontaktberechtigung für die E-Mail-Vervollständigung erteilen.
+ Berechtigung zum Auslesen der Kontakte für die E-Mail-Vervollständigung erteilen.
Eine Videosprache auswählen, statt alle Videos in allen Sprachen anzuzeigen.
Falls aktiviert, werden Videos im Hintergrund weiter abgespielt.
Wählen Sie einen Server aus der Liste oder geben Sie ihn direkt ein.
@@ -297,7 +297,7 @@
\nGNU Affero General Public License v3.0
\n
\nBerechtigungen dieser stärksten Copyleft-Lizenz bedingen, sämtlichen Quellcode von lizenzierten Werken und Modifikationen, einschließlich größere Werke, die ein lizenziertes Werk verwenden, unter derselben Lizenz bereitzustellen. Urheberrechts- und Lizenzhinweise müssen erhalten bleiben. Mitarbeitende gewähren eine ausdrückliche Genehmigung der Verwertungsrechte. Wenn eine modifizierte Version verwendet wird, um einen Dienst über ein Netzwerk anzubieten, muss der vollständige Quellcode der modifizierten Version verfügbar gemacht werden.
- Videowiedergabe über einen Torrentstream. Dies erfordert Speicherberechtigungen. (Alphastadium, nicht stabil!)
+ Videowiedergabe via Torrent-Stream. Dies benötigt Speicherberechtigungen. (Alpha, nicht stabil!)
1,25×
0,75×
Hinzufügen
@@ -314,4 +314,37 @@
Suchverlauf löschen
Wählen Sie die Sprache für die Anwendungsschnittstelle aus. Starten Sie die Anwendung neu, damit die Änderung wirksam wird.
Sprache der Anwendung
+ Über
+ Videowiedergabe
+ Videoliste
+ Videos: %s, Lokale Videos: %s
+ Wiedergabe stoppen
+ Token erneuert
+ Konnte das Token nicht erneuern
+ Automatisch
+ Aussehen
+ Server suchen
+ Sind Sie sicher, dass Sie diesen Server aus ihrem Adressbuch entfernen möchten\?
+ Server entfernen
+ Adressbuch
+ Die Bild-in-Bild-Berechtigung ist für diese Anwendung in den Android-Einstellungen deaktiviert
+ Konfiguration für Hintergrundwiedergabe
+ Im Hintergrund als Audiostream weiterhören
+ Konto
+ Bengalisch (Bangladesch)
+ Unterbrechen der Hintergrundwiedergabe, wenn Sie während der Videowiedergabe zurück drücken.
+ Pause bei Zurück-Taste
+ Aktivitätseinstellungen2
+ Netzwerkfehler, bitte kontrollieren sie ihre Verbindung
+ Was geschehen soll, wenn ein abspielendes Video in den Hintergrund verschoben wird
+ Diese Android Version unterstützt keine Wiedergabe im schwebendem Fenster
+ In schwebendem Fenster weiterspielen
+ Erstellungszeit
+ NSWF-Instanz
+ Hat Anmeldungsdaten
+ Bezeichnung
+ Serverbezeichnung wird benötigt
+ Das Serververzeichnis ist leer
+ Hallo leeres Fragment
+ Liste filtern
\ No newline at end of file
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 8c61319..7686ca0 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -3,7 +3,7 @@
Ajustes
Iniciar sesión
Servidor
- Correo / Usuario
+ Correo / Nombre de usuario
Contraseña
Iniciar sesión
Iniciar sesión
@@ -96,8 +96,8 @@
Licencia
Idioma
Etiquetas
- Velocidad de reproducción
- Calidad
+ Velocidad de reproducción (%1$s)
+ Calidad (%1$s)
Vídeos
Canales
Acerca de
@@ -113,4 +113,65 @@
\nLos permisos de esta fuerte licencia copyleft están condicionados a hacer disponible el código fuente completo de los trabajos licenciados y las modificaciones, que incluyen trabajos más grandes usando un trabajo licenciado, bajo la misma licencia. Los derechos de autor y los avisos de licencia deben ser preservados. Los colaboradores proporcionan una concesión expresa de los derechos de patente. Cuando se utiliza una versión modificada para proporcionar un servicio a través de una red, el código fuente completo de la versión modificada debe estar disponible.
1,25×
0,75×
+ Idioma de la aplicación
+ Ayuda y feedback
+ Cerrar sesión
+ Una URL válida es requerida
+ La etiqueta de servidor es requerida
+ Ruso (Lenguaje de señas)
+ Ruso
+ Romano
+ Portugués
+ Polaco
+ Noruego
+ Pakistaní (Lenguaje de señas)
+ Francés (Lenguaje de señas)
+ Francés
+ Finlandés
+ Esperanto
+ Inglés
+ Danés (Lenguaje de señas)
+ Danés
+ Checo (Lenguaje de señas)
+ Checo
+ Croata
+ Vasco
+ Bengali
+ Bieloruso
+ Bashkir
+ Bambara
+ Aymara
+ Avaric
+ Assamese
+ Amharic
+ Akan
+ Afrikaans
+ Abkhazian
+ Token refrescado
+ No se pudo refrescar el token
+ Reproducción de video
+ Lista de video
+ Cuenta
+ Buscar servidor
+ ¿Estás seguro de que deseas eliminar este servidor de la libreta de direcciones\?
+ Quitar servidor
+ Libreta de direcciones
+ Servidor actual
+ Contraseña
+ Usuario
+ Buscar
+ URL del servidor
+ Etiqueta
+ Añadir
+ Error en el inicio de sesión!
+ ¿Deseas eliminar de forma permanente tu historial de búsqueda\?
+ Limpiar el historial de búsquedas
+ El permiso para modo picture-in-picture está desactivado para esta aplicación en los Ajustes de Android
+ Versión de Android no soporta ventanas flotantes
+ Configuración de reproducción en segundo plano
+ Continuar reproduciendo en ventana flotante
+ Detener todas las reproducciones
+ Continuar como audio en segundo plano
+ Selecciona el idioma de la interfaz de la aplicación. Reinicia para que los cambios se apliquen.
+ Pausar con el botón de retroceso
\ No newline at end of file
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index 78b7b91..29f9719 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -103,7 +103,7 @@
maori
oriya (makrokieli)
bislama
- Laatu
+ Laatu (%1$s)
Jotain meni pieleen, yritä myöhemmin!
bulgaria
uzbekki
@@ -204,7 +204,7 @@
navajo
kanuri
sunda
- Toistonopeus
+ Toistonopeus (%1$s)
sichuanin-yi
Punainen
Videon esikatselukuva
@@ -300,4 +300,6 @@
turkmeeni
1,25×
0,75×
+ Valitse kieli sovelluksen käyttöliittymälle. Käynnistä sovellus uudelleen, jotta muutos tulee voimaan.
+ Sovelluksen kieli
\ No newline at end of file
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 45dac4c..5aab696 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -8,7 +8,7 @@
Mot de passe
Se connecter
Se connecter
- Cette adresse de courriel n\'est pas valide
+ Cette adresse courriel est invalide
Ce mot de passe est trop court
Ce mot de passe est incorrect
Ce champ est requis
@@ -35,7 +35,7 @@
Licence
\nGNU Affero General Public License v3.0
-\n
+\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.
Version
Rechercher sur PeerTube
@@ -86,6 +86,7 @@
Serveur réglé sur : %s
Sélectionnez un serveur de la liste ci-dessous ou entrez-le directement.
URL du serveur PeerTube
+ Filtrer la liste
Compte
Signaler
Liste noire
@@ -99,8 +100,8 @@
Licence
Langue
Étiquettes
- Vitesse de lecture
- Qualité
+ Vitesse de lecture (%1$s)
+ Qualité (%1$s)
Vidéos
Chaînes
À propos
@@ -109,6 +110,7 @@
Description :
Inscrit·e le :
Quelque chose s’est mal passé, veuillez essayer plus tard !
+ Problème réseau, veuillez vérifier votre connexion
Sélectionnez un serveur
abkhaze
afar
@@ -187,7 +189,7 @@
japonais
langue des signes japonaise
javanais
- kalaallisut
+ groenlandais
kannada
kanuri
cachemiri
@@ -306,17 +308,17 @@
0,75×
1,25×
Carnet d\'adresses
- Identification réussie
+ Identifié
Identification échouée !
a un identifiant
Ajouter
Mot de passe
Nom d\'utilisateur
Rechercher
- Url du serveur
+ URL du serveur
Étiquette
- Aide et commentaire
- Déconnexion
+ Aide et remarques
+ Se déconnecter
Une URL valide est requise
L\'étiquette du serveur est obligatoire
Le livre des serveurs est vide
@@ -326,8 +328,10 @@
Langue de l\'application
Mettre la lecture d\'arrière-plan en pause en appuyant sur la touche de retour pendant la lecture de la vidéo.
Pause sur le bouton retour
- À propos
Apparence
+ SettingsActivity2
+ Bengalais (Bangladesh)
+ À propos
Compte
Paramètres de lecture en fond
Votre version Android ne supporte pas la lecture de vidéos dans une fenêtre flottante
@@ -338,7 +342,14 @@
Continuer dans une fenêtre flottante
Sélectionner le mode de fonctionnement de la lecture de vidéo lorsque l\'application est mise en arrière-plan
Liste de vidéos
- Sélectionner un serveur
+ Serveur de recherche
Retirer un serveur
Voulez-vous vraiment retirer ce serveur de votre carnet d\'adresses ?
+ Automatique
+ Instance avec du contenu adulte
+ Bonjour ! Fragment vide
+ Vidéos : %s, Vidéos locales : %s
+ Temps de construction
+ Jeton rafraîchi
+ Impossible de rafraîchir le jeton
\ No newline at end of file
diff --git a/app/src/main/res/values-gd/strings.xml b/app/src/main/res/values-gd/strings.xml
index d338263..0a91e2f 100644
--- a/app/src/main/res/values-gd/strings.xml
+++ b/app/src/main/res/values-gd/strings.xml
@@ -285,8 +285,8 @@
Ceadachas
Cànan
Tagaichean
- Luaths na cluiche
- Càileachd
+ Luaths na cluiche (%1$s)
+ Càileachd (%1$s)
Videothan
Seanailean
Mu dhèidhinn
diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml
new file mode 100644
index 0000000..a6b3dae
--- /dev/null
+++ b/app/src/main/res/values-id/strings.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 9f0d2e8..f0ed19f 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -3,11 +3,11 @@
Impostazioni
Accedi
Server
- Email / Nome utente
+ E-mail / Nome utente
Password
Accedi
Accedi
- Questo indirizzo email non è valido
+ Questo indirizzo e-mail non è valido
La password è troppo corta
Questa password non è corretta
Questo campo è obbligatorio
@@ -32,10 +32,10 @@
Altro
Condividi
URL non valido.
- Riavviare l\'applicazione affinché la modalità Dark Mode abbia effetto.
+ Riavvia l\'applicazione affinché la modalità scura abbia effetto.
Tema dell\'app
Riavviare l\'applicazione affinché il tema abbia effetto.
- Lettore Video Torrent
+ Lettore video Torrent
Riproduzione di Video tramite torrent stream. Questo richiede i permessi di archiviazione. (Alfa, non stabile!)
Licenza
Versione
@@ -46,7 +46,7 @@
Server PeerTube
Riproduzione in sottofondo
Se abilitata, continua a riprodurre il video in sottofondo.
- Modo scuro
+ Modalità scura
\nGNU Affero General Public License v3.0
\n
@@ -286,8 +286,8 @@
Licenza
Lingua
Parole chiave
- Velocità di riproduzione
- Qualità
+ Velocità di riproduzione (%1$s)
+ Qualità (%1$s)
Video
Canali
A proposito
@@ -316,4 +316,35 @@
Cancella la cronologia delle ricerche
Seleziona la lingua per l\'interfaccia dell\'applicazione. Riavvia l\'app per rendere effettive le modifiche.
Lingua dell\'applicazione
+ Come la riproduzione video risponde quando va in sottofondo
+ Token aggiornato
+ Impossibile aggiornare il token
+ Tempo di costruzione
+ Automatico
+ Videos: %s, Video locali: %s
+ Instanza NSFW
+ Aspetto
+ Info
+ Riproduzione video
+ Lista dei video
+ ImpostazioniAttività2
+ Account
+ Cerca server
+ Sicuro di voler rimuovere questo server dalla rubrica\?
+ Server remoto
+ Rubrica
+ Etichetta
+ L\'etichetta del server è obbligatoria
+ Ciao frammento vuoto
+ Bengalese (Bangladesh)
+ Il permesso della modalità Picture-in-Picture è disattivata per questa app nelle impostazioni Android
+ Questa versione di Android non supporta la lettura fluttuante del video
+ Configurazione della lettura in sottfondo
+ Continua riproduzione in una finestra fluttuante
+ Ferma la lettura video
+ Continua come flusso sonoro in sottofondo
+ Metti la riproduzione di sottofondo in pausa quando premi il tasto indietro durante la lettura del video.
+ Pausa sul tasto backspace
+ Errore di accesso alla rete, controlla la tua connettività
+ Elenco dei filtri
\ No newline at end of file
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index c9616a4..29b6f63 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -88,8 +88,8 @@
ラインセンス
言語
タグ
- 再生速度
- クオリティ
+ 再生速度 (%1$s)
+ クオリティ(%1$s)
ビデオ
チャンネル
情報
diff --git a/app/src/main/res/values-ks/strings.xml b/app/src/main/res/values-ks/strings.xml
new file mode 100644
index 0000000..a6b3dae
--- /dev/null
+++ b/app/src/main/res/values-ks/strings.xml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml
index abfcf6f..fbdfb61 100644
--- a/app/src/main/res/values-nb-rNO/strings.xml
+++ b/app/src/main/res/values-nb-rNO/strings.xml
@@ -51,8 +51,8 @@
Lisens
Språk
Etiketter
- Avspillingshastighet
- Kvalitet
+ Avspillingshastighet (%1$s)
+ Kvalitet (%1$s)
Videoer
Kanaler
Om
@@ -74,7 +74,7 @@
Videoavspilling via en torrentstrøm. Dette krever lagringstilgang. (Alfa, ikke stabilt!)
Lisens
-\nGNU Affero General Public Lisens v3.0
+\nGNU Affero General Public Lisens v3.0
\n
\nRettigheter til denne sterkeste av copyleft-lisenser er prisgitt at hele kildekoden for lisensierte verker og endringer frigis, som inkluderer større utledede arbeider, under samme lisens. Kopirett og lisensmerknader må bevares. Bidragsytere må besørge uttrykt innvilgelse av patentrettigheter. Når en endret versjon brukes for å tilby en tjeneste over et nettverk, må hele kildekoden for den endrede versjonen tilgjengeliggjøres.
Versjon
@@ -124,4 +124,66 @@
Vietnamesisk
1,25×
0,75×
+ Ønsker du å slette all søkehistorikk for godt\?
+ Tøm søkehistorikk
+ Hvordan avspilling av video utføres når den sendes til bakgrunnen
+ Bilde-i-bilde -tilgang er mangler for dette programmet i Android-innstillingene
+ Android-versjonen støtter ikke flytende video
+ Oppsett av bakgrunnsavspilling
+ Fortsett video|avspilling i flytende vindu
+ Opphold i bakgrunnsavspilling når \"Tilbake\" trykkes under videoavspilling.
+ Sett på pause med \"Tilbake\"-knapp
+ Stopp all avspilling
+ Fortsett som lydstrøm i bakgrunnen
+ Velg språk for programgrensesnittet. Start programmet på ny for å utføre endringene.
+ Programspråk
+ Tjener-nettadresse
+ Søk
+ Username
+ Legg til
+ Passord
+ Adressebok
+ Fjern tjener
+ Om
+ Tjeneradressebok tom
+ SettingsActivity2
+ Symbol gjenoppfrisket
+ Kunne ikke gjenoppfriske symbol
+ Byggtid
+ Automatisert
+ Videoer: %s, lokale videoer: %s
+ Utseende og oppførsel
+ Videoavspilling
+ Videoliste
+ Konto
+ Søk i tjener
+ Er du sikker på at du ønsker å fjerne denne tjeneren fra adresseboken\?
+ Har innlogging
+ Etikett
+ Hjelp og tilbakemelding
+ Logg ut
+ Gyldig nettadresse kreves
+ Tjeneretikett kreves
+ Kunne ikke logge inn
+ Innlogget
+ Hei blanke fragment
+ Tilknytningsfeil, sjekk tilkoblingen din
+ Filterliste
+ tibetansk
+ thai
+ telugu
+ tamil
+ sundanesisk
+ sinhala
+ mongolsk
+ malayalam
+ laotisk
+ kannada
+ khmer
+ javanesisk
+ hebraisk
+ gujarati
+ bengalsk
+ armensk
+ Arbeidsutrygg insans
\ No newline at end of file
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index b859884..ababf17 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -275,8 +275,8 @@
Licentie
Taal
Labels
- Afspeelsnelheid
- Kwaliteit
+ Afspeelsnelheid (%1$s)
+ Kwaliteit (%1$s)
Video\'s
Kanalen
Over
@@ -322,4 +322,27 @@
App-taal
Pauzeer het afspelen als er op de terugknop wordt gedrukt.
Pauzeren na drukken op terugknop
+ Uiterlijk
+ Over
+ Video afspelen
+ Videolijst
+ SettingsActivity2
+ Account
+ Server zoeken
+ Weet je zeker dat je deze server wilt verwijderen uit het adresboek\?
+ Server verwijderen
+ Bengaals (Bangladesh)
+ Hoe een video moet worden afgespeeld op de achtergrond
+ Picture-in-picturemachtiging is niet afgegeven voor deze app in de Android-instellingen
+ Deze Android-versie ondersteunt geen zwevende video\'s
+ Afspelen op achtergrond
+ Video afspelen in zwevend venster
+ Afspelen stoppen
+ Audio afspelen op achtergrond
+ Bouwtijd
+ Geautomatiseerd
+ Video\'s: %s - Lokale video\'s: %s
+ NSFW-instantie
+ Toegangssleutel verversd
+ Kan toegangssleutel niet verversen
\ No newline at end of file
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 9367e80..430e1e7 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -48,8 +48,8 @@
Konto:
Kanały
Filmy
- Jakość
- Prędkość odtwarzania
+ Jakość (%1$s)
+ Prędkość odtwarzania (%1$s)
Znaczniki
Język
Licencja
@@ -300,4 +300,22 @@
Licencja
1,25×
0,75×
+ Odtwarzanie Wideo
+ Lista Wideo
+ Konto
+ Dodaj
+ Hasło
+ Wyszukaj
+ Serwer URL
+ Pomoc i Opinie
+ Wyloguj
+ Pomyślnie zalogowano
+ Błąd dostępu do sieci, sprawdź swoje połączenie
+ Lista filtrów
+ Bengalski (Bangladesz)
+ Czy chcesz trwale usunąć historię wyszukiwań\?
+ Usuń historię wyszukiwań
+ Ustawienia odtwarzania w tle
+ Kontynuuj odtwarzanie w ruchomym oknie
+ Język Aplikacji
\ No newline at end of file
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
new file mode 100644
index 0000000..25035ac
--- /dev/null
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -0,0 +1,350 @@
+
+
+ Servidor NSFW
+ Visual e Funcionalidade
+ Sobre
+ Reprodução de vídeo
+ Lista de vídeos
+ SettingsActivity2
+ Conta
+ Busca servidor
+ Tem certeza que quer excluir este servidor da lista de contatos\?
+ Excluir servidor
+ 1.25x
+ 0.75x
+ Lista de contactos
+ Servidor atual
+ Tem login
+ Adicionar
+ Senha
+ Nome do usuário
+ Busca
+ URL do servidor
+ Nome Identificador
+ Ajuda e Opiniões
+ Sair
+ URL válido é requerido
+ Categoria do servidor é requerido
+ O Servidor de Reservas está vazio
+ Login Falhou!
+ Logado
+ Olá secção em branco
+ Selecione o servidor
+ Algo deu errado, por favor tente mais tarde!
+ Membro desde:
+ Descrição:
+ Assinantes:
+ Conta:
+ Sobre
+ Canais
+ Vídeos
+ Qualidade (%1$s)
+ Velocidade de reprodução (%1$s)
+ Categorias
+ Idioma
+ Licença
+ Categoria
+ Privacidade
+ Baixar
+ Compartilhar
+ Você deve fazer o login para usar este serviço
+ Classificação falhou
+ Não é possível fazer o download do vídeo sem permissão de gravação
+ Lista negra
+ Relatar
+ Conta
+ URL do servidor de PeerTube
+ Selecione um servidor da lista abaixo ou digite-o diretamente.
+ Servidor configurado para: %s
+ Não
+ Sim
+ Inscrição permitida: %s
+ Selecione o servidor
+ 2x
+ 1.5x
+ Normal
+ 0.5x
+ Bluegray
+ Cinza
+ Marrom
+ Laranja Profunda
+ Laranja
+ Âmbar
+ Amarelo
+ Lime
+ Verde claro
+ Verde
+ Teal
+ Ciano
+ Azul claro
+ Azul
+ Índigo
+ Púrpura profunda
+ Púrpura
+ Cor-de-rosa
+ Vermelho
+ Zulu
+ Zhuang
+ Yoruba
+ Yiddish
+ Xhosa
+ Wolof
+ Frisiano Ocidental
+ Galês
+ Walloon
+ Vietnamita
+ Venda
+ Uzbeque
+ Urdu
+ Ucraniano
+ Uighur
+ Twi
+ Turcomeno
+ Turco
+ Tswana
+ Tsonga
+ Tonga (Ilhas Tonga)
+ Tigrinya
+ Tibetano
+ Tailandês
+ Telugu
+ Tatar
+ Tamil
+ Tajik
+ Taitiano
+ Tagalog
+ Língua Sueca de Sinais
+ Sueco
+ Swati
+ Swahili (macrolinguagem)
+ Sundanese
+ Espanhol
+ Língua de sinais sul-africana
+ Somali
+ Esloveno
+ Eslovaco
+ Sinhala
+ Sindhi
+ Sichuan Yi
+ Shona
+ Servo-Croata
+ Sérvio
+ Gaélico escocês
+ Língua de sinais da Arábia Saudita
+ Sardo
+ Sango
+ Samoan
+ Língua de sinais russa
+ Russo
+ Rundi
+ Romanche
+ Romeno
+ Quechua
+ Pushto
+ Português
+ Polonês
+ Persa
+ Panjabi
+ Língua de sinais do Paquistão
+ Ossetian
+ Oromo
+ Oriya (macrolanguage)
+ Ojibwa
+ Occitan
+ Nyanja
+ Norueguês Nynorsk
+ Bokmål norueguês
+ Norueguês
+ Nepalês (macrolinguagem)
+ Ndonga
+ Navajo
+ Nauru
+ Mongol
+ Grego moderno (1453-)
+ Marshallese
+ Marathi
+ Maori
+ Manx
+ Maltês
+ Malayalam
+ Malay (macrolanguage)
+ Malagasy
+ Macedônio
+ Luxemburguês
+ Luba-Katanga
+ Lojban
+ Lituano
+ Lingala
+ Limburgan
+ Letão
+ Lao
+ Curdo
+ Kuanyama
+ Kotava
+ Coreano
+ Kongo
+ Komi
+ Klingon
+ Kirghiz
+ Kinyarwanda
+ Kikuyu
+ Khmer
+ Kazakh
+ Kashmiri
+ Kanuri
+ Kannada
+ Kalaallisut
+ Javanese
+ Língua japonesa de sinais
+ Japonês
+ Italiano
+ Irlandês
+ Inupiaq
+ Inuktitut
+ Indonésio
+ Igbo
+ Islandês
+ Húngaro
+ Hiri Motu
+ Hindi
+ Herero
+ Hebraico
+ Hausa
+ Haitiano
+ Gujarati
+ Guarani
+ Língua Alemã de Sinais
+ Alemão
+ Georgian
+ Ganda
+ Galician
+ Fulah
+ Língua de sinais francesa
+ Francês
+ Finnish
+ Fijian
+ Faroese
+ Ewe
+ Estonian
+ Esperanto
+ Inglês
+ Dzongkha
+ Dutch
+ Dhivehi
+ Língua de sinais dinamarquesa
+ Danish
+ Língua de sinais tcheca
+ Czech
+ Croatian
+ Cree
+ Corsican
+ Cornish
+ Chuvash
+ Língua chinesa de sinais
+ Chinês
+ Chechen
+ Chamorro
+ Catalan
+ Burmese
+ Bulgarian
+ Língua de sinais britânica
+ Breton
+ Língua Brasileira de Sinais
+ Bosnian
+ Bislama
+ Bengali (Bangladesh)
+ Bengali
+ Belarusian
+ Basque
+ Bashkir
+ Bambara
+ Azerbaijani
+ Aymara
+ Avaric
+ Assamese
+ Armenian
+ Aragonese
+ Arabic
+ Amharic
+ Linguagem dos sinais americana
+ Albanian
+ Akan
+ Afrikaans
+ Abkhazian
+ Você quer apagar permanentemente o histórico de busca\?
+ Limpiar todo histórico de busca
+ Como um vídeo em reprodução responde quando vai para o fundo
+ A permissão Picture-in-Picture está desativada para este aplicativo nas Configurações do Android
+ A versão de Android não suporta vídeo flutuante
+ Configuração da reprodução no fundo
+ Continuar reproduzindo vídeo na janela flutuante
+ Parar toda a reprodução
+ Continuar como um Stream de áudio no fundo
+ Selecione o idioma para a interface do aplicativo. Reinicie o aplicativo para que a alteração tenha efeito.
+ Idioma do aplicativo
+ Pausa no clicar botão voltar
+ Pausar a reprodução no fundo ao pressionar botão voltar durante a reprodução do vídeo.
+ Se ativado, continua a reprodução de vídeo no fundo.
+ Reprodução no fundo
+ Servidor de PeerTube
+ Selecione um idioma de vídeo, em vez de mostrar todos os vídeos em todos os idiomas.
+ Filtro de idiomas
+ Afar
+ "
+\n<b>GNU Affero Licença Pública Geral v3.0</b>
+\n
+\nAs permissões desta licença mais forte de copyleft estão condicionadas a disponibilizar o código fonte completo de obras licenciadas e modificações, que incluem obras maiores usando uma obra licenciada, sob a mesma licença. Os avisos de direitos autorais e de licença devem ser preservados. Os contribuidores fornecem uma concessão expressa de direitos de patente. Quando uma versão modificada é usada para fornecer um serviço através de uma rede, o código-fonte completo da versão modificada deve ser disponibilizado."GNU Affero General Public License v3.0 \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.
+ Sotho do Sul
+ Ndebele do Sul
+ Sami do Norte
+ Ndebele do Norte
+ Token atualizado
+ Não foi possível atualizar o token
+ Build Time
+ Automático
+ Vídeos: %s, Vídeos locais: %s
+ Mostrar conteúdo NSFW
+ Conteúdo NSFW
+ Versão
+ Licença
+ Reprodução de torrent vídeo. Isto requer permissões de armazenamento. (Alfa, não estável!)
+ Reprodutor de Torrent Vídeos
+ Reinicie o aplicativo para que o tema tenha efeito.
+ Tema do App
+ Reinicie o aplicativo para que o Tema Escuro tenha efeito.
+ Tema Oscuro
+ URL inválido.
+ Compartilhar
+ Mais
+ Sem resultados
+ Busca
+ Busca no PeerTube
+ UrlVideoPlayActivity
+ Avatar da conta
+ Miniatura do vídeo
+ " Visualizações"
+ Conta
+ Subscrições
+ Local
+ Recente
+ Tendências
+ Descobrir
+ Conta
+ Sair
+ Configurações
+ Busca
+ Conceda permissão de contato para preenchimento de e-mail.
+ Este campo é obrigatório
+ Esta senha está incorreta
+ Esta senha é muito curta
+ Este endereço de correio eletrônico é inválido
+ Entrar
+ Entrar
+ Senha
+ E-mail / Nome de usuário
+ Servidor
+ Entrar
+ Configurações
+ Erro de acesso à rede, verifique sua conectividade
+ Filtrar a lista
+
\ No newline at end of file
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
new file mode 100644
index 0000000..adcc3a5
--- /dev/null
+++ b/app/src/main/res/values-pt/strings.xml
@@ -0,0 +1,350 @@
+
+
+ Parar toda a reprodução
+ Akan
+ Língua de sinais sul-africana
+ Bokmål norueguês
+ Venda
+ Busca
+ E-mail / Nome de utilizador
+ Busca no PeerTube
+ Belarusian
+ Este campo é obrigatório
+ Uzbeque
+ Busca servidor
+ Taitiano
+ URL inválido.
+ Chinês
+ Tema Oscuro
+ Nome Identificador
+ Catalan
+ Tajik
+ Finnish
+ Tonga (Ilhas Tonga)
+ Subscrições
+ Esta palavra-passe é muito curta
+ Conta
+ Russo
+ Frisiano Ocidental
+ Nome do utilizador
+ Sair
+ Lista de vídeos
+ Cornish
+ Tibetano
+ Índigo
+ Não é possível fazer o download do vídeo sem permissão de gravação
+ 2x
+ Assamese
+ Servidor de PeerTube
+ Login Falhou!
+ Persa
+ 0.5x
+ Local
+ Esperanto
+ Limburgan
+ Classificação falhou
+ Reprodução no fundo
+ Língua de sinais tcheca
+ Nyanja
+ Arabic
+ Kashmiri
+ Língua chinesa de sinais
+ Kanuri
+ Ucraniano
+ Faroese
+ Miniatura do vídeo
+ A permissão Picture-in-Picture está desativada para esta app nas Configurações do Android
+ Polonês
+ Qualidade (%1$s)
+ Bashkir
+ Lao
+ Burmese
+ Kuanyama
+ Kikuyu
+ Reinicie a app para que o Tema Escuro tenha efeito.
+ Klingon
+ Indonésio
+ Língua japonesa de sinais
+ Inglês
+ Tem certeza que quer remover este servidor da lista de contatos\?
+ Vietnamita
+ Âmbar
+ Assinantes:
+ Configurações
+ Oromo
+ Aragonese
+ Walloon
+ Gaélico escocês
+ Servidor atual
+ Reprodução de torrent vídeo. Isto requer permissões de armazenamento. (Alfa, não estável!)
+ Breton
+ Chamorro
+ Compartilhar
+ Fulah
+ Idioma do aplicação
+ Norueguês
+ Língua de sinais do Paquistão
+ Servidor NSFW
+ Púrpura profunda
+ Norueguês Nynorsk
+ Malayalam
+ Francês
+ Ossetian
+ 0.75x
+ Privacidade
+ Malagasy
+ Samoan
+ Descrição:
+ Língua de sinais da Arábia Saudita
+ Servidor
+ Maltês
+ Azul
+ Olá secção em branco
+ Conta
+ Tamil
+ Kalaallisut
+ Khmer
+ Avatar da conta
+ Ndebele do Sul
+ Selecione um idioma de vídeo, em vez de mostrar todos os vídeos em todos os idiomas.
+ O Servidor de Reservas está vazio
+ Púrpura
+ A versão de Android não suporta vídeo flutuante
+ Sami do Norte
+ Entrar
+ Categoria
+ Se ativado, continua a reprodução de vídeo no fundo.
+ Chuvash
+ Herero
+ Remover servidor
+ Licença
+ Reprodução de vídeo
+ Língua Brasileira de Sinais
+ Amharic
+ Croatian
+ Marshallese
+ Komi
+ Língua Alemã de Sinais
+ " Visualizações"
+ Bluegray
+ Nauru
+ Ewe
+ Sueco
+ Lista de contactos
+ Curdo
+ Amarelo
+ UrlVideoPlayActivity
+ Sim
+ Servidor configurado para: %s
+ Kirghiz
+ Cinza
+ Como um vídeo em reprodução responde quando vai para o fundo
+ Conta
+ Selecione o servidor
+ URL do servidor de PeerTube
+ Compartilhar
+ Pushto
+ Armenian
+ Sango
+ Occitan
+ Quer apagar permanentemente o histórico de busca\?
+ Língua de sinais dinamarquesa
+ Palavra-passe
+ Sundanese
+ Bengali
+ 1.25x
+ Malay (macrolanguage)
+ Gujarati
+ Afar
+ Kotava
+ Descobrir
+ Canais
+ Reinicie a app para que o tema tenha efeito.
+ Sérvio
+ Tsonga
+ Configuração da reprodução no fundo
+ Haitiano
+ URL válido é requerido
+ Sobre
+ Este endereço de correio eletrónico é inválido
+ Tailandês
+ Rundi
+ Czech
+ Navajo
+ Guarani
+ Panjabi
+ Categoria do servidor é requerido
+ Luxemburguês
+ Sardo
+ Laranja Profunda
+ Continuar como um Stream de áudio no fundo
+ Mais
+ Lista negra
+ Selecione o idioma para a interface da app. Reinicie a app para que a alteração tenha efeito.
+ Mostrar conteúdo NSFW
+ Danish
+ Verde claro
+ Igbo
+ Abkhazian
+ Português
+ SettingsActivity2
+ Tswana
+ Língua de sinais russa
+ Aymara
+ Sair
+ Entrar
+ Sindhi
+ Token atualizado
+ Bulgarian
+ Tema do App
+ Hindi
+ Logado
+ Galês
+ Bosnian
+ Selecione o servidor
+ Zhuang
+ Quechua
+ Pausa no clicar botão voltar
+ Servo-Croata
+ 1.5x
+ Língua de sinais britânica
+ Linguagem dos sinais americana
+ Limpiar todo histórico de busca
+ Relatar
+ Bislama
+ Romeno
+ Kinyarwanda
+ Conceda permissão de contato para preenchimento de e-mail.
+ Georgian
+ Sem resultados
+ Islandês
+ Zulu
+ Hiri Motu
+ Cree
+ Eslovaco
+ Configurações
+ Javanese
+ URL do servidor
+ Dhivehi
+ Automático
+ Deve fazer o login para usar este serviço
+ Nepalês (macrolinguagem)
+ Tatar
+ Filtro de idiomas
+ Húngaro
+ Afrikaans
+ Vídeos
+ Hausa
+ Reprodutor de Torrent Vídeos
+ Língua Sueca de Sinais
+ Visual e Funcionalidade
+ Inupiaq
+ Yiddish
+ Avaric
+ Romanche
+ Espanhol
+ Conta
+ Lingala
+ Licença
+ Italiano
+ Teal
+ Marathi
+ Urdu
+ "
+\n<b>GNU Affero Licença Pública Geral v3.0</b>
+\n
+\nAs permissões desta licença mais forte de copyleft estão condicionadas a disponibilizar o código fonte completo de obras licenciadas e modificações, que incluem obras maiores usando uma obra licenciada, sob a mesma licença. Os avisos de direitos autorais e de licença devem ser preservados. Os contribuidores fornecem uma concessão expressa de direitos de patente. Quando uma versão modificada é usada para fornecer um serviço através de uma rede, o código-fonte completo da versão modificada deve ser disponibilizado."GNU Affero General Public License v3.0 \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.
+ Sinhala
+ Normal
+ Versão
+ Ndebele do Norte
+ Kongo
+ Hebraico
+ Estonian
+ Somali
+ Telugu
+ Tem login
+ Luba-Katanga
+ Mongol
+ Esta palavra-passe está incorreta
+ Conteúdo NSFW
+ Bengali (Bangladesh)
+ Turco
+ Dzongkha
+ Conta:
+ Lojban
+ Sobre
+ Continuar reproduzindo vídeo na janela flutuante
+ Bambara
+ Busca
+ Swati
+ Tagalog
+ Busca
+ Vermelho
+ Wolof
+ Tendências
+ Inscrição permitida: %s
+ Azerbaijani
+ Azul claro
+ Ciano
+ Galician
+ Adicionar
+ Ojibwa
+ Coreano
+ Sotho do Sul
+ Lime
+ Xhosa
+ Macedônio
+ Ajuda e Opiniões
+ Yoruba
+ Corsican
+ Albanian
+ Alemão
+ Inuktitut
+ Categorias
+ Japonês
+ Chechen
+ Kannada
+ Basque
+ Entrar
+ Esloveno
+ Build Time
+ Tigrinya
+ Dutch
+ Maori
+ Não foi possível atualizar o token
+ Membro desde:
+ Idioma
+ Verde
+ Lituano
+ Laranja
+ Letão
+ Língua de sinais francesa
+ Descarregar
+ Não
+ Palavra-passe
+ Irlandês
+ Recente
+ Swahili (macrolinguagem)
+ Velocidade de reprodução (%1$s)
+ Turcomeno
+ Uighur
+ Algo deu errado, por favor tente mais tarde!
+ Twi
+ Fijian
+ Marrom
+ Vídeos: %s, Vídeos locais: %s
+ Shona
+ Kazakh
+ Pausar a reprodução no fundo ao pressionar botão voltar durante a reprodução do vídeo.
+ Sichuan Yi
+ Cor-de-rosa
+ Oriya (macrolanguage)
+ Manx
+ Ndonga
+ Grego moderno (1453-)
+ Selecione um servidor da lista abaixo ou digite-o diretamente.
+ Ganda
+ Erro de acesso à rede, por favor verifique a sua conectividade
+ Filtrar a lista
+
\ No newline at end of file
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 2807285..01208b9 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -26,7 +26,7 @@
Сервер PeerTube
Миниатюра видео
- Аватар
+ Аватар аккаунта
Показ NSFW ( контекст сексуального характера)
Показывать NSFW (контент сексуального характера)
Фильтр языков
@@ -34,12 +34,15 @@
Торрент видео плеер
Воспроизведение видео через торрент поток. Это требует разрешения на хранение. (Альфа, не стабильный!)
Лицензия
- Strings related to login
+
+\n Стандартная общественная лицензия GNU Affero v3.0
+\n
+\nРазрешения этой сильнейшей лицензии с авторским левом обусловлены предоставлением полного исходного кода лицензионных произведений и модификаций, которые включают более крупные произведения с использованием лицензионных произведений, по той же лицензии. Уведомления об авторских правах и лицензии должны быть сохранены. Соавторы предоставляют явное предоставление патентных прав. Когда измененная версия используется для предоставления услуги по сети, полный исходный код измененной версии должен быть доступен.
Версия
Поиск PeerTube
Поиск
Нет результатов
- Другое
+ Больше
Поделиться
Недействительная ссылка.
Темный режим
@@ -245,11 +248,11 @@
2×
Фоновое воспроизведение
Если включено, продолжает воспроизводить видео в фоновом режиме.
- Местоположение
+ Локальные
Аккаунт
Аккаунт
- Последний
+ Недавние
" Представления"
Малайский
Маршалловых островов
@@ -277,8 +280,8 @@
Лицензия
Язык
Теги
- Скорость воспроизведения
- Качество
+ Скорость воспроизведения (%1$s)
+ Качество (%1$s)
Описание:
Что-то пошло не так, пожалуйста, попробуйте позже!
Выберите сервер
@@ -303,4 +306,58 @@
UrlVideoPlayActivity
1,25×
0,75×
+ Аккаунт
+ Токен обновлён
+ Не удалось обновить токен
+ Время сборки
+ Автоматически
+ Видео: %s, локальные видео: %s
+ Экземпляр NSFW
+ Стиль оформления
+ О приложении
+ Проигрывание видео
+ Список видео
+ НастройкиАктивности2
+ Поиск сервера
+ Вы уверены, что хотите удалить этот сервер из адресной книги\?
+ Удалить сервер
+ Адресная книга
+ Имеет логин
+ Добавить
+ Пароль
+ Имя пользователя
+ Поиск
+ URL-адрес сервера
+ Метка
+ Помощь и обратная связь
+ Выйти
+ Требуется действительный URL
+ Требуется метка сервера
+ Серверная книга пуста
+ Вход не удался!
+ Успешный вход
+ Привет пустой фрагмент
+ Бенгальский (Бангладеш)
+ Вы хотите навсегда удалить историю поиска\?
+ Очистить историю поиска
+ Как воспроизводимое видео реагирует на переход в фоновый режим
+ Разрешение \"Картинка в картинке\" отключено для этого приложения в настройках Android
+ Версия Android не поддерживает плавающее видео
+ Конфигурация фонового воспроизведения
+ Продолжить воспроизведение видео в плавающем окне
+ Остановить все воспроизведения
+ Продолжить как фоновый аудиопоток
+ Выберите язык интерфейса приложения. Перезапустите приложение, чтобы изменения вступили в силу.
+ Язык приложения
+ Приостановите фоновое воспроизведение при нажатии назад во время воспроизведения видео.
+ Пауза на кнопку Назад
+ Ошибка доступа к сети, проверьте подключение
+ Список фильтров
+ Да
+ Нет
+ Отключить проверку SSL сертификата
+ Дополнительно
+ Внимание!
+ Игнорировать незащищенные соединения. Используйте только если знаете сервер к которому подключаетесь. Требуется перезапуск приложения.
+ "Вы собираетесь отключить валидацию всех SSL сертификатов в Thorium. Это может быть очень опасно если peertube сервер вами не контролируется, потому что \"атака посредника\" может направить трафик на другой сервер. Злоумышленник может записывать пароли и другие личные данные."
\ No newline at end of file
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index 6a7f958..231248c 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -272,8 +272,8 @@
Licens
Språk
Taggar
- Uppspelningshastighet
- Kvalitet
+ Uppspelningshastighet (%1$s)
+ Kvalitet (%1$s)
Videor
Kanaler
Om
@@ -300,4 +300,24 @@
Aktuell server
1,25×
0,75×
+ Byggtid
+ Om
+ Video lista
+ Konto
+ Sök Server
+ Ta bort Server
+ Adressbok
+ Har inloggning
+ Lägg till
+ Lösenord
+ Användarnamn
+ Sök
+ Server URL
+ Hjälp & Feedback
+ Logga ut
+ Giltig URL krävs
+ Inloggning misslyckades!
+ Inloggad
+ Bengali (Bangladesh)
+ Rensa sökhistorik
\ No newline at end of file
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 90b0ae9..9933918 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -263,7 +263,19 @@
Normal
1,5×
2×
- Arkaplanda Oynatma
+ {faw-play-circle}
+ {faw-cog}
+ {faw-check}
+ {faw-check}
+ {faw-expand}
+ {faw-compress}
+ {faw-ellipsis-v}
+ {faw-thumbs-up}
+ {faw-thumbs-down}
+ {faw-share}
+ {faw-download}
+ {faw-save}
+ Arka Planda Oynatma
Etkinleştirilirse, arka planda izleti oynatmaya devam eder.
Yerel
Hesap
@@ -279,8 +291,8 @@
Lisans
Dil
Etiketler
- Oynatma hızı
- Kalite
+ Oynatma hızı (%1$s)
+ Kalite (%1$s)
Hesap
Yeniler
@@ -315,13 +327,39 @@
Sunucu URL\'si
Etiket
Yardım & Geri Bildirim
- Oturumu kapat
+ Oturumu Kapat
Geçerli URL gerekli
Sunucu etiketi gerekli
Oturum Açma Başarısız!
- Oturum Açma Başarılı
+ Oturum açıldı
Arama geçmişini kalıcı olarak silmek istiyor musunuz\?
Arama Geçmişini Temizle
Uygulama arayüzü için dil seçin. Değişikliklerin etkili olması için uygulamayı yeniden başlatın.
Uygulama Dili
+ Görünüm
+ Hakkında
+ Video Oynatma
+ Video Listesi
+ SettingsActivity2
+ Hesap
+ Sunucu Ara
+ Bu sunucuyu adres defterinden kaldırmak istediğinizden emin misiniz\?
+ Sunucuyu Kaldır
+ Bengalce (Bangladeş)
+ Arka plana giderken oynatılan bir videonun nasıl yanıt vereceği
+ Android Ayarlarında bu uygulama için resim içinde resim izni devre dışı
+ Android sürümü kayan videoyu desteklemiyor
+ Kayan pencerede video oynatmaya devam et
+ Arka planda oynatma yapılandırması
+ Tüm oynatmaları durdur
+ Arka planda ses akışı olarak devam et
+ Ahlaksız Örnek
+ Video: %s, Yerel Video: %s
+ Otomatik
+ Oluşturma Zamanı
+ Merhaba boş parça
+ Belirteç yenilendi
+ Belirteç yenilenemedi
+ Ağ erişim hatası, lütfen bağlantınızı gözden geçirin
+ Listeyi filtrele
\ No newline at end of file
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
new file mode 100644
index 0000000..8fcc9d4
--- /dev/null
+++ b/app/src/main/res/values-uk/strings.xml
@@ -0,0 +1,357 @@
+
+
+ Зовнішній вигляд
+ Має обліковий запис
+ Помилка доступу до мережі, перевірте з’єднання
+ Увійдіть, щоб користуватися цією службою
+ Не вдалося оцінити
+
+\nЗагальна публічна ліцензія GNU Affero v3.0
+\n
+\nДозволи цієї найсильнішої ліцензії на копілефт обумовлені наданням повного джерельного коду ліцензованих творів та модифікацій, які включають більші твори з використанням ліцензованої роботи, за тією самою ліцензією. Повідомлення про авторські права та ліцензії повинні зберігатися. Учасники надають явне надання патентних прав. Коли модифікована версія використовується для надання послуги через мережу, повинен бути доступний повний джерельний код модифікованої версії.
+ Огляд
+ Автоматизовано
+ Відео: %s, Локальні відео: %s
+ Екземпляр NSFW
+ Відтворення відео
+ Список відео
+ SettingsActivity2
+ Пошук сервера
+ Дійсно бажаєте видалити цей сервер з адресної книги\?
+ URL-адреса сервера
+ Мітка
+ Довідка та відгуки
+ Потрібна дійсна URL-адреса
+ Потрібна мітка сервера
+ Серверні книги порожні
+ Помилка входу!
+ Ви ввійшли
+ Привіт, порожній фрагменте
+ Вибрати сервер
+ Дата збірки
+ Не вдалося оновити токен
+ Токен оновлено
+ Не вдалося завантажити відео без дозволу на запис
+ Список фільтрів
+ URL-адреса сервера PeerTube
+ Виберіть сервер з переліку внизу або введіть його безпосередньо.
+ Сервер встановлено на: %s
+ Поведінка відтворюваного відео після переходу в фоновий режим
+ Дозвіл на зображення в зображенні вимкнено для цього застосунку в Налаштуваннях Android
+ Версія Android не підтримує плаваюче відео
+ Налаштування відтворення у тлі
+ Продовжити відтворення відео у плаваючому вікні
+ Зупинити все відтворення
+ Продовжити фоновим аудіопотоком
+ Виберіть мову інтерфейсу застосунку. Перезапустіть застосунок, щоб зміни набули чинності.
+ Мова застосунку
+ Зупиняти відтворення в тлі натисканням кнопки назад під час відтворення відео.
+ Зупиняти кнопкою назад
+ Якщо ввімкнено, продовжує відтворювати відео у фоновому режимі.
+ Відтворення в тлі
+ Сервер PeerTube
+ Виберіть мову відео, замість перегляду всіх відео всіма мовами.
+ Фільтр мов
+ Показувати вміст NSFW
+ Вміст NSFW
+ Версія
+ Ліцензія
+ Відтворення відео через торрент-потік. Для цього потрібні дозволи на зберігання. (Альфа, не стабільне!)
+ Про
+ Вилучити сервер
+ 1.25x
+ 0.75x
+ Адресна книга
+ Поточний сервер
+ Додати
+ Пароль
+ Ім’я користувача
+ Шукати
+ Вийти
+ Щось пішло не так, спробуйте пізніше!
+ Приєднання:
+ Опис:
+ Підписники:
+ Обліковий запис:
+ Про
+ Канали
+ Відео
+ Якість (%1$s)
+ Швидкість відтворення (%1$s)
+ Мітки
+ Мова
+ Ліцензія
+ Категорія
+ Приватність
+ Завантажити
+ Поділитися
+ Список блокування
+ Звіт
+ Ні
+ Так
+ Реєстрацію дозволено: %s
+ Вибрати сервер
+ 2x
+ 1,5x
+ Звичайна
+ 0.5x
+ Сіро-блакитний
+ Сірий
+ Коричневий
+ Темно-помаранчевий
+ Помаранчевий
+ Бурштиновий
+ Жовтий
+ Лаймовий
+ Світло-зелений
+ Зелений
+ Синьо-зелений
+ Бірюзовий
+ Блакитний
+ Синій
+ Індиго
+ Насичений пурпуровий
+ Бузковий
+ Рожевий
+ Червоний
+ зулуська
+ чуанг
+ йоруба
+ ідиш
+ коса
+ волоф
+ західно-фризька
+ валлійська
+ валлонська
+ в\'єтнамська
+ венда
+ узбецька
+ урду
+ українська
+ уйгурська
+ тві
+ туркменська
+ турецька
+ тсвана
+ тсонга
+ тонга (Острови Тонга)
+ тигринья
+ тибетська
+ тайська
+ телугу
+ татарська
+ тамільська
+ таджицька
+ таїтянська
+ тагальська
+ Шведська мова жестів
+ шведська
+ сваті
+ суахілі (макромова)
+ сунданська
+ іспанська
+ південне сото
+ південна ндебеле
+ Південноафриканська мова жестів
+ сомалійська
+ словенська
+ словацька
+ сингальська
+ синдхі
+ носу
+ шона
+ сербсько-хорватська
+ сербська
+ шотландська гельська
+ Саудівська Аравія Мова жестів
+ сардинська
+ санґо
+ самоанська
+ Російська мова жестів
+ російська
+ рунді
+ ретороманська
+ румунська
+ кечуа
+ пушту
+ португальська
+ польська
+ перська
+ панджабі
+ Пакистанська мова жестів
+ осетинська
+ оромо
+ орія (макромови)
+ оджибвемовінська
+ окситанська
+ ньянджа
+ норвезька (нюношк)
+ норвезька (букмол)
+ норвезька
+ північносаамська
+ північна ндебеле
+ непальська (макромова)
+ ндонга
+ навахо
+ науру
+ монгольська
+ грецька сучасна (1453-)
+ маршальська
+ маратхі
+ маорійська
+ менська
+ мальтійська
+ малаялам
+ малайська (макромова)
+ малагасійська
+ македонська
+ люксембурзька
+ луба-катанґа
+ ложбан
+ литовська
+ лінґала
+ лімбурзька
+ латиська
+ лаоська
+ курдська
+ кваньяма
+ котава
+ корейська
+ конґо
+ комі
+ клінгонська
+ киргизька
+ руандійська
+ кікую
+ кхмерська
+ казахська
+ кашмірська
+ канурі
+ каннада
+ гренландська
+ яванська
+ Японська мова жестів
+ японська
+ італійська
+ ірландська
+ інуп\'як
+ інуктітут
+ індонезійська
+ ігбо
+ ісландська
+ угорська
+ гірімоту
+ гінді
+ гереро
+ іврит
+ гауса
+ гаїтянська
+ гуджараті
+ ґуарані
+ Німецька мова жестів
+ німецька
+ грузинська
+ гандійська
+ галісійська
+ фула
+ Французька мова жестів
+ французька
+ фінська
+ фіджійська
+ фарерська
+ еве
+ естонська
+ есперанто
+ англійська
+ дзонгкха
+ нідерландська
+ мальдівська
+ Данська мова жестів
+ данська
+ Чеська мова жестів
+ чеська
+ хорватська
+ крі
+ корсиканська
+ корнська
+ чуваська
+ Китайська мова жестів
+ китайська
+ чеченська
+ чаморро
+ каталонська
+ бірманська
+ болгарська
+ Британська мова жестів
+ бретонська
+ Бразильська мова жестів
+ боснійська
+ біслама
+ бенгальська (Бангладеш)
+ бенгальська
+ білоруська
+ баскська
+ башкирська
+ бамбара
+ азербайджанська
+ аймарська
+ аварська
+ асамська
+ вірменська
+ арагонська
+ арабська
+ амхарська
+ Американська мова жестів
+ албанська
+ акан
+ африкаанс
+ афарська
+ абхазька
+ Остаточно видалити історію пошуку\?
+ Очистити історію пошуку
+ Торрент-програвач відео
+ Перезапустіть застосунок, щоб темний режим набув чинності.
+ Тема застосунку
+ Перезапустіть програму, щоб темний режим набув чинності.
+ Темний режим
+ Недійсна URL-адреса.
+ Поділитися
+ Додатково
+ Нічого не знайдено
+ Шукати
+ Шукати на PeerTube
+ UrlVideoPlayActivity
+ Аватар облікового запису
+ Ескіз відео
+ " Перегляди"
+ Підписки
+ Локальне
+ Нещодавнє
+ Популярне
+ Шукати
+ Надайте доступ до контактів для заповнення електронної пошти.
+ Пароль
+ Електронна адреса / ім’я користувача
+ Увійти
+ Це поле обов\'язкове
+ Цей пароль не правильний
+ Цей пароль закороткий
+ Ця адреса електронної пошти недійсна
+ Увійти
+ Обліковий запис
+ Обліковий запис
+ Обліковий запис
+ Обліковий запис
+ Вийти
+ Параметри
+ Сервер
+ Увійти
+ Параметри
+ Вимкнути перевірку SSL сертифіката
+ Ігнорувати незахищені з\'єднання. Використовуйте це лише якщо знаєте сервер до якого підключаєтесь. Перезапустіть застосунок, щоб зміни набули чинності.
+ Так
+ Ні
+ Увага!
+ "Ви збираєтеся вимкнути всі перевірки сертифікації SSL у Thorium. Це може бути дуже небезпечно якщо peertube сервер вами не контролюється, оскільки атака \"людина посередині\" може направити трафік на інший сервер без вашого відома. Зловмисник може записувати паролі та інші особисті дані. "
+ Додатково
+
\ No newline at end of file
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index 91e491e..f1aa71f 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -54,7 +54,7 @@
褐色
灰色
蓝灰色
- 次观看
+ " 次观看"
本地
帐号
按语言过滤
@@ -87,7 +87,7 @@
老挝语
现代希腊语(1453年—)
蒙古语
- 奥里亚语
+ 奥里亚语 (巨集语言)
俄语
僧伽罗字母
西班牙语
@@ -112,8 +112,8 @@
类别
许可
标签
- 播放速度
- 画质
+ 播放速度 (%1$s)
+ 画质 (%1$s)
视频
频道
关于
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 037f1f0..8e00abb 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -279,8 +279,8 @@
授權條款
語言
標籤
- 播放速度
- 畫質
+ 播放速度 (%1$s)
+ 畫質 (%1$s)
影片
頻道
關於
@@ -306,7 +306,7 @@
密碼
使用者名稱
搜尋
- 伺服器 Url
+ 伺服器 URL
標籤
說明與回饋
登出
@@ -314,7 +314,7 @@
伺服器標籤必填
伺服器參考書為空
登入失敗!
- 登入成功
+ 已登入
您好空白片段
您想要永久刪除搜尋歷史紀錄嗎?
清除搜尋歷史
@@ -322,4 +322,29 @@
應用程式語言
當影片播放時按下後退鈕後暫停背景播放。
在後退鈕上暫停
+ 外觀與感覺
+ 關於
+ 影片播放
+ 影片清單
+ SettingsActivity2
+ 帳號
+ 搜尋伺服器
+ 您確定您想要從地址簿中移除此伺服器嗎?
+ 移除伺服器
+ 孟加拉語(孟加拉)
+ 播放影片到背景時如何回應
+ 在 Android 設定中已停用此應用程式的畫中畫權限
+ Android 版本不支援懸浮影片
+ 背景播放設定
+ 繼續以懸浮視窗播放影片
+ 停止所有播放
+ 以背景音訊串流繼續
+ 影片:%s,本地影片:%s
+ NSFW 站臺
+ 建構時間
+ 自動
+ 權杖已重新整理
+ 無法重新整理權杖
+ 網路存取錯誤,請檢查您的網路連線
+ 過濾清單
\ No newline at end of file
diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/constants.xml
similarity index 76%
rename from app/src/main/res/values/array.xml
rename to app/src/main/res/values/constants.xml
index a74e65b..7feb602 100644
--- a/app/src/main/res/values/array.xml
+++ b/app/src/main/res/values/constants.xml
@@ -1,6 +1,69 @@
+ Thorium
+
+
+ pref_language_app
+ pref_theme
+ pref_dark_mode
+
+ pref_show_nsfw
+ pref_language
+
+ pref_back_pause
+ pref_background_behavior
+ pref_torrent_player
+
+ pref_accept_insecure
+
+
+ https://troll.tv
+ AppTheme.BLUE
+
+
+ pref_token_access
+ pref_token_refresh
+ pref_token_expiration
+ pref_token_type
+ pref_auth_username
+ pref_auth_password
+ pref_client_id
+ pref_client_secret
+ pref_api_base
+ pref_quality
+
+
+ backgroundAudio
+ backgroundStop
+ backgroundFloat
+
+
+ 1.0.0-alpha.7
+
+ BACKGROUND_AUDIO
+
+ {faw-play-circle}
+ {faw-cog}
+ {faw-check}
+ {faw-check}
+ {faw-expand}
+ {faw-compress}
+ {faw-ellipsis-v}
+ {faw-thumbs-up}
+ {faw-thumbs-down}
+ {faw-share}
+ {faw-download}
+ {faw-save}
+
+ \@
+ \u0020-\u0020
+
+ VideoPlayActivity
+
+ PeerTube
+
+ PeerTube, a federated (ActivityPub) video streaming platform using P2P (BitTorrent) directly in the web browser with WebTorrent and Angular.
- @string/pref_background_audio
@@ -9,9 +72,9 @@
- - backgroundAudio
- - backgroundStop
- - backgroundFloat
+ - @string/pref_background_audio_key
+ - @string/pref_background_stop_key
+ - @string/pref_background_float_key
@@ -471,11 +534,12 @@
- ru
- sv
- tr
+ - uk
- zh-rCN
- zh-rTW
-
+
- @string/ar
- @string/bn
- @string/bn_rBD
@@ -497,12 +561,13 @@
- @string/ru
- @string/sv
- @string/tr
+ - @string/uk
- @string/zh
- @string/tw
-
+
- Low
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9a70782..d4a765e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,7 +1,5 @@
- Thorium
- VideoPlayActivity
Settings
Sign in
@@ -29,9 +27,7 @@
Account
- \u0020-\u0020
\u0020Views
- \@
Video Thumbnail
Account Avatar
UrlVideoPlayActivity
@@ -40,7 +36,6 @@
No Results
More
Share
- PeerTube
Invalid URL.
Dark Mode
@@ -56,13 +51,11 @@
Show NSFW content
Language filter
Select a video language, instead of showing all videos in all languages.
- https://troll.tv
PeerTube Server
Background Playback
If enabled, continues to play video in background.
Pause on back button
Pause background play when pressing back during video playback.
-
Application Language
Select language for application interface. Restart app for change to take effect.
Continue as a background audio stream
@@ -74,6 +67,8 @@
How a playing video responds when going to background
Clear Search History
Do you want to permanently delete the search history?
+ Ignore insecure connections. Use this only if you know the server you are connecting to. Requires App Restart.
+ Disable SSL Certificate Check
Abkhazian
Afar
@@ -292,18 +287,6 @@
Normal
1.5x
2x
- {faw-play-circle}
- {faw-cog}
- {faw-check}
- {faw-check}
- {faw-expand}
- {faw-compress}
- {faw-ellipsis-v}
- {faw-thumbs-up}
- {faw-thumbs-down}
- {faw-share}
- {faw-download}
- {faw-save}
Select Server
Signup Allowed: %s
Yes
@@ -311,6 +294,7 @@
Server set to: %s
Select a server from the list below or enter it directly.
PeerTube Server URL
+ Filter list
Account
Report
Blacklist
@@ -324,8 +308,8 @@
License
Language
Tags
- Playback speed
- Quality
+ Playback speed (%1$s)
+ Quality (%1$s)
Videos
Channels
About
@@ -334,52 +318,47 @@
Description:
Joined:
Something went wrong, please try later!
+ Network access error, please check your connectivity
Select Server
-
Hello blank fragment
-
- Login Successful
+
+ Logged in
Login Failed!
Server Books is empty
Server label is required
Valid URL is required
- Logout
+ Log Out
Label
- Server Url
+ Server URL
Search
Username
Password
Add
+ Save
Has Login
- none
- like
- dislike
- 1.0.0-alpha.7
Current Server
Address Book
0.75x
1.25x
Remove Server
Are you sure you want to remove this server from the address book?
-
- Select Server
+ Search Server
Account
SettingsActivity2
-
Video List
Video Playback
About
-
-
-
- pref_token_access
- pref_token_refresh
- pref_token_expiration
- pref_token_type
- pref_auth_username
- pref_auth_password
-
-
+ NSFW Instance
+ Videos: %s, Local Videos: %s
+ Automated
+ Build Time
+ Could not refresh token
+ Token refreshed
+ Advanced
+ Warning!
+ No
+ Yes
+ You are about the disable all SSL Certification validation in Thorium. Disabling this can be very dangerous if the peertube server is not under your control, because a man-in-the-middle attack could direct traffic to another server without your knowledge. An attacker could record passwords and other personal data.
\ No newline at end of file
diff --git a/app/src/main/res/xml/pref_general.xml b/app/src/main/res/xml/pref_general.xml
deleted file mode 100644
index 71d4806..0000000
--- a/app/src/main/res/xml/pref_general.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- />
-
-
- />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml
index e60c6cf..96736b3 100644
--- a/app/src/main/res/xml/root_preferences.xml
+++ b/app/src/main/res/xml/root_preferences.xml
@@ -1,82 +1,108 @@
-
+
-
+
+ app:title="@string/pref_language_app"
+ app:iconSpaceReserved="false"/>
+ app:title="@string/pref_title_app_theme"
+ app:iconSpaceReserved="false"/>
+ app:title="@string/pref_title_dark_mode"
+ app:iconSpaceReserved="false"/>
-
+
+ app:title="@string/pref_title_show_nsfw"
+ app:iconSpaceReserved="false"/>
+ app:title="@string/pref_language"
+ app:iconSpaceReserved="false"/>
-
+
+ app:title="@string/pref_title_back_pause"
+ app:iconSpaceReserved="false"/>
+ app:title="@string/pref_background_behavior"
+ app:iconSpaceReserved="false"/>
+ app:title="@string/pref_title_torrent_player"
+ app:iconSpaceReserved="false"/>
-
+
+
+
+
+
+
+
+ app:title="@string/pref_title_version"
+ app:iconSpaceReserved="false"/>
+
+
+ app:title="@string/pref_title_license"
+ app:iconSpaceReserved="false"/>
diff --git a/build.gradle b/build.gradle
index e4e9daa..b4ad13b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,13 +1,16 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
+
+ ext.kotlin_version = '1.4.21'
repositories {
google()
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.0.0'
+ classpath 'com.android.tools.build:gradle:4.1.1'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
diff --git a/ci-scripts/make-github-release.sh b/ci-scripts/make-github-release.sh
new file mode 100755
index 0000000..3fb95a8
--- /dev/null
+++ b/ci-scripts/make-github-release.sh
@@ -0,0 +1,52 @@
+#!/usr/bin/env bash
+
+repo="sschueller/peertube-android"
+username="sschueller"
+
+# set work dir
+cd "$(dirname "${BASH_SOURCE[0]}")/.."
+
+# get release notes
+release_notes=$(cat fastlane/metadata/android/en-US/changelogs/"${VERSION_CODE}".txt)
+
+echo "Commit Tag: ${CI_COMMIT_TAG}"
+
+if [[ "${CI_COMMIT_TAG}" = "" ]] ; then
+ echo "No CI_COMMIT_TAG" >&2; exit 1
+fi
+
+# Check release exists?
+echo "Check release exists..."
+res=$(curl -X GET -s -H "Content-Type:application/json" -H "Authorization: token ${github_token}" https://${username}@api.github.com/repos/${repo}/releases/tags/$CI_COMMIT_TAG)
+
+rel=$(echo "${res}" | jq ".id")
+
+if ! [[ "${rel}" = "null" ]] || [[ "${rel}" = "" ]] ; then
+ echo "Release exists ${CI_COMMIT_TAG}, stopping" >&2; exit 1
+else
+ echo "Release does not exist.";
+fi
+
+# escape release notes
+release_notes=$(echo "${release_notes}" | jq -aRs .)
+postdata="{\"tag_name\":\"${CI_COMMIT_TAG}\",\"target_commitish\":\"master\",\"name\":\"Release ${CI_COMMIT_TAG}\",\"body\":${release_notes},\"draft\":false,\"prerelease\":false}"
+
+# Generate Release
+echo "Generate Release..."
+echo "${postdata}" | jq
+
+res=$(curl -s -X POST -H "Content-Type:application/json" -H "Authorization: token ${github_token}" https://${username}@api.github.com/repos/${repo}/releases -d "${postdata}")
+echo "${res}" | jq
+
+release_id=$(echo "${res}" | jq '.id')
+
+echo "Release ID: ${release_id}"
+
+re='^[0-9]+$'
+if ! [[ ${release_id} =~ ${re} ]] ; then
+ echo "Invalid ID ${release_id}" >&2; exit 1
+fi
+
+echo "Attaching artifact..."
+# Attach artifact
+curl -X POST -H "Authorization: token ${github_token}" -F 'data=@app/build/outputs/apk/release/app-release.apk' https://${username}@uploads.github.com/repos/${repo}/releases/"${release_id}"/assets?name=app-release.apk
diff --git a/ci-scripts/update-changelog.sh b/ci-scripts/update-changelog.sh
new file mode 100644
index 0000000..e558bfb
--- /dev/null
+++ b/ci-scripts/update-changelog.sh
@@ -0,0 +1,11 @@
+#!/usr/bin/env bash
+
+# External environment variables
+VERSION_CODE="$1"
+export VERSION_NAME=${VERSION_CODE:0:1}.${VERSION_CODE:1:1}.${VERSION_CODE:2}
+
+CHANGES=$(cat fastlane/metadata/android/en-US/changelogs/$VERSION_CODE.txt)
+
+DATE=$(date '+%Y-%m-%d')
+NEW="### Version ${VERSION_NAME} Tag: v${VERSION_NAME} (${DATE})\n${CHANGES}\n"
+echo -e "${NEW}\n$(cat CHANGELOG.md)" > CHANGELOG.md
\ No newline at end of file
diff --git a/fastlane/Appfile b/fastlane/Appfile
new file mode 100644
index 0000000..c443b27
--- /dev/null
+++ b/fastlane/Appfile
@@ -0,0 +1,2 @@
+json_key_file("../google_play_api_key.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
+package_name("net.schueller.peertube") # e.g. com.krausefx.app
diff --git a/fastlane/Fastfile b/fastlane/Fastfile
new file mode 100644
index 0000000..92fb865
--- /dev/null
+++ b/fastlane/Fastfile
@@ -0,0 +1,57 @@
+opt_out_usage
+
+# This file contains the fastlane.tools configuration
+# You can find the documentation at https://docs.fastlane.tools
+#
+# For a list of all available actions, check out
+#
+# https://docs.fastlane.tools/actions
+#
+# For a list of all available plugins, check out
+#
+# https://docs.fastlane.tools/plugins/available-plugins
+#
+
+# Uncomment the line if you want fastlane to automatically update itself
+#update_fastlane
+
+default_platform(:android)
+
+platform :android do
+
+ desc "Builds the debug code"
+ lane :buildDebug do
+ gradle(task: "assembleDebug")
+ end
+
+ desc "Builds the release code"
+ lane :buildRelease do
+ gradle(task: "assembleRelease")
+ end
+
+ desc "Runs all the tests"
+ lane :test do
+ gradle(task: "test")
+ end
+
+ desc "Submit a new Internal Build to Play Store"
+ lane :internal do
+ upload_to_play_store(track: 'internal', apk: 'app/build/outputs/apk/release/app-release.apk')
+ end
+
+ desc "Promote Internal to Alpha"
+ lane :promote_internal_to_alpha do
+ upload_to_play_store(track: 'internal', track_promote_to: 'alpha', skip_upload_changelogs: true)
+ end
+
+ desc "Promote Alpha to Beta"
+ lane :promote_alpha_to_beta do
+ upload_to_play_store(track: 'alpha', track_promote_to: 'beta', skip_upload_changelogs: true)
+ end
+
+ desc "Promote Beta to Production"
+ lane :promote_beta_to_production do
+ upload_to_play_store(track: 'beta', track_promote_to: 'production', skip_upload_changelogs: true)
+ end
+
+end
diff --git a/fastlane/metadata/android/ar/full_description.txt b/fastlane/metadata/android/ar/full_description.txt
new file mode 100644
index 0000000..5e68aa3
--- /dev/null
+++ b/fastlane/metadata/android/ar/full_description.txt
@@ -0,0 +1 @@
+Thorium هو عميل PeerTube يمكنه الاتصال بأي خادم peertube يعمل بالإصدار v1.1.0-alpha.2 أو أعلى. PeerTube عبارة عن منصة دفق فيديو (ActivityPub) موحدة باستخدام P2P (BitTorrent) مباشرة في متصفح الويب. لمزيد من المعلومات ، يرجى زيارة https://joinpeertube.org/ لمزيد من المعلومات وقائمة الخوادم. يأتي هذا العميل مُهيئًا مسبقًا بخادم PeerTube واحد يديره منشئ التطبيق - وليس مشروع PeerTube نفسه ، الذي يسرد المزيد على http://instances.joinpeertube.org/ - للسماح لك بتذوق ما يمكن للعميل القيام به. اختر الخادم الخاص بك لضبط تجربتك! الميزات الحالية: - الاتصال بأي خادم PeerTube - فيديو تورنت أو تشغيل مباشر - بحث PeerTube - تنزيل / مشاركة الفيديو - ثيمات / الوضع الداكن - تشغيل الخلفية - تشغيل ملء الشاشة في الوضع الأفقي - سرعة التشغيل - تصفية محتوى NSFW - المصادقة / تسجيل الدخول - إبداء الإعجاب / عدم الإعجاب بالفيديو سآتي قريبا: - تعليق مقاطع الفيديو - تسجيل - صفحة نظرة عامة على المستخدم / القناة - تقرير مقاطع الفيديو الأذونات: - الوصول إلى التخزين ، مطلوب لتنزيل التورنت أو تنزيل الفيديو. مُرخصة بموجب رخصة جنو أفيرو العمومية v3.0 أذونات أقوى ترخيص حقوق متروكة مشروطة بإتاحة كود مصدر كامل للأعمال المرخصة والتعديلات ، والتي تشمل الأعمال الأكبر باستخدام عمل مرخص ، بموجب نفس الترخيص. يجب الحفاظ على إشعارات حقوق النشر والترخيص. يقدم المساهمون منحًا صريحًا لحقوق براءات الاختراع. عند استخدام نسخة معدلة لتقديم خدمة عبر شبكة ، يجب توفير كود المصدر الكامل للنسخة المعدلة. كود المصدر على: https://github.com/sschueller/peertube-android/
diff --git a/fastlane/metadata/android/ar/short_description.txt b/fastlane/metadata/android/ar/short_description.txt
new file mode 100644
index 0000000..2ecef04
--- /dev/null
+++ b/fastlane/metadata/android/ar/short_description.txt
@@ -0,0 +1 @@
+Thorium هو مشغل PeerTube غير رسمي
diff --git a/fastlane/metadata/android/ar/title.txt b/fastlane/metadata/android/ar/title.txt
new file mode 100644
index 0000000..e901099
--- /dev/null
+++ b/fastlane/metadata/android/ar/title.txt
@@ -0,0 +1 @@
+الثوريوم عميل غير رسمي لشركة P
diff --git a/fastlane/metadata/android/ar/video.txt b/fastlane/metadata/android/ar/video.txt
new file mode 100644
index 0000000..5824a09
--- /dev/null
+++ b/fastlane/metadata/android/ar/video.txt
@@ -0,0 +1 @@
+https://www.youtube.com/watch?v=PJIsiuSdpq8
diff --git a/fastlane/metadata/android/bn-BD/changelogs/1047.txt b/fastlane/metadata/android/bn-BD/changelogs/1047.txt
new file mode 100644
index 0000000..fae1658
--- /dev/null
+++ b/fastlane/metadata/android/bn-BD/changelogs/1047.txt
@@ -0,0 +1 @@
+- প্রমাণীকরণ রিফ্রেশ
diff --git a/fastlane/metadata/android/bn-BD/changelogs/1048.txt b/fastlane/metadata/android/bn-BD/changelogs/1048.txt
new file mode 100644
index 0000000..dcb8923
--- /dev/null
+++ b/fastlane/metadata/android/bn-BD/changelogs/1048.txt
@@ -0,0 +1 @@
+- স্বয়ংক্রিয় নিয়োগ ঠিক করতে f-droid রিলিজ
diff --git a/fastlane/metadata/android/bn-BD/changelogs/1049.txt b/fastlane/metadata/android/bn-BD/changelogs/1049.txt
new file mode 100644
index 0000000..81bcaf0
--- /dev/null
+++ b/fastlane/metadata/android/bn-BD/changelogs/1049.txt
@@ -0,0 +1,7 @@
+- বর্ণনায় হাইপারটেক্সট পুনঃনির্দেশনার সমর্থন যোগ করো (@freeboub)
+ - বিভিন্ন ক্র্যাশ ফিক্স (@freeboub)
+ - শেয়ার বাটনের কারণে অ্যাপ ছাড়ার সময় পিপ-এ যাওয়া এড়িয়ে চলো (@freeboub)
+ - সার্ভার তালিকা ফিল্টার করার ক্ষমতা যোগ করো (@freeboub)
+ - নেটওয়ার্ক ত্রুটি বিভক্ত করতে টোস্ট ত্রুটি ব্যবস্থাপনা রিফ্যাক্টর করো (@freeboub)
+ - পিপের জন্য ভিডিও অ্যাসপেক্ট রেশিও ঠিক রাখো (@freeboub)
+ - ল্যান্ডস্কেপ মোড (@freeboub) ছাড়ার সময় নেভিগেশন বার পুনর্বহাল করা হয়নি
diff --git a/fastlane/metadata/android/bn-BD/full_description.txt b/fastlane/metadata/android/bn-BD/full_description.txt
new file mode 100644
index 0000000..d496bcc
--- /dev/null
+++ b/fastlane/metadata/android/bn-BD/full_description.txt
@@ -0,0 +1,33 @@
+থোরিয়াম একটি পিয়ারটিউব ক্লায়েন্ট যা যে কোন পিয়ারটিউব সার্ভারের চলমান সংস্করণ স১.১.০-আলফা.২ বা তার বেশি সংযোগ করতে পারে।
+
+পিয়ারটিউব একটি ফেডারেটেড (অ্যাক্টিভিটিপাব) ভিডিও স্ট্রিমিং প্ল্যাটফর্ম যা সরাসরি ওয়েব ব্রাউজারেপ পিটুপি(বিটটরেন্ট) ব্যবহার করে। আরও তথ্যের জন্য অনুগ্রহ করে https://joinpeertube.org/ এবং সার্ভারের একটি তালিকা দেখুন।
+
+এই ক্লায়েন্ট অ্যাপ্লিকেশন নির্মাতা দ্বারা পরিচালিত একটি পিয়ারটিউব সার্ভার দ্বারা প্রি-কনফিগার করা হয় - পিয়ারটিউব প্রকল্প নিজে নয়, যা http://instances.joinpeertube.org/ আরো তালিকাভুক্ত করে - ক্লায়েন্ট কি করতে সক্ষম তার স্বাদ পেতে তোমাকে অনুমতি দেয়. তোমার অভিজ্ঞতা টিউন করতে তোমার সার্ভার পছন্দ করো!
+
+বর্তমান বৈশিষ্ট্য:
+- যেকোন পিয়ারটিউব সার্ভারে সংযোগ করো
+- টরেন্ট ভিডিও অথবা সরাসরি প্লেব্যাক
+- পিয়ারটিউব অনুসন্ধান করো
+- ডাউনলোড / শেয়ার ভিডিও
+- থিম / ডার্ক মোড
+- ব্যাকগ্রাউন্ড প্লেব্যাক
+- প্রাকৃতিক দৃশ্যে ফুলস্ক্রিন প্লেব্যাক
+- প্লেব্যাক এর গতি
+- অশ্লীল বিষয়বস্তু ফিল্টার করো
+- প্রমাণীকরণ / লগইন
+- লাইক/অপছন্দ ভিডিও
+
+শীঘ্রই যোগাযোগ:
+- মন্তব্য ভিডিও
+- রেজিস্টার করুন
+- ব্যবহারকারী / চ্যানেল ওভারভিউ পৃষ্ঠা
+- ভিডিও রিপোর্ট করুন
+
+অনুমতি:
+- টরেন্ট ডাউনলোড বা ভিডিও ডাউনলোডের জন্য স্টোরেজ অ্যাক্সেস প্রয়োজন।
+
+GNU Affero সাধারণ পাবলিক লাইসেন্স সং৩.০ এর অধীনে লাইসেন্সপ্রাপ্ত
+
+এই শক্তিশালী অনুমতিপত্র বাম লাইসেন্সের অনুমতি লাইসেন্সকৃত কাজ এবং সংশোধনের সম্পূর্ণ সোর্স কোড তৈরি করার শর্ত দেওয়া হয়, যার মধ্যে একই লাইসেন্সের অধীনে একটি লাইসেন্সপ্রাপ্ত কাজ ব্যবহার করে বৃহত্তর কাজ অন্তর্ভুক্ত করা হয়। কপিরাইট এবং লাইসেন্স বিজ্ঞপ্তি অবশ্যই সংরক্ষণ করতে হবে। অবদানকারীরা পেটেন্ট অধিকারের একটি এক্সপ্রেস অনুদান প্রদান করে। যখন একটি নেটওয়ার্কের উপর একটি সেবা প্রদান করতে একটি পরিবর্তিত সংস্করণ ব্যবহার করা হয়, পরিবর্তিত সংস্করণের সম্পূর্ণ উৎস কোড উপলব্ধ করতে হবে।
+
+সোর্স কোড: https://github.com/sschueller/peertube-android/
diff --git a/fastlane/metadata/android/bn-BD/short_description.txt b/fastlane/metadata/android/bn-BD/short_description.txt
new file mode 100644
index 0000000..db22725
--- /dev/null
+++ b/fastlane/metadata/android/bn-BD/short_description.txt
@@ -0,0 +1 @@
+থোরিয়াম একটি অনানুষ্ঠানিক পিয়ারটিউব প্লেয়ার
diff --git a/fastlane/metadata/android/bn-BD/title.txt b/fastlane/metadata/android/bn-BD/title.txt
new file mode 100644
index 0000000..9284517
--- /dev/null
+++ b/fastlane/metadata/android/bn-BD/title.txt
@@ -0,0 +1 @@
+Thorium an unofficial PeerTube client
\ No newline at end of file
diff --git a/fastlane/metadata/android/bn-BD/video.txt b/fastlane/metadata/android/bn-BD/video.txt
new file mode 100644
index 0000000..5824a09
--- /dev/null
+++ b/fastlane/metadata/android/bn-BD/video.txt
@@ -0,0 +1 @@
+https://www.youtube.com/watch?v=PJIsiuSdpq8
diff --git a/fastlane/metadata/android/ca/changelogs/1047.txt b/fastlane/metadata/android/ca/changelogs/1047.txt
new file mode 100644
index 0000000..4e1c207
--- /dev/null
+++ b/fastlane/metadata/android/ca/changelogs/1047.txt
@@ -0,0 +1 @@
+- Renovació de l'autenticació
diff --git a/fastlane/metadata/android/ca/changelogs/1048.txt b/fastlane/metadata/android/ca/changelogs/1048.txt
new file mode 100644
index 0000000..2db2703
--- /dev/null
+++ b/fastlane/metadata/android/ca/changelogs/1048.txt
@@ -0,0 +1 @@
+- fes servir la versió de f-droid per corretgir el desplegament automatic
diff --git a/fastlane/metadata/android/ca/changelogs/1049.txt b/fastlane/metadata/android/ca/changelogs/1049.txt
new file mode 100644
index 0000000..34d40f2
--- /dev/null
+++ b/fastlane/metadata/android/ca/changelogs/1049.txt
@@ -0,0 +1,7 @@
+- Afegir suport de hypertext redirection en la descripció (@freeboub)
+- Correcció de diversos errors fatals (@freeboub)
+- Eludir anar a pip quan surts de l'app pel share button (@freeboub)
+- Afegida la possibilitat de filtrar el llistat de servidors (@freeboub)
+- Refactor Toast error management to split network error (@freeboub)
+- Mantenir la relació d'aspecte per a pip(@freeboub)
+- La barra de navegació no va ser restaurada en sortir del mode horitzontal(@freeboub)
diff --git a/fastlane/metadata/android/ca/full_description.txt b/fastlane/metadata/android/ca/full_description.txt
new file mode 100644
index 0000000..9cca0e7
--- /dev/null
+++ b/fastlane/metadata/android/ca/full_description.txt
@@ -0,0 +1 @@
+Thorium es un reproductor de PeerTube no oficial
diff --git a/fastlane/metadata/android/ca/short_description.txt b/fastlane/metadata/android/ca/short_description.txt
new file mode 100644
index 0000000..9cca0e7
--- /dev/null
+++ b/fastlane/metadata/android/ca/short_description.txt
@@ -0,0 +1 @@
+Thorium es un reproductor de PeerTube no oficial
diff --git a/fastlane/metadata/android/ca/title.txt b/fastlane/metadata/android/ca/title.txt
new file mode 100644
index 0000000..9284517
--- /dev/null
+++ b/fastlane/metadata/android/ca/title.txt
@@ -0,0 +1 @@
+Thorium an unofficial PeerTube client
\ No newline at end of file
diff --git a/fastlane/metadata/android/ca/video.txt b/fastlane/metadata/android/ca/video.txt
new file mode 100644
index 0000000..5824a09
--- /dev/null
+++ b/fastlane/metadata/android/ca/video.txt
@@ -0,0 +1 @@
+https://www.youtube.com/watch?v=PJIsiuSdpq8
diff --git a/fastlane/metadata/android/de-DE/changelogs/1047.txt b/fastlane/metadata/android/de-DE/changelogs/1047.txt
new file mode 100644
index 0000000..9f6c675
--- /dev/null
+++ b/fastlane/metadata/android/de-DE/changelogs/1047.txt
@@ -0,0 +1 @@
+- Authentifizierungsaktualisierung
diff --git a/fastlane/metadata/android/de-DE/full_description.txt b/fastlane/metadata/android/de-DE/full_description.txt
new file mode 100644
index 0000000..e23eb1d
--- /dev/null
+++ b/fastlane/metadata/android/de-DE/full_description.txt
@@ -0,0 +1,33 @@
+Thorium ist ein PeerTube-Client, der eine Verbindung zu jedem PeerTube-Server mit Version v1.1.0-alpha.2 oder höher herstellen kann.
+
+PeerTube ist eine föderierte (ActivityPub) Video-Streaming-Plattform, die P2P (BitTorrent) direkt im Webbrowser verwendet. Weitere Informationen finden Sie unter https://joinpeertube.org/ und eine Liste von Servern.
+
+Dieser Client wird vorkonfiguriert mit einem PeerTube-Server geliefert, der vom Ersteller der Anwendung verwaltet wird – nicht das PeerTube-Projekt selbst, das mehr unter http://instances.joinpeertube.org/ aufgelistet ist –, damit Sie einen Vorgeschmack darauf bekommen, wozu der Client in der Lage ist. Wählen Sie Ihren Server, um Ihre Erfahrung zu optimieren!
+
+Aktuelle Merkmale:
+- Verbindung zu jedem PeerTube-Server
+- Torrent-Video oder direkte Wiedergabe
+- PeerTube durchsuchen
+- Video herunterladen / weitergeben
+- Dunkel-Modus
+- Wiedergabe im Hintergrund
+- Vollbild-Wiedergabe im Querformat
+- Wiedergabegeschwindigkeit
+- NSFW-Inhalt filtern
+- Authentifizierung / Anmeldung
+- Video gefällt mir / gefällt mir nicht
+
+Demnächst:
+- Videos kommentieren
+- Registrieren
+- Benutzer-/Kanal-Übersichtsseite
+- Bericht Videos
+
+Genehmigungen:
+- Speicherzugang, erforderlich für Torrent-Herunterladen oder Video-Herunterladen.
+
+Lizenziert unter der GNU Affero General Public License v3.0
+
+Genehmigungen dieser stärksten Copyleft-Lizenz sind an die Bedingung geknüpft, den vollständigen Quellcode der lizenzierten Werke und Modifikationen, zu denen auch größere Werke gehören, die ein lizenziertes Werk verwenden, unter der gleichen Lizenz zur Verfügung zu stellen. Urheberrechts- und Lizenzhinweise müssen erhalten bleiben. Mitwirkende stellen eine ausdrückliche Gewährung von Patentrechten zur Verfügung. Wenn eine modifizierte Version verwendet wird, um einen Dienst über ein Netzwerk anzubieten, muss der vollständige Quellcode der modifizierten Version zur Verfügung gestellt werden.
+
+Quellcode unter: https://github.com/sschueller/peertube-android/
diff --git a/fastlane/metadata/android/de-DE/short_description.txt b/fastlane/metadata/android/de-DE/short_description.txt
new file mode 100644
index 0000000..ea2c0d2
--- /dev/null
+++ b/fastlane/metadata/android/de-DE/short_description.txt
@@ -0,0 +1 @@
+Thorium ist ein inoffizieller PeerTube-Abspieler
diff --git a/fastlane/metadata/android/de-DE/title.txt b/fastlane/metadata/android/de-DE/title.txt
new file mode 100644
index 0000000..ed7acb6
--- /dev/null
+++ b/fastlane/metadata/android/de-DE/title.txt
@@ -0,0 +1 @@
+Inoffizieller PeerTube-Client
diff --git a/fastlane/metadata/android/de-DE/video.txt b/fastlane/metadata/android/de-DE/video.txt
new file mode 100644
index 0000000..5824a09
--- /dev/null
+++ b/fastlane/metadata/android/de-DE/video.txt
@@ -0,0 +1 @@
+https://www.youtube.com/watch?v=PJIsiuSdpq8
diff --git a/fastlane/metadata/android/en-US/changelogs/1047.txt b/fastlane/metadata/android/en-US/changelogs/1047.txt
new file mode 100644
index 0000000..1269068
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/1047.txt
@@ -0,0 +1 @@
+ - Authentication refresh
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/1048.txt b/fastlane/metadata/android/en-US/changelogs/1048.txt
new file mode 100644
index 0000000..b297db6
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/1048.txt
@@ -0,0 +1 @@
+ - f-droid release to fix auto deployment
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/1049.txt b/fastlane/metadata/android/en-US/changelogs/1049.txt
new file mode 100644
index 0000000..542db4b
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/1049.txt
@@ -0,0 +1,7 @@
+ - add support of hypertext redirection in description (@freeboub)
+ - various crash fixes (@freeboub)
+ - avoid going to pip when leaving the app due to share button (@freeboub)
+ - Add ability to filter server list (@freeboub)
+ - Refactor Toast error management to split network error (@freeboub)
+ - keep video aspect ratio for pip (@freeboub)
+ - navigation bar was not restored when leaving landscape mode (@freeboub)
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/1050.txt b/fastlane/metadata/android/en-US/changelogs/1050.txt
new file mode 100644
index 0000000..fb65b55
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/1050.txt
@@ -0,0 +1,2 @@
+ - add support for disabling SSL
+ - translations
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/changelogs/1051.txt b/fastlane/metadata/android/en-US/changelogs/1051.txt
new file mode 100644
index 0000000..24280a8
--- /dev/null
+++ b/fastlane/metadata/android/en-US/changelogs/1051.txt
@@ -0,0 +1,5 @@
+ - fixed default app language on first start (@kosharskiy)
+ - Settings screen translations uk and ru languages (@kosharskiy)
+ - cleanup app/build.gradle file (@kosharskiy)
+ - fixed video meta data display issue (@kosharskiy)
+ - updated translations
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt
index bf2f133..53bbf08 100644
--- a/fastlane/metadata/android/en-US/full_description.txt
+++ b/fastlane/metadata/android/en-US/full_description.txt
@@ -1,5 +1,33 @@
-PeerTube is a federated video streaming platform that is community-owned and ad-free, with no vendor lock-in. This client allows you to watch and browse videos on a server of your choice in the PeerTube network.
+Thorium is a PeerTube client that can connect to any peertube server running version v1.1.0-alpha.2 or higher.
+
+PeerTube is a federated (ActivityPub) video streaming platform using P2P (BitTorrent) directly in the web browser. For more information, please visit https://joinpeertube.org/ for more information and a list of servers.
This client comes preconfigured with one PeerTube server managed by the application creator - not the PeerTube project itself, which lists more on http://instances.joinpeertube.org/ - to allow you to have a taste of what the client is capable of. Choose your server to tune your experience!
-Please note this is app is in beta and is still missing a lot of features.
+Current Features:
+- Connect to any PeerTube server
+- Torrent video or direct playback
+- Search PeerTube
+- Download / Share video
+- Themes / Dark mode
+- Background playback
+- Fullscreen playback in landscape
+- Playback speed
+- Filter NSFW content
+- Authentication / Login
+- Like/dislike video
+
+Comming Soon:
+- Comment videos
+- Register
+- User / Channel Overview Page
+- Report Videos
+
+Permissions:
+- Storage access, required for torrent download or video download.
+
+Licensed under GNU Affero General Public License v3.0
+
+Permissions 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.
+
+Source Code at: https://github.com/sschueller/peertube-android/
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/images/featureGraphic.png b/fastlane/metadata/android/en-US/images/featureGraphic.png
new file mode 100644
index 0000000..f7cd9db
Binary files /dev/null and b/fastlane/metadata/android/en-US/images/featureGraphic.png differ
diff --git a/fastlane/metadata/android/en-US/images/icon.png b/fastlane/metadata/android/en-US/images/icon.png
new file mode 100644
index 0000000..17b90f6
Binary files /dev/null and b/fastlane/metadata/android/en-US/images/icon.png differ
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/shot_01.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/1_en-US.png
similarity index 100%
rename from fastlane/metadata/android/en-US/images/phoneScreenshots/shot_01.png
rename to fastlane/metadata/android/en-US/images/phoneScreenshots/1_en-US.png
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/2_en-US.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/2_en-US.png
new file mode 100644
index 0000000..be76fd2
Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/2_en-US.png differ
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/shot_02.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/3_en-US.png
similarity index 100%
rename from fastlane/metadata/android/en-US/images/phoneScreenshots/shot_02.png
rename to fastlane/metadata/android/en-US/images/phoneScreenshots/3_en-US.png
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/4_en-US.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/4_en-US.png
new file mode 100644
index 0000000..3d72586
Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/4_en-US.png differ
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/5_en-US.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/5_en-US.png
new file mode 100644
index 0000000..f5e8c59
Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/5_en-US.png differ
diff --git a/fastlane/metadata/android/en-US/short_description.txt b/fastlane/metadata/android/en-US/short_description.txt
index 9faf711..0654514 100644
--- a/fastlane/metadata/android/en-US/short_description.txt
+++ b/fastlane/metadata/android/en-US/short_description.txt
@@ -1 +1 @@
-A PeerTube player
\ No newline at end of file
+Thorium is an unofficial PeerTube Player
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/title.txt b/fastlane/metadata/android/en-US/title.txt
new file mode 100644
index 0000000..9284517
--- /dev/null
+++ b/fastlane/metadata/android/en-US/title.txt
@@ -0,0 +1 @@
+Thorium an unofficial PeerTube client
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/video.txt b/fastlane/metadata/android/en-US/video.txt
new file mode 100644
index 0000000..e85c1c2
--- /dev/null
+++ b/fastlane/metadata/android/en-US/video.txt
@@ -0,0 +1 @@
+https://www.youtube.com/watch?v=PJIsiuSdpq8
\ No newline at end of file
diff --git a/fastlane/metadata/android/fr-FR/changelogs/1047.txt b/fastlane/metadata/android/fr-FR/changelogs/1047.txt
new file mode 100644
index 0000000..6c7752d
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/1047.txt
@@ -0,0 +1 @@
+- Rafraîchissement de l'authentification
diff --git a/fastlane/metadata/android/fr-FR/changelogs/1048.txt b/fastlane/metadata/android/fr-FR/changelogs/1048.txt
new file mode 100644
index 0000000..84f95b9
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/changelogs/1048.txt
@@ -0,0 +1 @@
+- sortie f-droid pour corriger le déploiement automatique
diff --git a/fastlane/metadata/android/fr-FR/full_description.txt b/fastlane/metadata/android/fr-FR/full_description.txt
new file mode 100644
index 0000000..d5116d7
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/full_description.txt
@@ -0,0 +1,33 @@
+Thorium est un client PeerTube qui peut se connecter à n'importe quel serveur Peertube exécutant la version v1.1.0-alpha.2 ou supérieure.
+
+PeerTube est une plateforme de streaming vidéo fédérée (ActivityPub) utilisant P2P (BitTorrent) directement dans le navigateur Web. Pour plus d'informations, veuillez visiter https://joinpeertube.org/ pour plus d'informations et une liste de serveurs.
+
+Ce client est préconfiguré avec un serveur PeerTube géré par le créateur de l'application – pas le projet PeerTube lui-même, qui en répertorie plus sur http://instances.joinpeertube.org/ – pour vous permettre d'avoir un avant-goût de ce dont le client est capable. Choisissez votre serveur pour optimiser votre expérience !
+
+Caractéristiques actuelles :
+- Connectez-vous à n'importe quel serveur PeerTube
+- Vidéo Torrent ou lecture directe
+- Rechercher PeerTube
+- Télécharger / Partager la vidéo
+- Thèmes / Mode sombre
+- Lecture en arrière-plan
+- Lecture plein écran en paysage
+- Vitesse de lecture
+- Filtrer le contenu NSFW
+- Authentification / Connexion
+- J'aime / n'aime pas la vidéo
+
+Prochainement :
+- Commenter des vidéos
+- S'inscrire
+- Page de présentation des utilisateurs / canaux
+- Signaler des vidéos
+
+Autorisations:
+- Accès au stockage, requis pour le téléchargement Torrent ou le téléchargement vidéo.
+
+Sous licence GNU Affero General Public License v3.0
+
+Les autorisations de cette licence copyleft la plus puissante sont conditionnées à la mise à disposition du code source complet des œuvres sous licence et des modifications, qui incluent des œuvres plus volumineuses utilisant une œuvre sous licence, sous la même licence. Les avis de droit d'auteur et de licence doivent être préservés. Les contributeurs accordent expressément les 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 rendu disponible.
+
+Code source sur : https://github.com/sschueller/peertube-android/
diff --git a/fastlane/metadata/android/fr-FR/short_description.txt b/fastlane/metadata/android/fr-FR/short_description.txt
new file mode 100644
index 0000000..860707f
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/short_description.txt
@@ -0,0 +1 @@
+Thorium est un lecteur non officiel de PeerTube
diff --git a/fastlane/metadata/android/fr-FR/title.txt b/fastlane/metadata/android/fr-FR/title.txt
new file mode 100644
index 0000000..b3ff845
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/title.txt
@@ -0,0 +1 @@
+Client PeerTube non officiel
diff --git a/fastlane/metadata/android/fr-FR/video.txt b/fastlane/metadata/android/fr-FR/video.txt
new file mode 100644
index 0000000..5824a09
--- /dev/null
+++ b/fastlane/metadata/android/fr-FR/video.txt
@@ -0,0 +1 @@
+https://www.youtube.com/watch?v=PJIsiuSdpq8
diff --git a/fastlane/metadata/android/id/changelogs/1047.txt b/fastlane/metadata/android/id/changelogs/1047.txt
new file mode 100644
index 0000000..2aec59d
--- /dev/null
+++ b/fastlane/metadata/android/id/changelogs/1047.txt
@@ -0,0 +1 @@
+- Refresh Otentikasi
diff --git a/fastlane/metadata/android/id/full_description.txt b/fastlane/metadata/android/id/full_description.txt
new file mode 100644
index 0000000..228efc8
--- /dev/null
+++ b/fastlane/metadata/android/id/full_description.txt
@@ -0,0 +1 @@
+Thorium adalah unoffical pemutar PeerTube
diff --git a/fastlane/metadata/android/id/short_description.txt b/fastlane/metadata/android/id/short_description.txt
new file mode 100644
index 0000000..228efc8
--- /dev/null
+++ b/fastlane/metadata/android/id/short_description.txt
@@ -0,0 +1 @@
+Thorium adalah unoffical pemutar PeerTube
diff --git a/fastlane/metadata/android/id/title.txt b/fastlane/metadata/android/id/title.txt
new file mode 100644
index 0000000..eae8dda
--- /dev/null
+++ b/fastlane/metadata/android/id/title.txt
@@ -0,0 +1 @@
+Thorium adalah unofficial Klien PeerTube
diff --git a/fastlane/metadata/android/id/video.txt b/fastlane/metadata/android/id/video.txt
new file mode 100644
index 0000000..e85c1c2
--- /dev/null
+++ b/fastlane/metadata/android/id/video.txt
@@ -0,0 +1 @@
+https://www.youtube.com/watch?v=PJIsiuSdpq8
\ No newline at end of file
diff --git a/fastlane/metadata/android/it-IT/changelogs/1047.txt b/fastlane/metadata/android/it-IT/changelogs/1047.txt
new file mode 100644
index 0000000..5d71c6b
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/changelogs/1047.txt
@@ -0,0 +1 @@
+- Aggiornamento dell'autenticazione
diff --git a/fastlane/metadata/android/it-IT/changelogs/1048.txt b/fastlane/metadata/android/it-IT/changelogs/1048.txt
new file mode 100644
index 0000000..e751d75
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/changelogs/1048.txt
@@ -0,0 +1 @@
+- uscita F-Droid per correggere la distribuzione automatica
diff --git a/fastlane/metadata/android/it-IT/changelogs/1049.txt b/fastlane/metadata/android/it-IT/changelogs/1049.txt
new file mode 100644
index 0000000..04efcd7
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/changelogs/1049.txt
@@ -0,0 +1,7 @@
+- Aggiunto il supporto del reindirizzamento ipertestuale nella descrizione (@freeboub)
+- vari crash fix (@freeboub)
+- evitare di andare a pip quando si esce dall'applicazione a causa del pulsante di condivisione (@freeboub)
+- Aggiunto la possibilità di filtrare la lista dei server (@freeboub)
+- Gestione degli errori del rifattore Toast per dividere l'errore di rete (@freeboub)
+- Mantenere il rapporto d'aspetto video per pip (@freeboub)
+- la barra di navigazione non è stata ripristinata
diff --git a/fastlane/metadata/android/it-IT/full_description.txt b/fastlane/metadata/android/it-IT/full_description.txt
new file mode 100644
index 0000000..eeccf69
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/full_description.txt
@@ -0,0 +1,33 @@
+Thorium è un client PeerTube in grado di connettersi a qualsiasi server peertube che esegue la versione v1.1.0-alpha.2 o successiva.
+
+PeerTube è una piattaforma di streaming video federata (ActivityPub) che utilizza P2P (BitTorrent) direttamente nel browser web. Per ulteriori informazioni, visitare https://joinpeertube.org/ per ulteriori informazioni e un elenco dei server.
+
+Questo client viene preconfigurato con un server PeerTube gestito dal creatore dell'applicazione – non il progetto PeerTube stesso, che elenca di più su http://instances.joinpeertube.org/ – per consentire di avere un assaggio di ciò che il client è in grado di. Scegli il tuo server per ottimizzare la tua esperienza!
+
+Caratteristiche attuali:
+- Connettersi a qualsiasi server PeerTube
+- Video Torrent o riproduzione diretta
+- Ricerca PeerTube
+- Scarica / Condividi video
+- Temi / Modalità scuro
+- Riproduzione nello sfondo
+- Riproduzione a schermo intero in orizzontale
+- Velocità di riproduzione
+- Filtrare il contenuto NSFW
+- Autenticazione / accesso
+- Video mi piace /non mi piace
+
+Comming Presto:
+- Commenta i video
+- Registrati
+- Pagina Panoramica utente/canale
+- Segnala video
+
+Autorizzazioni:
+- Accesso di archiviazione, necessario per lo scaricamento Torrent o lo scaricamento video.
+
+Concesso in licenza ai sensi della GNU Affero General Public License v3.0
+
+Le autorizzazioni di questa licenza copyleft più forte sono condizionate a rendere disponibile il codice sorgente completo delle opere e delle modifiche con licenza, che includono opere più grandi utilizzando un lavoro concesso in licenza, sotto la stessa licenza. Le note sul copyright e sulla licenza devono essere conservate. I contributori forniscono una concessione espressa dei diritti di brevetto. Quando una versione modificata viene utilizzata per fornire un servizio in rete, è necessario reso disponibile il codice sorgente completo della versione modificata.
+
+Codice sorgente all'indirizzo: https://github.com/sschueller/peertube-android/
diff --git a/fastlane/metadata/android/it-IT/short_description.txt b/fastlane/metadata/android/it-IT/short_description.txt
new file mode 100644
index 0000000..47680c6
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/short_description.txt
@@ -0,0 +1 @@
+Thorium è un lettore PeerTube non ufficiale
diff --git a/fastlane/metadata/android/it-IT/title.txt b/fastlane/metadata/android/it-IT/title.txt
new file mode 100644
index 0000000..428b773
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/title.txt
@@ -0,0 +1 @@
+Cliente PeerTube non ufficiale
diff --git a/fastlane/metadata/android/it-IT/video.txt b/fastlane/metadata/android/it-IT/video.txt
new file mode 100644
index 0000000..5824a09
--- /dev/null
+++ b/fastlane/metadata/android/it-IT/video.txt
@@ -0,0 +1 @@
+https://www.youtube.com/watch?v=PJIsiuSdpq8
diff --git a/fastlane/metadata/android/no-NO/changelogs/1047.txt b/fastlane/metadata/android/no-NO/changelogs/1047.txt
new file mode 100644
index 0000000..da6d7a2
--- /dev/null
+++ b/fastlane/metadata/android/no-NO/changelogs/1047.txt
@@ -0,0 +1 @@
+- Gjenoppfrisking av identitetsbekreftelse
diff --git a/fastlane/metadata/android/no-NO/full_description.txt b/fastlane/metadata/android/no-NO/full_description.txt
new file mode 100644
index 0000000..fb1d0e5
--- /dev/null
+++ b/fastlane/metadata/android/no-NO/full_description.txt
@@ -0,0 +1 @@
+Uoffisiell PeerTube-klient
diff --git a/fastlane/metadata/android/no-NO/short_description.txt b/fastlane/metadata/android/no-NO/short_description.txt
new file mode 100644
index 0000000..fb1d0e5
--- /dev/null
+++ b/fastlane/metadata/android/no-NO/short_description.txt
@@ -0,0 +1 @@
+Uoffisiell PeerTube-klient
diff --git a/fastlane/metadata/android/no-NO/title.txt b/fastlane/metadata/android/no-NO/title.txt
new file mode 100644
index 0000000..d639724
--- /dev/null
+++ b/fastlane/metadata/android/no-NO/title.txt
@@ -0,0 +1 @@
+Thorium
diff --git a/fastlane/metadata/android/no-NO/video.txt b/fastlane/metadata/android/no-NO/video.txt
new file mode 100644
index 0000000..5824a09
--- /dev/null
+++ b/fastlane/metadata/android/no-NO/video.txt
@@ -0,0 +1 @@
+https://www.youtube.com/watch?v=PJIsiuSdpq8
diff --git a/fastlane/metadata/android/pl-PL/full_description.txt b/fastlane/metadata/android/pl-PL/full_description.txt
new file mode 100644
index 0000000..4ac50d4
--- /dev/null
+++ b/fastlane/metadata/android/pl-PL/full_description.txt
@@ -0,0 +1,36 @@
+Thorium jest platformą PeerTube'a, która może połączyć się z każdym serwerem PeerTube'a działającym na wersji v1.1.0-alpha.2 lub nowszej.
+
+PeerTube jest sfederowaną (ActivityPub) platformą do streamowania wideo, używającą P2P (BitTorrent) bezpośrednio w przeglądarce. Po więcej informacji i listę serwerów odwiedź: https://joinpeertube.org/
+
+Platforma jest z góry wyposażona w jeden serwer PeerTube zarządzany przez twórcę aplikacji, a nie przez ogólny projekt PeerTube. Listę instancji znajdziesz pod: https://instances.joinpeertube.org/instances - by móc zobaczyć do czego zdolna jest platforma. Wybierz dowolny serwer, by dopasować go do oczekiwań!
+
+Obecne Właściwości:
+- Możliwość połączenia z jakimkolwiek serwerem PeerTube
+- Pobierz wideo przez torrent lub odtwarzaj bezpośrednio
+- Przeszukuj PeerTube
+- Pobierz / Udostępnij film
+- Różne skórki, w tym ciemna
+- Odtwarzanie w tle
+- Odtwarzanie pełnoekranowe w trybie krajobrazowym
+- Dostosowywanie prędkości odtwarzania
+- Filtrowanie treści dla dorosłych
+- Logowanie
+- Łapkowanie filmów
+
+Wkrótce:
+- Komentowanie filmów
+- Rejestracja
+- Pogląd Użytkowanika / Kanału
+- Zgłaszanie materiału
+
+Wymagane pozwolenia:
+- Dostęp do przechowywania, potrzebnego do pobierania.
+
+Permissions:
+- Storage access, required for torrent download or video download.
+
+Wydane pod certyfikatem GNU Affero General Public License v3.0
+
+Warunki ww. polityki praw autorskich ustalone są, by udostępniać pełen kod źródłowy certyfikowanych prac i ich modyfikacji zawierających większe prace wydane pod tym samym certyfikatem. Prawa autorskie i certyfikat muszą zostać zachowane. Współautorzy zapewniają wyraźne zrzeczenie się praw patentowych. Gdy zmodyfikowana wersja zostanie użyta do świadczenia usługi przez sieć, pełen kod źródłowy musi zostać udostępniony publicznie.
+
+Link do kodu źródłowego: https://github.com/sschueller/peertube-android/
diff --git a/fastlane/metadata/android/pl-PL/short_description.txt b/fastlane/metadata/android/pl-PL/short_description.txt
new file mode 100644
index 0000000..02462d8
--- /dev/null
+++ b/fastlane/metadata/android/pl-PL/short_description.txt
@@ -0,0 +1 @@
+Thorium jest nieoficjalnym odtwarzaczem PeerTuber Player
diff --git a/fastlane/metadata/android/pl-PL/title.txt b/fastlane/metadata/android/pl-PL/title.txt
new file mode 100644
index 0000000..9284517
--- /dev/null
+++ b/fastlane/metadata/android/pl-PL/title.txt
@@ -0,0 +1 @@
+Thorium an unofficial PeerTube client
\ No newline at end of file
diff --git a/fastlane/metadata/android/pl-PL/video.txt b/fastlane/metadata/android/pl-PL/video.txt
new file mode 100644
index 0000000..5824a09
--- /dev/null
+++ b/fastlane/metadata/android/pl-PL/video.txt
@@ -0,0 +1 @@
+https://www.youtube.com/watch?v=PJIsiuSdpq8
diff --git a/fastlane/metadata/android/ru-RU/changelogs/1047.txt b/fastlane/metadata/android/ru-RU/changelogs/1047.txt
new file mode 100644
index 0000000..850da59
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/changelogs/1047.txt
@@ -0,0 +1 @@
+- Обновление аутентификации
diff --git a/fastlane/metadata/android/ru-RU/changelogs/1048.txt b/fastlane/metadata/android/ru-RU/changelogs/1048.txt
new file mode 100644
index 0000000..ca03994
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/changelogs/1048.txt
@@ -0,0 +1 @@
+- выпуск в f-droid для исправления автоматического развёртывания
diff --git a/fastlane/metadata/android/ru-RU/changelogs/1049.txt b/fastlane/metadata/android/ru-RU/changelogs/1049.txt
new file mode 100644
index 0000000..3493f1a
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/changelogs/1049.txt
@@ -0,0 +1,7 @@
+- Добавлена поддержка перенаправления гипертекста в описании (@freeboub)
+ - Различные исправления сбоев (@freeboub)
+ - Избежание появления pip при выходе из приложения из-за кнопки "Поделиться" (@freeboub)
+ - Добавлена возможность фильтрации списка серверов (@freeboub)
+ - Реорганизовано управление ошибками Toast для сетевой ошибки (@freeboub)
+ - Сохранение соотношения сторон видео для pip (@freeboub)
+ - Панель навигации не восстанавливалась при выходе из ландшафтного режима (@freeboub)
diff --git a/fastlane/metadata/android/ru-RU/full_description.txt b/fastlane/metadata/android/ru-RU/full_description.txt
new file mode 100644
index 0000000..440bf70
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/full_description.txt
@@ -0,0 +1,33 @@
+Thorium - это клиент PeerTube, который может подключаться к любому серверу Peertube с версией v1.1.0-alpha.2 или выше.
+
+PeerTube - это федеративная (ActivityPub) платформа потокового видео, использующая P2P (BitTorrent) непосредственно в веб-браузере. Для получения дополнительной информации посетите https://joinpeertube.org/, чтобы получить дополнительную информацию и список серверов.
+
+Этот клиент поставляется с предварительно сконфигурированным одним сервером PeerTube, управляемым создателем приложения, а не самим проектом PeerTube, подробности которого перечислены на http://instances.joinpeertube.org/, чтобы вы могли почувствовать, на что способен клиент. Выберите свой сервер, чтобы настроить свой опыт!
+
+Текущие возможности:
+- Подключиться к любому серверу PeerTube
+- Торрент-видео или прямое воспроизведение
+- Поиск в PeerTube
+- Скачать / поделиться видео
+- Темы / Темный режим
+- Фоновое воспроизведение
+- Полноэкранное воспроизведение в альбомной ориентации
+- Скорость воспроизведения
+- Фильтр содержимого NSFW
+- Аутентификация / Вход
+- Лайк / дизлайк видео
+
+Скоро:
+- Комментировать видео
+- Регистр
+- Страница обзора пользователя / канала
+- Пожаловаться на видео
+
+Разрешения:
+- Доступ к хранилищу, необходимый для скачивания через торрент или видео.
+
+Под лицензией GNU Affero General Public License v3.0
+
+Разрешения этой сильнейшей лицензии с авторским левом обусловлены предоставлением полного исходного кода лицензионных произведений и модификаций, которые включают более крупные произведения с использованием лицензионных произведений, по той же лицензии. Уведомления об авторских правах и лицензии должны быть сохранены. Соавторы предоставляют явное предоставление патентных прав. Когда измененная версия используется для предоставления услуги по сети, полный исходный код измененной версии должен быть доступен.
+
+Исходный код: https://github.com/sschueller/peertube-android/
diff --git a/fastlane/metadata/android/ru-RU/short_description.txt b/fastlane/metadata/android/ru-RU/short_description.txt
new file mode 100644
index 0000000..246a544
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/short_description.txt
@@ -0,0 +1 @@
+Thorium - неофициальный плеер PeerTube
diff --git a/fastlane/metadata/android/ru-RU/title.txt b/fastlane/metadata/android/ru-RU/title.txt
new file mode 100644
index 0000000..cdb92da
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/title.txt
@@ -0,0 +1 @@
+Thorium-неоф. клиент PeerTube
diff --git a/fastlane/metadata/android/ru-RU/video.txt b/fastlane/metadata/android/ru-RU/video.txt
new file mode 100644
index 0000000..5824a09
--- /dev/null
+++ b/fastlane/metadata/android/ru-RU/video.txt
@@ -0,0 +1 @@
+https://www.youtube.com/watch?v=PJIsiuSdpq8
diff --git a/fastlane/metadata/android/tr-TR/changelogs/1047.txt b/fastlane/metadata/android/tr-TR/changelogs/1047.txt
new file mode 100644
index 0000000..a3413f0
--- /dev/null
+++ b/fastlane/metadata/android/tr-TR/changelogs/1047.txt
@@ -0,0 +1 @@
+- Kimlik doğrulaması yenileme
diff --git a/fastlane/metadata/android/tr-TR/changelogs/1048.txt b/fastlane/metadata/android/tr-TR/changelogs/1048.txt
new file mode 100644
index 0000000..79841fd
--- /dev/null
+++ b/fastlane/metadata/android/tr-TR/changelogs/1048.txt
@@ -0,0 +1 @@
+- otomatik dağıtımı düzeltmek için f-droid sürümü
diff --git a/fastlane/metadata/android/tr-TR/changelogs/1049.txt b/fastlane/metadata/android/tr-TR/changelogs/1049.txt
new file mode 100644
index 0000000..e5bc7ae
--- /dev/null
+++ b/fastlane/metadata/android/tr-TR/changelogs/1049.txt
@@ -0,0 +1,7 @@
+- açıklamada hipermetin yeniden yönlendirme desteği ekle (@freeboub)
+ - çeşitli çökme düzeltmeleri (@freeboub)
+ - paylaş düğmesi ile uygulamadan ayrılırken pip'e gitmekten kaçın (@freeboub)
+ - sunucu listesini filtreleme yeteneği ekle (@freeboub)
+ - ağ hatalarını ayırmak için Toast hata yönetimini yeniden düzenle (@freeboub)
+ - pip için video en/boy oranını koru (@freeboub)
+ - yatay moddan çıkarken gezinme çubuğu geri yüklenmiyordu (@freeboub)
diff --git a/fastlane/metadata/android/tr-TR/full_description.txt b/fastlane/metadata/android/tr-TR/full_description.txt
new file mode 100644
index 0000000..c1d19d0
--- /dev/null
+++ b/fastlane/metadata/android/tr-TR/full_description.txt
@@ -0,0 +1,33 @@
+Thorium, sürüm v1.1.0-alpha.2 veya daha üstünü çalıştıran herhangi bir PeerTube sunucusuna bağlanabilen bir PeerTube istemcisidir.
+
+PeerTube, doğrudan web tarayıcısında P2P (BitTorrent) kullanan bir federe (ActivityPub) video yayınlama platformudur. Daha fazla bilgi ve sunucu listesi için lütfen https://joinpeertube.org/ adresini ziyaret edin.
+
+Bu istemci, uygulamanın yaratıcısı tarafından - PeerTube projesinin kendisi değil, http://instances.joinpeertube.org/ adresinde daha fazlasını listelemektedir - yönetilen bir PeerTube sunucusuyla önceden yapılandırılmış olarak gelir, böylece istemcinin neler yapabileceğini görebilirsiniz. Deneyiminizi kendinize göre ayarlamak için sunucunuzu seçin!
+
+Mevcut Özellikler:
+- Herhangi bir PeerTube sunucusuna bağlanın
+- Videoyu torrent ile paylaşma veya doğrudan oynatma
+- PeerTube'de arayın
+- Video indirin / paylaşın
+- Temalar / Karanlık mod
+- Arka planda oynatma
+- Yatay modda tam ekran oynatma
+- Oynatma hızı
+- Uygunsuz (NSFW) içeriği filtreleyin
+- Kimlik doğrulama / Oturum açma
+- Video beğenin / beğenmeyin
+
+Yakında Gelecekler:
+- Videolara yorum yapma
+- Kaydolma
+- Kullanıcı / Kanal genel görünüm sayfası
+- Videoları şikayet etme
+
+İzinler:
+- Depolama erişimi, torrent veya video indirme için gerekli.
+
+GNU Affero Genel Kamu Lisansı v3.0 altında lisanslanmıştır.
+
+Bu en güçlü copyleft lisansının izinleri, lisanslı bir çalışmayı içeren daha büyük çalışmalar dahil, lisanslı çalışmanın ve değişikliklerinin tüm kaynak kodlarının aynı lisans altında açık olarak sunulmasını gerektirmektedir. Telif hakkı ve lisans uyarıları korunmalıdır. Katkıda bulunanlar, açık bir patent hakları verirler. Değiştirilmiş bir sürüm ağ üzerinden bir hizmet sağlamak için kullanıldığında, değiştirilmiş sürümün tam kaynak kodu açık olarak sunulmalıdır.
+
+Kaynak kodları: https://github.com/sschueller/peertube-android/
diff --git a/fastlane/metadata/android/tr-TR/short_description.txt b/fastlane/metadata/android/tr-TR/short_description.txt
new file mode 100644
index 0000000..d90c153
--- /dev/null
+++ b/fastlane/metadata/android/tr-TR/short_description.txt
@@ -0,0 +1 @@
+Thorium resmi olmayan bir PeerTube oynatıcısıdır
diff --git a/fastlane/metadata/android/tr-TR/title.txt b/fastlane/metadata/android/tr-TR/title.txt
new file mode 100644
index 0000000..d91340b
--- /dev/null
+++ b/fastlane/metadata/android/tr-TR/title.txt
@@ -0,0 +1 @@
+Thorium: PeerTube istemcisi
diff --git a/fastlane/metadata/android/tr-TR/video.txt b/fastlane/metadata/android/tr-TR/video.txt
new file mode 100644
index 0000000..5824a09
--- /dev/null
+++ b/fastlane/metadata/android/tr-TR/video.txt
@@ -0,0 +1 @@
+https://www.youtube.com/watch?v=PJIsiuSdpq8
diff --git a/fastlane/metadata/android/uk/changelogs/1047.txt b/fastlane/metadata/android/uk/changelogs/1047.txt
new file mode 100644
index 0000000..077cbe0
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/1047.txt
@@ -0,0 +1 @@
+- Оновлення автентифікації
diff --git a/fastlane/metadata/android/uk/changelogs/1048.txt b/fastlane/metadata/android/uk/changelogs/1048.txt
new file mode 100644
index 0000000..042cf14
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/1048.txt
@@ -0,0 +1 @@
+- випуск f-droid для виправлення автоматичного розгортання
diff --git a/fastlane/metadata/android/uk/changelogs/1049.txt b/fastlane/metadata/android/uk/changelogs/1049.txt
new file mode 100644
index 0000000..43cda85
--- /dev/null
+++ b/fastlane/metadata/android/uk/changelogs/1049.txt
@@ -0,0 +1,7 @@
+- додано підтримку перенаправлення гіпертексту в опис (@freeboub)
+ - різні виправлення збоїв (@freeboub)
+ - уникайте звз під час виходу з програми через кнопку спільного доступу (@freeboub)
+ - Додайно можливість фільтрувати список серверів (@freeboub)
+ - Управління помилками Refactor Toast для розділення помилки мережі (@freeboub)
+ - збереження співвідношення сторін відео для зображення в зображенні (@freeboub)
+ - панель навігації не відновлювалась після виходу з альбомного режиму (@freeboub)
diff --git a/fastlane/metadata/android/uk/full_description.txt b/fastlane/metadata/android/uk/full_description.txt
new file mode 100644
index 0000000..3110c73
--- /dev/null
+++ b/fastlane/metadata/android/uk/full_description.txt
@@ -0,0 +1,33 @@
+Thorium - це клієнт PeerTube, який може під'єднуватися до будь-якого сервера peertube, що працює версії v1.1.0-alpha.2 або новіших.
+
+PeerTube - це об'єднана (ActivityPub) платформа для потокового відео, що використовує P2P (BitTorrent) безпосередньо у браузері. Додаткові відомості та перелік серверів ви знайдете за адресою https://joinpeertube.org/ .
+
+Цей клієнт постачається з попередньо налаштованим сервером PeerTube, керованим творцем програми, а не самим проєктом PeerTube, який містить докладніші відомості на сайті http://instance.joinpeertube.org/, щоб дозволити вам відчути, на що здатний клієнт. Виберіть свій сервер, щоб налаштувати все що потрібно!
+
+Поточні функції:
+- Під'єднання до будь-якого сервера PeerTube
+- Торрент-відео або пряме відтворення
+- Пошук у PeerTube
+- Завантажити / Поділитися відео
+- Теми / Темний режим
+- Відтворення у тлі
+- Повноекранне відтворення в альбомному режимі
+- Швидкість відтворення
+- Фільтрувати вміст NSFW
+- Аутентифікація / Вхід
+- Вподобати / не подобається відео
+
+Скоро буде:
+- Коментувати відео
+- Реєстрація
+- Сторінка огляду користувача / каналу
+- Звіт про відео
+
+Дозволи:
+- Доступ до сховища, необхідний для завантаження торрента або завантаження відео.
+
+Ліцензовано під загальною публічною ліцензією GNU Affero v3.0
+
+Дозволи цієї найсильнішої ліцензії на копілефт обумовлені наданням повного джерельного коду ліцензованих творів та модифікацій, які включають більші твори з використанням ліцензованої роботи, за тією самою ліцензією. Повідомлення про авторські права та ліцензії повинні зберігатися. Учасники надають явне надання патентних прав. Коли модифікована версія використовується для надання послуги через мережу, джерельний код модифікованої версії повинен бути доступний.
+
+Джерельний код за адресою: https://github.com/sschueller/peertube-android/
diff --git a/fastlane/metadata/android/uk/short_description.txt b/fastlane/metadata/android/uk/short_description.txt
new file mode 100644
index 0000000..54abf3f
--- /dev/null
+++ b/fastlane/metadata/android/uk/short_description.txt
@@ -0,0 +1 @@
+Thorium - неофіційний програвач PeerTube
diff --git a/fastlane/metadata/android/uk/title.txt b/fastlane/metadata/android/uk/title.txt
new file mode 100644
index 0000000..991e4f2
--- /dev/null
+++ b/fastlane/metadata/android/uk/title.txt
@@ -0,0 +1 @@
+Thorium неоф. клієнт PeerTube
diff --git a/fastlane/metadata/android/uk/video.txt b/fastlane/metadata/android/uk/video.txt
new file mode 100644
index 0000000..5824a09
--- /dev/null
+++ b/fastlane/metadata/android/uk/video.txt
@@ -0,0 +1 @@
+https://www.youtube.com/watch?v=PJIsiuSdpq8
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index e023b24..cba2f4b 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Fri Jun 12 19:07:10 CEST 2020
+#Wed Jan 13 22:22:53 EET 2021
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-all.zip
diff --git a/gradlew b/gradlew
old mode 100644
new mode 100755