diff --git a/CHANGELOG.md b/CHANGELOG.md
index f6e2563..d2fe13a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+### 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
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..04ef9f4
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,19 @@
+FROM gradle:5.6.4-jdk8
+
+ENV ANDROID_SDK_URL https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip
+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 && \
+ 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"
\ No newline at end of file
diff --git a/REPRODUCIBLE_BUILDS.md b/REPRODUCIBLE_BUILDS.md
new file mode 100644
index 0000000..00bf5ef
--- /dev/null
+++ b/REPRODUCIBLE_BUILDS.md
@@ -0,0 +1,61 @@
+# Reproducible Builds
+
+Note: reproducible builds work starting version 1.0.44
+
+## 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 ~/peertube-android:/home/peertube-android -w /home/peertube-android thorium-builder gradle assembleProdRelease -PkeystorePassword=securePassword -PkeyAliasPassword=securePassword -PkeystoreFile=build.keystore -PbuildTimestamp=1593942384524
+cp app/build/outputs/apk/prod/release/app-prod-release.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 pull `adb shell pm path net.schueller.peertube | cut -d':' -f2` 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
+python apkdiff.py thorium-built.apk thorium-store.apk
+```
+
diff --git a/app/build.gradle b/app/build.gradle
index 0751f3e..4f789c7 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,13 +1,33 @@
apply plugin: 'com.android.application'
+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
+ }
+ }
+}
+
android {
compileSdkVersion 29
defaultConfig {
applicationId "net.schueller.peertube"
minSdkVersion 21
targetSdkVersion 29
- versionCode 1043
- versionName "1.0.43"
+ versionCode 1044
+ versionName "1.0.44"
+ //buildTime readPropertyWithDefault('buildTimestamp', System.currentTimeMillis()) + 'L'
+ //buildConfigField "long", "BUILD_TIME", readPropertyWithDefault('buildTimestamp', System.currentTimeMillis()) + 'L'
+ //resValue "string", "BUILD_TIME", readPropertyWithDefault('buildTimestamp', System.currentTimeMillis()) + 'L'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ext {
libVersions = [
@@ -87,6 +107,7 @@ android {
applicationVariants.all { variant ->
variant.resValue "string", "versionName", variant.versionName
+ variant.resValue "string", "buildTime", readPropertyWithDefault('buildTimestamp', System.currentTimeMillis()) + ''
}
}
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" />
- *
- * 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..c0fdaff 100644
--- a/app/src/main/java/net/schueller/peertube/activity/CommonActivity.java
+++ b/app/src/main/java/net/schueller/peertube/activity/CommonActivity.java
@@ -26,10 +26,9 @@ import android.preference.PreferenceManager;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
-import java.util.Locale;
+import net.schueller.peertube.R;
-import static net.schueller.peertube.helper.Constants.DEFAULT_THEME;
-import static net.schueller.peertube.helper.Constants.THEME_PREF_KEY;
+import java.util.Locale;
public class CommonActivity extends AppCompatActivity {
@@ -39,23 +38,28 @@ 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), "en");
+ assert countryCode != null;
+ Locale locale = new Locale(countryCode);
+
//Neither Chinese language choice was working, found this fix on stack overflow
- if(countryCode.equals("zh-rCN"))
+ if (countryCode.equals("zh-rCN"))
locale = Locale.SIMPLIFIED_CHINESE;
- if(countryCode.equals("zh-rTW"))
+ if (countryCode.equals("zh-rTW"))
locale = Locale.TRADITIONAL_CHINESE;
Locale.setDefault(locale);
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 85%
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..6c57cf7 100644
--- a/app/src/main/java/net/schueller/peertube/activity/SelectServerActivity.java
+++ b/app/src/main/java/net/schueller/peertube/activity/SearchServerActivity.java
@@ -18,7 +18,6 @@
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,36 +26,25 @@ 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.View;
-import android.widget.Button;
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.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 int currentStart = 0;
@@ -76,7 +64,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);
@@ -97,10 +85,10 @@ public class SelectServerActivity extends CommonActivity {
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);
@@ -144,7 +132,7 @@ public class SelectServerActivity extends CommonActivity {
isLoading = true;
GetServerListDataService service = RetrofitInstance.getRetrofitInstance(
- APIUrlHelper.getServerIndexUrl(SelectServerActivity.this)
+ APIUrlHelper.getServerIndexUrl(SearchServerActivity.this)
).create(GetServerListDataService.class);
@@ -183,7 +171,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();
+ Toast.makeText(SearchServerActivity.this, getString(R.string.api_error), Toast.LENGTH_SHORT).show();
isLoading = false;
swipeRefreshLayout.setRefreshing(false);
}
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 38126d2..6f559b2 100644
--- a/app/src/main/java/net/schueller/peertube/activity/SettingsActivity.java
+++ b/app/src/main/java/net/schueller/peertube/activity/SettingsActivity.java
@@ -25,8 +25,6 @@ import androidx.preference.PreferenceFragmentCompat;
import net.schueller.peertube.R;
-import java.util.Objects;
-
public class SettingsActivity extends CommonActivity {
@Override
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..b00bfa5 100644
--- a/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java
+++ b/app/src/main/java/net/schueller/peertube/activity/VideoListActivity.java
@@ -50,7 +50,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;
@@ -320,8 +319,8 @@ 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";
+ Set languages = sharedPref.getStringSet(getString(R.string.pref_video_language_key), null);
String apiBaseURL = APIUrlHelper.getUrlWithVersion(this);
GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class);
@@ -383,7 +382,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 f241d8b..398312f 100644
--- a/app/src/main/java/net/schueller/peertube/activity/VideoPlayActivity.java
+++ b/app/src/main/java/net/schueller/peertube/activity/VideoPlayActivity.java
@@ -36,6 +36,7 @@ import android.os.Bundle;
import android.preference.PreferenceManager;
+import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
@@ -56,26 +57,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 +84,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 +96,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 +119,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 +135,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 +150,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 +163,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 +187,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 +205,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 +233,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 +252,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 +268,44 @@ 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();
}
+ videoPlayerFragment.setIsFullscreen(isLandscape);
+
getWindow().addFlags(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 +326,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,108 +344,115 @@ 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");
- 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 (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();
+
}
- Log.v(TAG, "onUserLeaveHint()...");
+
+
}
- // @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");
+ String backgroundBehavior = sharedPref.getString(getString(R.string.pref_background_behavior_key), getString(R.string.pref_background_stop_key));
+ assert backgroundBehavior != null;
- // Log.v(TAG,"backgroundBehavior: " + backgroundBehavior);
+ 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();
- switch (backgroundBehavior){
- case "backgroundStop":
- Log.v(TAG,"stop the video");
- videoPlayerFragment.pauseVideo();
- stopService(new Intent(this, VideoPlayerService.class));
+ } 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;
- default:
- // Deal with bad entries from older version
- Log.v(TAG,"No setting, fallback");
- 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());
+ Log.v(TAG, rational.toString());
PictureInPictureParams mParams =
new PictureInPictureParams.Builder()
.setAspectRatio(rational)
@@ -472,19 +461,26 @@ public class VideoPlayActivity extends AppCompatActivity {
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/ServerListAdapter.java b/app/src/main/java/net/schueller/peertube/adapter/ServerListAdapter.java
index f7225df..1e8ba2f 100644
--- a/app/src/main/java/net/schueller/peertube/adapter/ServerListAdapter.java
+++ b/app/src/main/java/net/schueller/peertube/adapter/ServerListAdapter.java
@@ -18,15 +18,11 @@
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;
@@ -39,12 +35,8 @@ 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;
@@ -65,7 +57,7 @@ public class ServerListAdapter 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 +57,7 @@ public class ServerAdapter extends RecyclerView.Adapter {
- Intent intentServer = new Intent(getActivity(), SelectServerActivity.class);
+ Intent intentServer = new Intent(getActivity(), SearchServerActivity.class);
this.startActivityForResult(intentServer, PICK_SERVER);
});
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..7865f91 100644
--- a/app/src/main/java/net/schueller/peertube/fragment/VideoMenuQualityFragment.java
+++ b/app/src/main/java/net/schueller/peertube/fragment/VideoMenuQualityFragment.java
@@ -17,6 +17,7 @@
*/
package net.schueller.peertube.fragment;
+import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
@@ -44,7 +45,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 +54,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 +75,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 +91,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/VideoMetaDataFragment.java b/app/src/main/java/net/schueller/peertube/fragment/VideoMetaDataFragment.java
index 0785eeb..1d370e0 100644
--- a/app/src/main/java/net/schueller/peertube/fragment/VideoMetaDataFragment.java
+++ b/app/src/main/java/net/schueller/peertube/fragment/VideoMetaDataFragment.java
@@ -65,6 +65,10 @@ 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;
@@ -72,13 +76,11 @@ public class VideoMetaDataFragment extends Fragment {
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) {
-
Context context = getContext();
Activity activity = getActivity();
@@ -91,26 +93,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,20 +117,16 @@ 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();
+ // 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);
@@ -156,7 +151,6 @@ public class VideoMetaDataFragment extends Fragment {
}
});
-
Account account = video.getAccount();
// owner / creator Avatar
@@ -198,7 +192,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 +204,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 +212,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 +251,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,44 +260,46 @@ 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 + "\"}");
@@ -314,23 +307,47 @@ public class VideoMetaDataFragment extends Fragment {
String apiBaseURL = APIUrlHelper.getUrlWithVersion(getContext());
GetVideoDataService videoDataService = RetrofitInstance.getRetrofitInstance(apiBaseURL).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 +358,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..b0fb6d2 100644
--- a/app/src/main/java/net/schueller/peertube/fragment/VideoOptionsFragment.java
+++ b/app/src/main/java/net/schueller/peertube/fragment/VideoOptionsFragment.java
@@ -17,9 +17,9 @@
*/
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 +28,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 +36,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 +64,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 +106,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..3ac32ba 100644
--- a/app/src/main/java/net/schueller/peertube/fragment/VideoPlayerFragment.java
+++ b/app/src/main/java/net/schueller/peertube/fragment/VideoPlayerFragment.java
@@ -18,7 +18,6 @@
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;
@@ -66,15 +65,16 @@ 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;
@@ -134,6 +134,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);
@@ -195,30 +196,31 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
@Override
public void onFailure(@NonNull Call