Merge pull request #209 from sschueller/develop

Release v1.0.44
This commit is contained in:
Stefan Schüller 2020-07-05 20:15:17 +02:00 committed by GitHub
commit cab4220cda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 707 additions and 712 deletions

View File

@ -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) ### Version 1.0.43 Tag: v1.0.43 (2020-07-04)
* Fix back button issue * Fix back button issue

19
Dockerfile Normal file
View File

@ -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"

61
REPRODUCIBLE_BUILDS.md Normal file
View File

@ -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
```

View File

@ -1,13 +1,33 @@
apply plugin: 'com.android.application' 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 { android {
compileSdkVersion 29 compileSdkVersion 29
defaultConfig { defaultConfig {
applicationId "net.schueller.peertube" applicationId "net.schueller.peertube"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 29 targetSdkVersion 29
versionCode 1043 versionCode 1044
versionName "1.0.43" 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" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
ext { ext {
libVersions = [ libVersions = [
@ -87,6 +107,7 @@ android {
applicationVariants.all { variant -> applicationVariants.all { variant ->
variant.resValue "string", "versionName", variant.versionName variant.resValue "string", "versionName", variant.versionName
variant.resValue "string", "buildTime", readPropertyWithDefault('buildTimestamp', System.currentTimeMillis()) + ''
} }
} }

View File

@ -49,7 +49,7 @@
android:label="@string/title_activity_settings" android:label="@string/title_activity_settings"
android:theme="@style/AppTheme.NoActionBar" /> <!-- Server Selection --> android:theme="@style/AppTheme.NoActionBar" /> <!-- Server Selection -->
<activity <activity
android:name=".activity.SelectServerActivity" android:name=".activity.SearchServerActivity"
android:label="@string/title_activity_select_server" android:label="@string/title_activity_select_server"
android:theme="@style/AppTheme.NoActionBar" /> <!-- Me --> android:theme="@style/AppTheme.NoActionBar" /> <!-- Me -->
<activity <activity

View File

@ -1,145 +0,0 @@
/*
* Copyright 2018 Stefan Schüller <sschueller@techdroid.com>
*
* License: GPL-3.0+
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.schueller.peertube.activity;
import android.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;
}
}

View File

@ -26,10 +26,9 @@ import android.preference.PreferenceManager;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate; import androidx.appcompat.app.AppCompatDelegate;
import java.util.Locale; import net.schueller.peertube.R;
import static net.schueller.peertube.helper.Constants.DEFAULT_THEME; import java.util.Locale;
import static net.schueller.peertube.helper.Constants.THEME_PREF_KEY;
public class CommonActivity extends AppCompatActivity { public class CommonActivity extends AppCompatActivity {
@ -39,23 +38,28 @@ public class CommonActivity extends AppCompatActivity {
// Set Night Mode // Set Night Mode
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); 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); AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO);
// Set theme // Set theme
setTheme(getResources().getIdentifier( 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", "style",
getPackageName()) getPackageName())
); );
// Set language // Set language
String countryCode=sharedPref.getString("pref_language_app","en"); String countryCode = sharedPref.getString(getString(R.string.pref_language_app_key), "en");
Locale locale=new Locale(countryCode);; assert countryCode != null;
Locale locale = new Locale(countryCode);
//Neither Chinese language choice was working, found this fix on stack overflow //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; locale = Locale.SIMPLIFIED_CHINESE;
if(countryCode.equals("zh-rTW")) if (countryCode.equals("zh-rTW"))
locale = Locale.TRADITIONAL_CHINESE; locale = Locale.TRADITIONAL_CHINESE;
Locale.setDefault(locale); Locale.setDefault(locale);

View File

@ -18,7 +18,6 @@
package net.schueller.peertube.activity; package net.schueller.peertube.activity;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
@ -27,36 +26,25 @@ import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
import retrofit2.Response; import retrofit2.Response;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.util.Patterns;
import android.view.View; import android.view.View;
import android.widget.Button;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import net.schueller.peertube.R; import net.schueller.peertube.R;
import net.schueller.peertube.adapter.ServerAdapter; import net.schueller.peertube.adapter.ServerSearchAdapter;
import net.schueller.peertube.adapter.VideoAdapter;
import net.schueller.peertube.helper.APIUrlHelper; import net.schueller.peertube.helper.APIUrlHelper;
import net.schueller.peertube.model.ServerList; import net.schueller.peertube.model.ServerList;
import net.schueller.peertube.model.VideoList;
import net.schueller.peertube.network.GetServerListDataService; import net.schueller.peertube.network.GetServerListDataService;
import net.schueller.peertube.network.GetVideoDataService;
import net.schueller.peertube.network.RetrofitInstance; import net.schueller.peertube.network.RetrofitInstance;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Objects; import java.util.Objects;
import static net.schueller.peertube.helper.Constants.DEFAULT_THEME; public class SearchServerActivity extends CommonActivity {
import static net.schueller.peertube.helper.Constants.THEME_PREF_KEY;
public class SelectServerActivity extends CommonActivity { private ServerSearchAdapter serverAdapter;
private ServerAdapter serverAdapter;
private SwipeRefreshLayout swipeRefreshLayout; private SwipeRefreshLayout swipeRefreshLayout;
private int currentStart = 0; private int currentStart = 0;
@ -76,7 +64,7 @@ public class SelectServerActivity extends CommonActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_server_selection); setContentView(R.layout.activity_search_server);
// Attaching the layout to the toolbar object // Attaching the layout to the toolbar object
Toolbar toolbar = findViewById(R.id.tool_bar_server_selection); 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); 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); recyclerView.setLayoutManager(layoutManager);
serverAdapter = new ServerAdapter(new ArrayList<>(), this); serverAdapter = new ServerSearchAdapter(new ArrayList<>(), this);
recyclerView.setAdapter(serverAdapter); recyclerView.setAdapter(serverAdapter);
loadServers(currentStart, count); loadServers(currentStart, count);
@ -144,7 +132,7 @@ public class SelectServerActivity extends CommonActivity {
isLoading = true; isLoading = true;
GetServerListDataService service = RetrofitInstance.getRetrofitInstance( GetServerListDataService service = RetrofitInstance.getRetrofitInstance(
APIUrlHelper.getServerIndexUrl(SelectServerActivity.this) APIUrlHelper.getServerIndexUrl(SearchServerActivity.this)
).create(GetServerListDataService.class); ).create(GetServerListDataService.class);
@ -183,7 +171,7 @@ public class SelectServerActivity extends CommonActivity {
@Override @Override
public void onFailure(@NonNull Call<ServerList> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<ServerList> call, @NonNull Throwable t) {
Log.wtf("err", t.fillInStackTrace()); 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; isLoading = false;
swipeRefreshLayout.setRefreshing(false); swipeRefreshLayout.setRefreshing(false);
} }

View File

@ -25,8 +25,6 @@ import androidx.preference.PreferenceFragmentCompat;
import net.schueller.peertube.R; import net.schueller.peertube.R;
import java.util.Objects;
public class SettingsActivity extends CommonActivity { public class SettingsActivity extends CommonActivity {
@Override @Override

View File

@ -50,7 +50,6 @@ import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@ -320,8 +319,8 @@ public class VideoListActivity extends CommonActivity {
isLoading = true; isLoading = true;
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String nsfw = sharedPref.getBoolean("pref_show_nsfw", false) ? "both" : "false"; String nsfw = sharedPref.getBoolean(getString(R.string.pref_show_nsfw_key), false) ? "both" : "false";
Set<String> languages = sharedPref.getStringSet("pref_language", null); Set<String> languages = sharedPref.getStringSet(getString(R.string.pref_video_language_key), null);
String apiBaseURL = APIUrlHelper.getUrlWithVersion(this); String apiBaseURL = APIUrlHelper.getUrlWithVersion(this);
GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class); 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 // only check when we actually need the permission
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED && 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); ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
} }
} }

View File

@ -36,6 +36,7 @@ import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
@ -56,26 +57,25 @@ import net.schueller.peertube.service.VideoPlayerService;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Objects;
import androidx.fragment.app.FragmentManager; 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_PAUSE;
import static com.google.android.exoplayer2.ui.PlayerNotificationManager.ACTION_PLAY; import static com.google.android.exoplayer2.ui.PlayerNotificationManager.ACTION_PLAY;
import static com.google.android.exoplayer2.ui.PlayerNotificationManager.ACTION_STOP; 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.VideoHelper.canEnterPipMode;
import static net.schueller.peertube.helper.Constants.DEFAULT_THEME;
import static net.schueller.peertube.helper.Constants.THEME_PREF_KEY;
public class VideoPlayActivity extends AppCompatActivity { public class VideoPlayActivity extends AppCompatActivity {
private static final String TAG = "VideoPlayActivity"; private static final String TAG = "VideoPlayActivity";
private static boolean floatMode = false; static boolean floatMode = false;
private static final int REQUEST_CODE = 101; private static final int REQUEST_CODE = 101;
private BroadcastReceiver receiver; 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. //This can only be called when in entering pip mode which can't happen if the device doesn't support pip mode.
@SuppressLint("NewApi") @SuppressLint("NewApi")
public void makePipControls() { public void makePipControls() {
@ -84,7 +84,7 @@ public class VideoPlayActivity extends AppCompatActivity {
ArrayList<RemoteAction> actions = new ArrayList<>(); ArrayList<RemoteAction> 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); 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"}) 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); @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); remoteAction = new RemoteAction(icon, "play", "stop the media", pendingIntent);
actions.add(remoteAction); actions.add(remoteAction);
if (videoPlayerFragment.isPaused()){ assert videoPlayerFragment != null;
Log.e(TAG,"setting actions with play button"); if (videoPlayerFragment.isPaused()) {
Log.e(TAG, "setting actions with play button");
actionIntent = new Intent(ACTION_PLAY); actionIntent = new Intent(ACTION_PLAY);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), REQUEST_CODE, actionIntent, 0); pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), REQUEST_CODE, actionIntent, 0);
icon = Icon.createWithResource(getApplicationContext(), com.google.android.exoplayer2.ui.R.drawable.exo_notification_play); icon = Icon.createWithResource(getApplicationContext(), com.google.android.exoplayer2.ui.R.drawable.exo_notification_play);
remoteAction = new RemoteAction(icon, "play", "play the media", pendingIntent); remoteAction = new RemoteAction(icon, "play", "play the media", pendingIntent);
actions.add(remoteAction);
} else { } else {
Log.e(TAG,"setting actions with pause button"); Log.e(TAG, "setting actions with pause button");
actionIntent = new Intent(ACTION_PAUSE); actionIntent = new Intent(ACTION_PAUSE);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), REQUEST_CODE, actionIntent, 0); pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), REQUEST_CODE, actionIntent, 0);
icon = Icon.createWithResource(getApplicationContext(), com.google.android.exoplayer2.ui.R.drawable.exo_notification_pause); icon = Icon.createWithResource(getApplicationContext(), com.google.android.exoplayer2.ui.R.drawable.exo_notification_pause);
remoteAction = new RemoteAction(icon, "pause", "pause the media", pendingIntent); remoteAction = new RemoteAction(icon, "pause", "pause the media", pendingIntent);
actions.add(remoteAction);
} }
actions.add(remoteAction);
//add custom actions to pip window //add custom actions to pip window
@ -119,12 +119,13 @@ public class VideoPlayActivity extends AppCompatActivity {
.setActions(actions) .setActions(actions)
.build(); .build();
setPictureInPictureParams(params); setPictureInPictureParams(params);
} }
public void changedToPipMode() { public void changedToPipMode() {
FragmentManager fragmentManager = getSupportFragmentManager(); FragmentManager fragmentManager = getSupportFragmentManager();
VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment) fragmentManager.findFragmentById(R.id.video_player_fragment); VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment) fragmentManager.findFragmentById(R.id.video_player_fragment);
assert videoPlayerFragment != null;
videoPlayerFragment.showControls(false); videoPlayerFragment.showControls(false);
//create custom actions //create custom actions
makePipControls(); makePipControls();
@ -134,11 +135,12 @@ public class VideoPlayActivity extends AppCompatActivity {
filter.addAction(ACTION_STOP); filter.addAction(ACTION_STOP);
filter.addAction(ACTION_PAUSE); filter.addAction(ACTION_PAUSE);
filter.addAction(ACTION_PLAY); filter.addAction(ACTION_PLAY);
filter.addAction((BACKGROUND_AUDIO)); filter.addAction((getString(R.string.app_background_audio)));
receiver = new BroadcastReceiver() { receiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
String action = intent.getAction(); String action = intent.getAction();
assert action != null;
if (action.equals(ACTION_PAUSE)) { if (action.equals(ACTION_PAUSE)) {
videoPlayerFragment.pauseVideo(); videoPlayerFragment.pauseVideo();
makePipControls(); makePipControls();
@ -148,7 +150,7 @@ public class VideoPlayActivity extends AppCompatActivity {
makePipControls(); makePipControls();
} }
if (action.equals(BACKGROUND_AUDIO)) { if (action.equals(getString(R.string.app_background_audio))) {
unregisterReceiver(receiver); unregisterReceiver(receiver);
finish(); finish();
} }
@ -161,20 +163,23 @@ public class VideoPlayActivity extends AppCompatActivity {
registerReceiver(receiver, filter); registerReceiver(receiver, filter);
Log.v(TAG, "switched to pip "); Log.v(TAG, "switched to pip ");
floatMode=true; floatMode = true;
videoPlayerFragment.showControls(false); videoPlayerFragment.showControls(false);
} }
public void changedToNormalMode(){
public void changedToNormalMode() {
FragmentManager fragmentManager = getSupportFragmentManager(); FragmentManager fragmentManager = getSupportFragmentManager();
VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment) fragmentManager.findFragmentById(R.id.video_player_fragment); VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment) fragmentManager.findFragmentById(R.id.video_player_fragment);
assert videoPlayerFragment != null;
videoPlayerFragment.showControls(true); videoPlayerFragment.showControls(true);
if (receiver != null) { if (receiver != null) {
unregisterReceiver(receiver); unregisterReceiver(receiver);
} }
Log.v(TAG,"switched to normal"); Log.v(TAG, "switched to normal");
floatMode=false; floatMode = false;
} }
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -182,7 +187,10 @@ public class VideoPlayActivity extends AppCompatActivity {
// Set theme // Set theme
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
setTheme(getResources().getIdentifier( 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", "style",
getPackageName()) getPackageName())
); );
@ -197,17 +205,17 @@ public class VideoPlayActivity extends AppCompatActivity {
assert videoPlayerFragment != null; assert videoPlayerFragment != null;
String playingVideo = videoPlayerFragment.getVideoUuid(); 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)){ if (TextUtils.isEmpty(playingVideo)) {
Log.v(TAG,"oncreate no video currently playing"); Log.v(TAG, "oncreate no video currently playing");
videoPlayerFragment.start(videoUuid); videoPlayerFragment.start(videoUuid);
} else if(!playingVideo.equals(videoUuid)){ } else if (!playingVideo.equals(videoUuid)) {
Log.v(TAG,"oncreate different video playing currently"); Log.v(TAG, "oncreate different video playing currently");
videoPlayerFragment.stopVideo(); videoPlayerFragment.stopVideo();
videoPlayerFragment.start(videoUuid); videoPlayerFragment.start(videoUuid);
} else { } 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 // 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); getSupportFragmentManager().findFragmentById(R.id.video_player_fragment);
assert videoPlayerFragment != null; assert videoPlayerFragment != null;
String videoUuid = intent.getStringExtra(VideoListActivity.EXTRA_VIDEOID); String videoUuid = intent.getStringExtra(VideoListActivity.EXTRA_VIDEOID);
Log.v(TAG, "new intent click: " + videoUuid +" is trying to replace: "+videoPlayerFragment.getVideoUuid()); Log.v(TAG, "new intent click: " + videoUuid + " is trying to replace: " + videoPlayerFragment.getVideoUuid());
assert videoPlayerFragment != null;
String playingVideo = videoPlayerFragment.getVideoUuid(); String playingVideo = videoPlayerFragment.getVideoUuid();
if (TextUtils.isEmpty(playingVideo)){ if (TextUtils.isEmpty(playingVideo)) {
Log.v(TAG,"new intent no video currently playing"); Log.v(TAG, "new intent no video currently playing");
videoPlayerFragment.start(videoUuid); videoPlayerFragment.start(videoUuid);
} else if(!playingVideo.equals(videoUuid)){ } else if (!playingVideo.equals(videoUuid)) {
Log.v(TAG,"new intent different video playing currently"); Log.v(TAG, "new intent different video playing currently");
videoPlayerFragment.stopVideo(); videoPlayerFragment.stopVideo();
videoPlayerFragment.start(videoUuid); videoPlayerFragment.start(videoUuid);
} else { } 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 // if we are in landscape set the video to fullscreen
@ -245,12 +252,10 @@ public class VideoPlayActivity extends AppCompatActivity {
if (orientation == Configuration.ORIENTATION_LANDSCAPE) { if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
setOrientation(true); setOrientation(true);
} }
} }
@Override @Override
public void onConfigurationChanged(Configuration newConfig) { public void onConfigurationChanged(@NonNull Configuration newConfig) {
Log.v(TAG, "onConfigurationChanged()..."); Log.v(TAG, "onConfigurationChanged()...");
super.onConfigurationChanged(newConfig); super.onConfigurationChanged(newConfig);
@ -263,58 +268,44 @@ public class VideoPlayActivity extends AppCompatActivity {
} }
} }
private void setOrientation(Boolean isLandscape) { private void setOrientation(Boolean isLandscape) {
FragmentManager fragmentManager = getSupportFragmentManager(); FragmentManager fragmentManager = getSupportFragmentManager();
VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment) fragmentManager.findFragmentById(R.id.video_player_fragment); VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment) fragmentManager.findFragmentById(R.id.video_player_fragment);
VideoMetaDataFragment videoMetaFragment = (VideoMetaDataFragment) fragmentManager.findFragmentById(R.id.video_meta_data_fragment); VideoMetaDataFragment videoMetaFragment = (VideoMetaDataFragment) fragmentManager.findFragmentById(R.id.video_meta_data_fragment);
if (isLandscape) { assert videoPlayerFragment != null;
assert videoPlayerFragment != null; RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) videoPlayerFragment.requireView().getLayoutParams();
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) Objects.requireNonNull(videoPlayerFragment.getView()).getLayoutParams(); params.width = FrameLayout.LayoutParams.MATCH_PARENT;
params.width = FrameLayout.LayoutParams.MATCH_PARENT; params.height = isLandscape ? FrameLayout.LayoutParams.MATCH_PARENT : (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 250, getResources().getDisplayMetrics());
params.height = FrameLayout.LayoutParams.MATCH_PARENT;
videoPlayerFragment.getView().setLayoutParams(params);
if (videoMetaFragment != null) { videoPlayerFragment.requireView().setLayoutParams(params);
fragmentManager.beginTransaction()
.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out) if (videoMetaFragment != null) {
.hide(videoMetaFragment) FragmentTransaction transaction = fragmentManager.beginTransaction()
.commit(); .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
if (isLandscape) {
transaction.hide(videoMetaFragment);
} else {
transaction.show(videoMetaFragment);
} }
videoPlayerFragment.setIsFullscreen(true);
} else { transaction.commit();
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);
} }
videoPlayerFragment.setIsFullscreen(isLandscape);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
} }
@Override @Override
protected void onDestroy() { protected void onDestroy() {
VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment) VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment)
getSupportFragmentManager().findFragmentById(R.id.video_player_fragment); getSupportFragmentManager().findFragmentById(R.id.video_player_fragment);
assert videoPlayerFragment != null; assert videoPlayerFragment != null;
videoPlayerFragment.destroyVideo(); videoPlayerFragment.destroyVideo();
super.onDestroy(); super.onDestroy();
Log.v(TAG, "onDestroy..."); Log.v(TAG, "onDestroy...");
} }
@ -335,15 +326,6 @@ public class VideoPlayActivity extends AppCompatActivity {
protected void onStop() { protected void onStop() {
super.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) VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment)
getSupportFragmentManager().findFragmentById(R.id.video_player_fragment); getSupportFragmentManager().findFragmentById(R.id.video_player_fragment);
@ -362,108 +344,115 @@ public class VideoPlayActivity extends AppCompatActivity {
@SuppressLint("NewApi") @SuppressLint("NewApi")
@Override @Override
public void onUserLeaveHint () { public void onUserLeaveHint() {
Log.v(TAG, "onUserLeaveHint()...");
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
FragmentManager fragmentManager = getSupportFragmentManager(); FragmentManager fragmentManager = getSupportFragmentManager();
VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment) fragmentManager.findFragmentById(R.id.video_player_fragment); 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){ String backgroundBehavior = sharedPref.getString(getString(R.string.pref_background_behavior_key), getString(R.string.pref_background_stop_key));
case "backgroundStop":
Log.v(TAG,"stop the video"); assert videoPlayerFragment != null;
videoPlayerFragment.pauseVideo(); assert backgroundBehavior != null;
stopService(new Intent(this, VideoPlayerService.class));
super.onBackPressed(); if (backgroundBehavior.equals(getString(R.string.pref_background_stop_key))) {
break; Log.v(TAG, "stop the video");
case "backgroundAudio":
Log.v(TAG,"play the Audio"); videoPlayerFragment.pauseVideo();
super.onBackPressed(); stopService(new Intent(this, VideoPlayerService.class));
break; super.onBackPressed();
case "backgroundFloat":
Log.v(TAG,"play in floating video"); } else if (backgroundBehavior.equals(getString(R.string.pref_background_audio_key))) {
//canEnterPIPMode makes sure API level is high enough Log.v(TAG, "play the Audio");
if (canEnterPipMode(this)) { super.onBackPressed();
Log.v(TAG, "enabling pip");
enterPipMode(); } else if (backgroundBehavior.equals(getString(R.string.pref_background_float_key))) {
} else { Log.v(TAG, "play in floating video");
Log.v(TAG, "unable to use pip"); //canEnterPIPMode makes sure API level is high enough
} if (canEnterPipMode(this)) {
break; 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") @SuppressLint("NewApi")
public void onBackPressed() { public void onBackPressed() {
Log.v(TAG, "onBackPressed()...");
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment) VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment)
getSupportFragmentManager().findFragmentById(R.id.video_player_fragment); getSupportFragmentManager().findFragmentById(R.id.video_player_fragment);
//copying Youtube behavior to have back button exit full screen. assert videoPlayerFragment != null;
if (videoPlayerFragment.getIsFullscreen()){
Log.v(TAG,"exiting full screen"); // copying Youtube behavior to have back button exit full screen.
if (videoPlayerFragment.getIsFullscreen()) {
Log.v(TAG, "exiting full screen");
videoPlayerFragment.fullScreenToggle(); videoPlayerFragment.fullScreenToggle();
return; return;
} }
// pause video if pref is enabled
if (sharedPref.getBoolean("pref_back_pause", true)) { if (sharedPref.getBoolean(getString(R.string.pref_back_pause_key), true)) {
assert videoPlayerFragment != null;
videoPlayerFragment.pauseVideo(); 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){ } else if (backgroundBehavior.equals(getString(R.string.pref_background_audio_key))) {
case "backgroundStop": Log.v(TAG, "play the Audio");
Log.v(TAG,"stop the video"); super.onBackPressed();
videoPlayerFragment.pauseVideo();
stopService(new Intent(this, VideoPlayerService.class)); } 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(); super.onBackPressed();
break; }
case "backgroundAudio":
Log.v(TAG,"play the Audio"); } else {
super.onBackPressed(); // Deal with bad entries from older version
break; Log.v(TAG, "No setting, fallback");
case "backgroundFloat": super.onBackPressed();
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;
} }
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) @RequiresApi(api = Build.VERSION_CODES.O)
public void enterPipMode() { public void enterPipMode() {
Rational rational = new Rational(239, 100); Rational rational = new Rational(239, 100);
Log.v(TAG,rational.toString()); Log.v(TAG, rational.toString());
PictureInPictureParams mParams = PictureInPictureParams mParams =
new PictureInPictureParams.Builder() new PictureInPictureParams.Builder()
.setAspectRatio(rational) .setAspectRatio(rational)
@ -472,19 +461,26 @@ public class VideoPlayActivity extends AppCompatActivity {
enterPictureInPictureMode(mParams); enterPictureInPictureMode(mParams);
} }
@Override @Override
public void onPictureInPictureModeChanged (boolean isInPictureInPictureMode, Configuration newConfig) { public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode, Configuration newConfig) {
FragmentManager fragmentManager = getSupportFragmentManager(); FragmentManager fragmentManager = getSupportFragmentManager();
VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment) fragmentManager.findFragmentById(R.id.video_player_fragment); VideoPlayerFragment videoPlayerFragment = (VideoPlayerFragment) fragmentManager.findFragmentById(R.id.video_player_fragment);
if (isInPictureInPictureMode) { if (videoPlayerFragment != null) {
changedToPipMode();
Log.v(TAG,"switched to pip "); if (isInPictureInPictureMode) {
videoPlayerFragment.useController(false); changedToPipMode();
Log.v(TAG, "switched to pip ");
videoPlayerFragment.useController(false);
} else {
changedToNormalMode();
Log.v(TAG, "switched to normal");
videoPlayerFragment.useController(true);
}
} else { } else {
changedToNormalMode(); Log.e(TAG, "videoPlayerFragment is NULL");
Log.v(TAG,"switched to normal");
videoPlayerFragment.useController(true);
} }
} }

View File

@ -18,15 +18,11 @@
package net.schueller.peertube.adapter; package net.schueller.peertube.adapter;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.provider.SearchRecentSuggestions;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -39,12 +35,8 @@ import androidx.recyclerview.widget.RecyclerView;
import net.schueller.peertube.R; 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.database.Server;
import net.schueller.peertube.helper.APIUrlHelper; import net.schueller.peertube.helper.APIUrlHelper;
import net.schueller.peertube.provider.SearchSuggestionsProvider;
import net.schueller.peertube.service.LoginService; import net.schueller.peertube.service.LoginService;
@ -65,7 +57,7 @@ public class ServerListAdapter extends RecyclerView.Adapter<ServerListAdapter.Se
@NonNull @NonNull
@Override @Override
public ServerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public ServerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = mInflater.inflate(R.layout.row_serverbook, parent, false); View itemView = mInflater.inflate(R.layout.row_server_address_book, parent, false);
return new ServerViewHolder(itemView); return new ServerViewHolder(itemView);
} }
@ -94,7 +86,7 @@ public class ServerListAdapter extends RecyclerView.Adapter<ServerListAdapter.Se
String serverUrl = APIUrlHelper.cleanServerUrl(getServerAtPosition(position).getServerHost()); String serverUrl = APIUrlHelper.cleanServerUrl(getServerAtPosition(position).getServerHost());
editor.putString("pref_api_base", serverUrl); editor.putString(mInflater.getContext().getString(R.string.pref_api_base_key), serverUrl);
editor.apply(); editor.apply();
// attempt authentication if we have a username // attempt authentication if we have a username

View File

@ -27,7 +27,7 @@ import android.widget.Toast;
import net.schueller.peertube.R; 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.helper.APIUrlHelper;
import net.schueller.peertube.model.Server; import net.schueller.peertube.model.Server;
@ -41,14 +41,14 @@ import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import static android.app.Activity.RESULT_OK; import static android.app.Activity.RESULT_OK;
public class ServerAdapter extends RecyclerView.Adapter<ServerAdapter.AccountViewHolder> { public class ServerSearchAdapter extends RecyclerView.Adapter<ServerSearchAdapter.AccountViewHolder> {
private ArrayList<Server> serverList; private ArrayList<Server> serverList;
private SelectServerActivity activity; private SearchServerActivity activity;
private String baseUrl; private String baseUrl;
public ServerAdapter(ArrayList<Server> serverList, SelectServerActivity activity) { public ServerSearchAdapter(ArrayList<Server> serverList, SearchServerActivity activity) {
this.serverList = serverList; this.serverList = serverList;
this.activity = activity; this.activity = activity;
} }
@ -57,7 +57,7 @@ public class ServerAdapter extends RecyclerView.Adapter<ServerAdapter.AccountVie
@Override @Override
public AccountViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public AccountViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.row_server, parent, false); View view = layoutInflater.inflate(R.layout.row_search_server, parent, false);
baseUrl = APIUrlHelper.getUrl(activity); baseUrl = APIUrlHelper.getUrl(activity);

View File

@ -63,7 +63,7 @@ public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.VideoViewHol
@Override @Override
public VideoViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { public VideoViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext()); LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.row_video, parent, false); View view = layoutInflater.inflate(R.layout.row_video_list, parent, false);
baseUrl = APIUrlHelper.getUrl(context); baseUrl = APIUrlHelper.getUrl(context);

View File

@ -38,10 +38,12 @@ import android.widget.EditText;
import android.widget.Toast; import android.widget.Toast;
import net.schueller.peertube.R; import net.schueller.peertube.R;
import net.schueller.peertube.activity.SelectServerActivity; import net.schueller.peertube.activity.SearchServerActivity;
import net.schueller.peertube.activity.ServerAddressBookActivity; import net.schueller.peertube.activity.ServerAddressBookActivity;
import net.schueller.peertube.helper.APIUrlHelper; import net.schueller.peertube.helper.APIUrlHelper;
import java.util.Objects;
import static android.app.Activity.RESULT_OK; import static android.app.Activity.RESULT_OK;
@ -78,14 +80,15 @@ public class AddServerFragment extends Fragment {
Activity act = getActivity(); Activity act = getActivity();
Boolean formValid = true; boolean formValid = true;
// close keyboard // close keyboard
try { try {
assert act != null;
InputMethodManager inputManager = (InputMethodManager) InputMethodManager inputManager = (InputMethodManager)
act.getSystemService(Context.INPUT_METHOD_SERVICE); act.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(act.getCurrentFocus().getWindowToken(), inputManager.hideSoftInputFromWindow(Objects.requireNonNull(act.getCurrentFocus()).getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS); InputMethodManager.HIDE_NOT_ALWAYS);
} catch (Exception e) { } catch (Exception e) {
@ -128,7 +131,7 @@ public class AddServerFragment extends Fragment {
Button pickServerUrl = mView.findViewById(R.id.pickServerUrl); Button pickServerUrl = mView.findViewById(R.id.pickServerUrl);
pickServerUrl.setOnClickListener(view -> { pickServerUrl.setOnClickListener(view -> {
Intent intentServer = new Intent(getActivity(), SelectServerActivity.class); Intent intentServer = new Intent(getActivity(), SearchServerActivity.class);
this.startActivityForResult(intentServer, PICK_SERVER); this.startActivityForResult(intentServer, PICK_SERVER);
}); });

View File

@ -17,6 +17,7 @@
*/ */
package net.schueller.peertube.fragment; package net.schueller.peertube.fragment;
import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
@ -44,7 +45,7 @@ public class VideoMenuQualityFragment extends BottomSheetDialogFragment {
public static final String TAG = "VideoMenuQuality"; public static final String TAG = "VideoMenuQuality";
private static File autoQualityFile; private static File autoQualityFile;
public static VideoMenuQualityFragment newInstance(ArrayList<File> files) { public static VideoMenuQualityFragment newInstance(Context context, ArrayList<File> files) {
mFiles = files; mFiles = files;
@ -53,7 +54,7 @@ public class VideoMenuQualityFragment extends BottomSheetDialogFragment {
autoQualityFile = new File(); autoQualityFile = new File();
Resolution autoQualityResolution = new Resolution(); Resolution autoQualityResolution = new Resolution();
autoQualityResolution.setId(0); autoQualityResolution.setId(0);
autoQualityResolution.setLabel("Auto"); autoQualityResolution.setLabel(context.getString(R.string.menu_video_options_quality_automated));
autoQualityFile.setId(0); autoQualityFile.setId(0);
autoQualityFile.setResolution(autoQualityResolution); autoQualityFile.setResolution(autoQualityResolution);
} }
@ -74,11 +75,11 @@ public class VideoMenuQualityFragment extends BottomSheetDialogFragment {
false); false);
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext()); 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) { 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); TextView iconView = menuRow.findViewById(R.id.video_quality_icon);
iconView.setId(file.getResolution().getId()); iconView.setId(file.getResolution().getId());
@ -90,7 +91,7 @@ public class VideoMenuQualityFragment extends BottomSheetDialogFragment {
textView.setOnClickListener(view1 -> { textView.setOnClickListener(view1 -> {
// Log.v(TAG, file.getResolution().getLabel()); // Log.v(TAG, file.getResolution().getLabel());
SharedPreferences.Editor editor = sharedPref.edit(); 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(); editor.apply();
for (File fileV : mFiles) { for (File fileV : mFiles) {

View File

@ -65,6 +65,10 @@ public class VideoMetaDataFragment extends Fragment {
private static final String TAG = "VideoMetaDataFragment"; 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 Rating videoRating;
private ColorStateList defaultTextColor; private ColorStateList defaultTextColor;
@ -72,13 +76,11 @@ public class VideoMetaDataFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
// Inflate the layout for this fragment // Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_video_meta, container, false); return inflater.inflate(R.layout.fragment_video_meta, container, false);
} }
public void updateVideoMeta(Video video, VideoPlayerService mService) { public void updateVideoMeta(Video video, VideoPlayerService mService) {
Context context = getContext(); Context context = getContext();
Activity activity = getActivity(); Activity activity = getActivity();
@ -91,26 +93,23 @@ public class VideoMetaDataFragment extends Fragment {
thumbsUpButton.setText(R.string.video_thumbs_up_icon); thumbsUpButton.setText(R.string.video_thumbs_up_icon);
new Iconics.IconicsBuilder().ctx(context).on(thumbsUpButton).build(); new Iconics.IconicsBuilder().ctx(context).on(thumbsUpButton).build();
thumbsUpButton.setOnClickListener(v -> { 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 // Thumbs Down
Button thumbsDownButton = activity.findViewById(R.id.video_thumbs_down); Button thumbsDownButton = activity.findViewById(R.id.video_thumbs_down);
thumbsDownButton.setText(R.string.video_thumbs_down_icon); thumbsDownButton.setText(R.string.video_thumbs_down_icon);
new Iconics.IconicsBuilder().ctx(context).on(thumbsDownButton).build(); new Iconics.IconicsBuilder().ctx(context).on(thumbsDownButton).build();
thumbsDownButton.setOnClickListener(v -> { thumbsDownButton.setOnClickListener(v -> {
rateVideo(false, video.getId()); rateVideo(false, video);
}); });
// video rating // video rating
videoRating = new Rating(); videoRating = new Rating();
videoRating.setRating("none"); // default videoRating.setRating(RATING_NONE); // default
updateVideoRating(); updateVideoRating(video);
// Retrieve which rating the user gave to this video
if (Session.getInstance().isLoggedIn()) { if (Session.getInstance().isLoggedIn()) {
Call<Rating> call = videoDataService.getVideoRating(video.getId()); Call<Rating> call = videoDataService.getVideoRating(video.getId());
call.enqueue(new Callback<Rating>() { call.enqueue(new Callback<Rating>() {
@ -118,20 +117,16 @@ public class VideoMetaDataFragment extends Fragment {
@Override @Override
public void onResponse(Call<Rating> call, Response<Rating> response) { public void onResponse(Call<Rating> call, Response<Rating> response) {
videoRating = response.body(); videoRating = response.body();
updateVideoRating(); updateVideoRating(video);
} }
@Override @Override
public void onFailure(Call<Rating> call, Throwable t) { public void onFailure(Call<Rating> 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 // Share
Button videoShareButton = activity.findViewById(R.id.video_share); Button videoShareButton = activity.findViewById(R.id.video_share);
videoShareButton.setText(R.string.video_share_icon); videoShareButton.setText(R.string.video_share_icon);
@ -156,7 +151,6 @@ public class VideoMetaDataFragment extends Fragment {
} }
}); });
Account account = video.getAccount(); Account account = video.getAccount();
// owner / creator Avatar // owner / creator Avatar
@ -198,7 +192,6 @@ public class VideoMetaDataFragment extends Fragment {
TextView videoDescription = activity.findViewById(R.id.description); TextView videoDescription = activity.findViewById(R.id.description);
videoDescription.setText(video.getDescription()); videoDescription.setText(video.getDescription());
// video privacy // video privacy
TextView videoPrivacy = activity.findViewById(R.id.video_privacy); TextView videoPrivacy = activity.findViewById(R.id.video_privacy);
videoPrivacy.setText(video.getPrivacy().getLabel()); videoPrivacy.setText(video.getPrivacy().getLabel());
@ -211,7 +204,7 @@ public class VideoMetaDataFragment extends Fragment {
TextView videoLicense = activity.findViewById(R.id.video_license); TextView videoLicense = activity.findViewById(R.id.video_license);
videoLicense.setText(video.getLicence().getLabel()); videoLicense.setText(video.getLicence().getLabel());
// video langauge // video language
TextView videoLanguage = activity.findViewById(R.id.video_language); TextView videoLanguage = activity.findViewById(R.id.video_language);
videoLanguage.setText(video.getLanguage().getLabel()); videoLanguage.setText(video.getLanguage().getLabel());
@ -219,7 +212,6 @@ public class VideoMetaDataFragment extends Fragment {
TextView videoTags = activity.findViewById(R.id.video_tags); TextView videoTags = activity.findViewById(R.id.video_tags);
videoTags.setText(android.text.TextUtils.join(", ", video.getTags())); videoTags.setText(android.text.TextUtils.join(", ", video.getTags()));
// more button // more button
TextView moreButton = activity.findViewById(R.id.moreButton); TextView moreButton = activity.findViewById(R.id.moreButton);
moreButton.setText(R.string.video_more_icon); moreButton.setText(R.string.video_more_icon);
@ -259,8 +251,7 @@ public class VideoMetaDataFragment extends Fragment {
} }
void updateVideoRating(Video video) {
void updateVideoRating() {
Button thumbsUpButton = getActivity().findViewById(R.id.video_thumbs_up); Button thumbsUpButton = getActivity().findViewById(R.id.video_thumbs_up);
Button thumbsDownButton = getActivity().findViewById(R.id.video_thumbs_down); 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}); TypedArray a = getContext().obtainStyledAttributes(typedValue.data, new int[]{R.attr.colorPrimary});
int accentColor = a.getColor(0, 0); int accentColor = a.getColor(0, 0);
if (videoRating.getRating().equals(getString(R.string.video_rating_none))) { // Change the color of the thumbs
thumbsUpButton.setTextColor(defaultTextColor); switch (videoRating.getRating()) {
thumbsDownButton.setTextColor(defaultTextColor); case RATING_NONE:
//Log.v(TAG, getString(R.string.video_rating_none)); thumbsUpButton.setTextColor(defaultTextColor);
thumbsDownButton.setTextColor(defaultTextColor);
} else if (videoRating.getRating().equals(getString(R.string.video_rating_like))) { break;
thumbsUpButton.setTextColor(accentColor); case RATING_LIKE:
thumbsDownButton.setTextColor(defaultTextColor); thumbsUpButton.setTextColor(accentColor);
//Log.v(TAG, getString(R.string.video_rating_like)); thumbsDownButton.setTextColor(defaultTextColor);
break;
} else if (videoRating.getRating().equals(getString(R.string.video_rating_dislike))) { case RATING_DISLIKE:
thumbsUpButton.setTextColor(defaultTextColor); thumbsUpButton.setTextColor(defaultTextColor);
thumbsDownButton.setTextColor(accentColor); thumbsDownButton.setTextColor(accentColor);
//Log.v(TAG, getString(R.string.video_rating_dislike)); 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(); a.recycle();
} }
void rateVideo(Boolean rate, Integer videoId) { void rateVideo(Boolean like, Video video) {
// TODO cleanup
if (Session.getInstance().isLoggedIn()) { if (Session.getInstance().isLoggedIn()) {
final String ratePayload;
String ratePayload = getString(R.string.video_rating_none); switch (videoRating.getRating()) {
case RATING_LIKE:
if (rate) { ratePayload = like ? RATING_NONE : RATING_DISLIKE;
// thumbsup break;
if (videoRating.getRating().equals(getString(R.string.video_rating_none))) { case RATING_DISLIKE:
ratePayload = getString(R.string.video_rating_like); ratePayload = like ? RATING_LIKE : RATING_NONE;
} break;
} else { case RATING_NONE:
// thumbsdown default:
if (videoRating.getRating().equals(getString(R.string.video_rating_none))) { ratePayload = like ? RATING_LIKE : RATING_DISLIKE;
ratePayload = getString(R.string.video_rating_dislike); break;
}
} }
RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json"), "{\"rating\":\"" + ratePayload + "\"}"); 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()); String apiBaseURL = APIUrlHelper.getUrlWithVersion(getContext());
GetVideoDataService videoDataService = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class); GetVideoDataService videoDataService = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class);
Call<ResponseBody> call = videoDataService.rateVideo(videoId, body); Call<ResponseBody> call = videoDataService.rateVideo(video.getId(), body);
final String newRating = ratePayload;
call.enqueue(new Callback<ResponseBody>() { call.enqueue(new Callback<ResponseBody>() {
@Override @Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
//Log.v(TAG, response.toString()); //Log.v(TAG, response.toString());
// if 20x update likes // if 20x, update likes/dislikes
if (response.isSuccessful()) { if (response.isSuccessful()) {
videoRating.setRating(newRating); String previousRating = videoRating.getRating();
updateVideoRating();
// 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 { } else {
Toast.makeText(getContext(), getString(R.string.video_login_required_for_service), Toast.LENGTH_SHORT).show(); Toast.makeText(getContext(), getString(R.string.video_login_required_for_service), Toast.LENGTH_SHORT).show();
} }
} }
} }

View File

@ -17,9 +17,9 @@
*/ */
package net.schueller.peertube.fragment; package net.schueller.peertube.fragment;
import android.annotation.SuppressLint; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.preference.PreferenceManager;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -28,6 +28,7 @@ import android.widget.TextView;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import com.mikepenz.iconics.Iconics; import com.mikepenz.iconics.Iconics;
import net.schueller.peertube.R; import net.schueller.peertube.R;
import net.schueller.peertube.model.File; import net.schueller.peertube.model.File;
import net.schueller.peertube.service.VideoPlayerService; import net.schueller.peertube.service.VideoPlayerService;
@ -35,6 +36,7 @@ import net.schueller.peertube.service.VideoPlayerService;
import java.util.ArrayList; import java.util.ArrayList;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
public class VideoOptionsFragment extends BottomSheetDialogFragment { public class VideoOptionsFragment extends BottomSheetDialogFragment {
@ -62,32 +64,41 @@ public class VideoOptionsFragment extends BottomSheetDialogFragment {
LinearLayout menuHolder = view.findViewById(R.id.video_options_popup); LinearLayout menuHolder = view.findViewById(R.id.video_options_popup);
// Video Speed // 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 iconView = menuRow.findViewById(R.id.video_quality_icon);
TextView textView = menuRow.findViewById(R.id.video_quality_text); 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); iconView.setText(R.string.video_option_speed_icon);
new Iconics.IconicsBuilder().ctx(getContext()).on(iconView).build(); new Iconics.IconicsBuilder().ctx(getContext()).on(iconView).build();
textView.setOnClickListener(view1 -> { textView.setOnClickListener(view1 -> {
VideoMenuSpeedFragment videoMenuSpeedFragment = VideoMenuSpeedFragment videoMenuSpeedFragment =
VideoMenuSpeedFragment.newInstance(videoPlayerService); VideoMenuSpeedFragment.newInstance(videoPlayerService);
videoMenuSpeedFragment.show(getActivity().getSupportFragmentManager(), videoMenuSpeedFragment.show(requireActivity().getSupportFragmentManager(),
VideoMenuSpeedFragment.TAG); VideoMenuSpeedFragment.TAG);
}); });
menuHolder.addView(menuRow); menuHolder.addView(menuRow);
// Video Quality // 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 iconView2 = menuRow2.findViewById(R.id.video_quality_icon);
TextView textView2 = menuRow2.findViewById(R.id.video_quality_text); 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); iconView2.setText(R.string.video_option_quality_icon);
new Iconics.IconicsBuilder().ctx(getContext()).on(iconView2).build(); new Iconics.IconicsBuilder().ctx(getContext()).on(iconView2).build();
textView2.setOnClickListener(view1 -> { textView2.setOnClickListener(view1 -> {
VideoMenuQualityFragment videoMenuQualityFragment = VideoMenuQualityFragment videoMenuQualityFragment =
VideoMenuQualityFragment.newInstance(files); VideoMenuQualityFragment.newInstance(getContext(), files);
videoMenuQualityFragment.show(getActivity().getSupportFragmentManager(), videoMenuQualityFragment.show(requireActivity().getSupportFragmentManager(),
videoMenuQualityFragment.TAG); VideoMenuQualityFragment.TAG);
}); });
menuHolder.addView(menuRow2); menuHolder.addView(menuRow2);
@ -95,4 +106,26 @@ public class VideoOptionsFragment extends BottomSheetDialogFragment {
} }
private String getCurrentVideoQuality(ArrayList<File> 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);
}
} }

View File

@ -18,7 +18,6 @@
package net.schueller.peertube.fragment; package net.schueller.peertube.fragment;
import android.app.Activity; import android.app.Activity;
import android.app.AppOpsManager;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -66,15 +65,16 @@ import net.schueller.peertube.network.GetVideoDataService;
import net.schueller.peertube.network.RetrofitInstance; import net.schueller.peertube.network.RetrofitInstance;
import net.schueller.peertube.service.VideoPlayerService; import net.schueller.peertube.service.VideoPlayerService;
import java.util.Objects;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import retrofit2.Call; import retrofit2.Call;
import retrofit2.Callback; import retrofit2.Callback;
import retrofit2.Response; import retrofit2.Response;
import static net.schueller.peertube.helper.VideoHelper.canEnterPipMode;
public class VideoPlayerFragment extends Fragment implements VideoRendererEventListener { public class VideoPlayerFragment extends Fragment implements VideoRendererEventListener {
private String mVideoUuid; private String mVideoUuid;
@ -134,6 +134,7 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
progressBar = activity.findViewById(R.id.torrent_progress); progressBar = activity.findViewById(R.id.torrent_progress);
progressBar.setMax(100); progressBar.setMax(100);
assert context != null;
simpleExoPlayerView = new PlayerView(context); simpleExoPlayerView = new PlayerView(context);
simpleExoPlayerView = activity.findViewById(R.id.video_view); simpleExoPlayerView = activity.findViewById(R.id.video_view);
@ -195,30 +196,31 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
@Override @Override
public void onFailure(@NonNull Call<Video> call, @NonNull Throwable t) { public void onFailure(@NonNull Call<Video> call, @NonNull Throwable t) {
Log.wtf(TAG, t.fillInStackTrace()); Log.wtf(TAG, t.fillInStackTrace());
Toast.makeText(context, "Something went wrong: "+t.getLocalizedMessage(), Toast.LENGTH_LONG).show(); Toast.makeText(context, "Something went wrong: " + t.getLocalizedMessage(), Toast.LENGTH_LONG).show();
} }
}); });
} }
public void useController(boolean value){
if (mBound){ public void useController(boolean value) {
if (mBound) {
simpleExoPlayerView.setUseController(value); simpleExoPlayerView.setUseController(value);
} }
} }
private void playVideo(Video video) { private void playVideo(Video video) {
Context context = getContext(); Context context = getContext();
// video Meta fragment // video Meta fragment
assert getFragmentManager() != null;
VideoMetaDataFragment videoMetaDataFragment = (VideoMetaDataFragment) VideoMetaDataFragment videoMetaDataFragment = (VideoMetaDataFragment)
getFragmentManager().findFragmentById(R.id.video_meta_data_fragment); requireActivity().getSupportFragmentManager().findFragmentById(R.id.video_meta_data_fragment);
assert videoMetaDataFragment != null; assert videoMetaDataFragment != null;
videoMetaDataFragment.updateVideoMeta(video, mService); videoMetaDataFragment.updateVideoMeta(video, mService);
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); 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); torrentStatus.setVisibility(View.VISIBLE);
String stream = video.getFiles().get(0).getTorrentUrl(); String stream = video.getFiles().get(0).getTorrentUrl();
Log.v(TAG, "getTorrentUrl : " + video.getFiles().get(0).getTorrentUrl()); Log.v(TAG, "getTorrentUrl : " + video.getFiles().get(0).getTorrentUrl());
@ -226,11 +228,11 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
torrentStream.startStream(stream); torrentStream.startStream(stream);
} else { } else {
Integer videoQuality = sharedPref.getInt("pref_quality", 0); Integer videoQuality = sharedPref.getInt(getString(R.string.pref_quality_key), 0);
//get video qualities //get video qualities
String urlToPlay = video.getFiles().get(0).getFileUrl(); String urlToPlay = video.getFiles().get(0).getFileUrl();
for (File file :video.getFiles()) { for (File file : video.getFiles()) {
// Set quality if it matches // Set quality if it matches
if (file.getResolution().getId().equals(videoQuality)) { if (file.getResolution().getId().equals(videoQuality)) {
urlToPlay = file.getFileUrl(); urlToPlay = file.getFileUrl();
@ -247,7 +249,7 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
} }
private void startPlayer() { private void startPlayer() {
Util.startForegroundService(Objects.requireNonNull(getContext()), videoPlayerIntent); Util.startForegroundService(requireContext(), videoPlayerIntent);
} }
@ -259,30 +261,35 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
} }
public void pauseVideo() { public void pauseVideo() {
if (mBound){ if (mBound) {
mService.player.setPlayWhenReady(false); mService.player.setPlayWhenReady(false);
} }
} }
public void pauseToggle() { public void pauseToggle() {
if (mBound) { if (mBound) {
mService.player.setPlayWhenReady(!mService.player.getPlayWhenReady()); mService.player.setPlayWhenReady(!mService.player.getPlayWhenReady());
} }
} }
public void unPauseVideo() { public void unPauseVideo() {
if (mBound) { if (mBound) {
mService.player.setPlayWhenReady(true); mService.player.setPlayWhenReady(true);
} }
} }
public boolean isPaused(){
public boolean isPaused() {
return !mService.player.getPlayWhenReady(); return !mService.player.getPlayWhenReady();
} }
public void showControls(boolean value){
public void showControls(boolean value) {
simpleExoPlayerView.setUseController(value); simpleExoPlayerView.setUseController(value);
} }
public void stopVideo() { public void stopVideo() {
if (mBound) { if (mBound) {
Objects.requireNonNull(getContext()).unbindService(mConnection); requireContext().unbindService(mConnection);
mBound = false; mBound = false;
} }
} }
@ -290,7 +297,7 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
public void setIsFullscreen(Boolean fullscreen) { public void setIsFullscreen(Boolean fullscreen) {
isFullscreen = fullscreen; isFullscreen = fullscreen;
TextView fullscreenButton = getActivity().findViewById(R.id.exo_fullscreen); TextView fullscreenButton = requireActivity().findViewById(R.id.exo_fullscreen);
if (fullscreen) { if (fullscreen) {
fullscreenButton.setText(R.string.video_compress_icon); fullscreenButton.setText(R.string.video_compress_icon);
} else { } else {
@ -302,15 +309,17 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
public Boolean getIsFullscreen() { public Boolean getIsFullscreen() {
return isFullscreen; return isFullscreen;
} }
public void fullScreenToggle() { public void fullScreenToggle() {
if (!isFullscreen) { if (!isFullscreen) {
setIsFullscreen(true); setIsFullscreen(true);
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); requireActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else { } else {
setIsFullscreen(false); setIsFullscreen(false);
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); requireActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} }
} }
/** /**
* Torrent Playback * Torrent Playback
* *
@ -404,18 +413,6 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
Log.v(TAG, "onVideoDisabled()..."); 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() { View.OnTouchListener touchListener = new View.OnTouchListener() {
@Override @Override
public boolean onTouch(View v, MotionEvent event) { public boolean onTouch(View v, MotionEvent event) {
@ -423,62 +420,64 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
} }
}; };
public String getVideoUuid(){
public String getVideoUuid() {
return mVideoUuid; return mVideoUuid;
} }
class MyGestureListener extends GestureDetector.SimpleOnGestureListener { class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
/* /*
@Override @Override
public boolean onDown(MotionEvent event) { public boolean onDown(MotionEvent event) {
Log.d("TAG","onDown: "); Log.d("TAG","onDown: ");
return true; return true;
} }
@Override @Override
public boolean onSingleTapConfirmed(MotionEvent e) { public boolean onSingleTapConfirmed(MotionEvent e) {
Log.i("TAG", "onSingleTapConfirmed: "); Log.i("TAG", "onSingleTapConfirmed: ");
pauseToggle(); pauseToggle();
return true; return true;
} }
@Override @Override
public void onLongPress(MotionEvent e) { public void onLongPress(MotionEvent e) {
Log.i("TAG", "onLongPress: "); Log.i("TAG", "onLongPress: ");
} }
@Override @Override
public boolean onDoubleTap(MotionEvent e) { public boolean onDoubleTap(MotionEvent e) {
Log.i("TAG", "onDoubleTap: "); Log.i("TAG", "onDoubleTap: ");
return true; return true;
} }
@Override @Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) { float distanceX, float distanceY) {
Log.i("TAG", "onScroll: "); Log.i("TAG", "onScroll: ");
return true; return true;
} }
*/ */
@RequiresApi(api = Build.VERSION_CODES.N) @RequiresApi(api = Build.VERSION_CODES.N)
@Override @Override
public boolean onFling(MotionEvent event1, MotionEvent event2, public boolean onFling(MotionEvent event1, MotionEvent event2,
float velocityX, float velocityY) { float velocityX, float velocityY) {
Log.d(TAG ,event1.toString()); Log.d(TAG, event1.toString());
Log.d(TAG,event2.toString()); Log.d(TAG, event2.toString());
Log.d(TAG, String.valueOf(velocityX)); 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. //arbitrarily velocity speeds that seem to work to differentiate events.
if (velocityY>4000){ if (velocityY > 4000) {
Log.d(TAG,"we have a drag down event"); Log.d(TAG, "we have a drag down event");
if (canEnterPipMode(getContext())) { if (canEnterPipMode(getContext())) {
getActivity().enterPictureInPictureMode(); requireActivity().enterPictureInPictureMode();
} }
} }
if ((velocityX>2000) && (Math.abs(velocityY) <2000)){ if ((velocityX > 2000) && (Math.abs(velocityY) < 2000)) {
Log.d(TAG,"swipe right "+velocityY); Log.d(TAG, "swipe right " + velocityY);
} }
if ((velocityX<2000) && (Math.abs(velocityY)<2000)){ if ((velocityX < 2000) && (Math.abs(velocityY) < 2000)) {
Log.d(TAG,"swipe left "+velocityY); Log.d(TAG, "swipe left " + velocityY);
} }
return true; return true;
} }

View File

@ -32,7 +32,7 @@ public class APIUrlHelper{
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
// validate URL is valid // 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)) { if (!URLUtil.isValidUrl(URL)) {
return "http://invalid"; return "http://invalid";
} }

View File

@ -1,25 +0,0 @@
/*
* Copyright 2018 Stefan Schüller <sschueller@techdroid.com>
*
* License: GPL-3.0+
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.schueller.peertube.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";
}

View File

@ -0,0 +1,40 @@
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;
}
}

View File

@ -178,11 +178,18 @@ public class VideoPlayerService extends Service {
//Playback speed control //Playback speed control
public void setPlayBackSpeed(float speed) { public void setPlayBackSpeed(float speed) {
Log.v(TAG, "setPlayBackSpeed..."); Log.v(TAG, "setPlayBackSpeed...");
player.setPlaybackParameters(new PlaybackParameters(speed)); 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() { public void playVideo() {
Context context = this; Context context = this;

View File

@ -4,7 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".activity.SelectServerActivity"> tools:context=".activity.SearchServerActivity">
<com.google.android.material.appbar.AppBarLayout <com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_server_selection" android:id="@+id/appbar_server_selection"

View File

@ -14,7 +14,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@android:color/darker_gray" android:background="@android:color/darker_gray"
tools:listitem="@layout/row_serverbook" /> tools:listitem="@layout/row_server_address_book" />

View File

@ -143,8 +143,8 @@
<string name="video_meta_button_license">الرخصة</string> <string name="video_meta_button_license">الرخصة</string>
<string name="video_meta_button_language">اللغة</string> <string name="video_meta_button_language">اللغة</string>
<string name="video_meta_button_tags">العلامات</string> <string name="video_meta_button_tags">العلامات</string>
<string name="menu_video_options_playback_speed">سرعة التشغيل</string> <string name="menu_video_options_playback_speed" formatted="true">سرعة التشغيل (%1$s)</string>
<string name="menu_video_options_quality">الجودة</string> <string name="menu_video_options_quality" formatted="true">(%1$s) الجودة</string>
<string name="account_bottom_menu_videos">الفيديو</string> <string name="account_bottom_menu_videos">الفيديو</string>
<string name="account_bottom_menu_channels">القنوات</string> <string name="account_bottom_menu_channels">القنوات</string>
<string name="account_bottom_menu_about">حول</string> <string name="account_bottom_menu_about">حول</string>

View File

@ -285,8 +285,8 @@
<string name="deeppurple">গাঢ় বেগুনি</string> <string name="deeppurple">গাঢ় বেগুনি</string>
<string name="action_bar_title_account">অ্যাকাউন্ট</string> <string name="action_bar_title_account">অ্যাকাউন্ট</string>
<string name="bottom_nav_title_recent">সাম্প্রতিক</string> <string name="bottom_nav_title_recent">সাম্প্রতিক</string>
<string name="menu_video_options_playback_speed">প্লেব্যাক এর গতি</string> <string name="menu_video_options_playback_speed" formatted="true">প্লেব্যাক এর গতি (%1$s)</string>
<string name="menu_video_options_quality">কোয়ালিটি</string> <string name="menu_video_options_quality" formatted="true">কোয়ালিটি (%1$s)</string>
<string name="account_bottom_menu_videos">ভিডিও</string> <string name="account_bottom_menu_videos">ভিডিও</string>
<string name="account_bottom_menu_channels">চ্যানেলগুলি</string> <string name="account_bottom_menu_channels">চ্যানেলগুলি</string>
<string name="account_bottom_menu_about">সম্পর্কিত</string> <string name="account_bottom_menu_about">সম্পর্কিত</string>

View File

@ -276,8 +276,8 @@
<string name="video_meta_button_license">Lizenz</string> <string name="video_meta_button_license">Lizenz</string>
<string name="video_meta_button_language">Sprache</string> <string name="video_meta_button_language">Sprache</string>
<string name="video_meta_button_tags">Tags</string> <string name="video_meta_button_tags">Tags</string>
<string name="menu_video_options_playback_speed">Wiedergabegeschwindigkeit</string> <string name="menu_video_options_playback_speed" formatted="true">Wiedergabegeschwindigkeit (%1$s)</string>
<string name="menu_video_options_quality">Qualität</string> <string name="menu_video_options_quality" formatted="true">Qualität (%1$s)</string>
<string name="account_bottom_menu_videos">Videos</string> <string name="account_bottom_menu_videos">Videos</string>
<string name="account_bottom_menu_channels">Kanäle</string> <string name="account_bottom_menu_channels">Kanäle</string>
<string name="account_bottom_menu_about">Über</string> <string name="account_bottom_menu_about">Über</string>
@ -314,4 +314,8 @@
<string name="clear_search_history">Suchverlauf löschen</string> <string name="clear_search_history">Suchverlauf löschen</string>
<string name="pref_description_language_app">Wählen Sie die Sprache für die Anwendungsschnittstelle aus. Starten Sie die Anwendung neu, damit die Änderung wirksam wird.</string> <string name="pref_description_language_app">Wählen Sie die Sprache für die Anwendungsschnittstelle aus. Starten Sie die Anwendung neu, damit die Änderung wirksam wird.</string>
<string name="pref_language_app">Sprache der Anwendung</string> <string name="pref_language_app">Sprache der Anwendung</string>
<string name="settings_activity_about_category_title">Über</string>
<string name="settings_activity_video_playback_category_title">Videowiedergabe</string>
<string name="settings_activity_video_list_category_title">Videoliste</string>
<string name="server_selection_video_totals">Videos: %s, Lokale Videos: %s</string>
</resources> </resources>

View File

@ -96,8 +96,8 @@
<string name="video_meta_button_license">Licencia</string> <string name="video_meta_button_license">Licencia</string>
<string name="video_meta_button_language">Idioma</string> <string name="video_meta_button_language">Idioma</string>
<string name="video_meta_button_tags">Etiquetas</string> <string name="video_meta_button_tags">Etiquetas</string>
<string name="menu_video_options_playback_speed">Velocidad de reproducción</string> <string name="menu_video_options_playback_speed" formatted="true">Velocidad de reproducción (%1$s)</string>
<string name="menu_video_options_quality">Calidad</string> <string name="menu_video_options_quality" formatted="true">Calidad (%1$s)</string>
<string name="account_bottom_menu_videos">Vídeos</string> <string name="account_bottom_menu_videos">Vídeos</string>
<string name="account_bottom_menu_channels">Canales</string> <string name="account_bottom_menu_channels">Canales</string>
<string name="account_bottom_menu_about">Acerca de</string> <string name="account_bottom_menu_about">Acerca de</string>

View File

@ -103,7 +103,7 @@
<string name="mi">maori</string> <string name="mi">maori</string>
<string name="or">oriya (makrokieli)</string> <string name="or">oriya (makrokieli)</string>
<string name="bi">bislama</string> <string name="bi">bislama</string>
<string name="menu_video_options_quality">Laatu</string> <string name="menu_video_options_quality" formatted="true">Laatu (%s)</string>
<string name="api_error">Jotain meni pieleen, yritä myöhemmin!</string> <string name="api_error">Jotain meni pieleen, yritä myöhemmin!</string>
<string name="bg">bulgaria</string> <string name="bg">bulgaria</string>
<string name="uz">uzbekki</string> <string name="uz">uzbekki</string>
@ -204,7 +204,7 @@
<string name="nv">navajo</string> <string name="nv">navajo</string>
<string name="kr">kanuri</string> <string name="kr">kanuri</string>
<string name="su">sunda</string> <string name="su">sunda</string>
<string name="menu_video_options_playback_speed">Toistonopeus</string> <string name="menu_video_options_playback_speed" formatted="true">Toistonopeus (%1$s)</string>
<string name="ii">sichuanin-yi</string> <string name="ii">sichuanin-yi</string>
<string name="red">Punainen</string> <string name="red">Punainen</string>
<string name="video_row_video_thumbnail">Videon esikatselukuva</string> <string name="video_row_video_thumbnail">Videon esikatselukuva</string>

View File

@ -99,8 +99,8 @@
<string name="video_meta_button_license">Licence</string> <string name="video_meta_button_license">Licence</string>
<string name="video_meta_button_language">Langue</string> <string name="video_meta_button_language">Langue</string>
<string name="video_meta_button_tags">Étiquettes</string> <string name="video_meta_button_tags">Étiquettes</string>
<string name="menu_video_options_playback_speed">Vitesse de lecture</string> <string name="menu_video_options_playback_speed" formatted="true">Vitesse de lecture (%1$s)</string>
<string name="menu_video_options_quality">Qualité</string> <string name="menu_video_options_quality" formatted="true">Qualité (%1$s)</string>
<string name="account_bottom_menu_videos">Vidéos</string> <string name="account_bottom_menu_videos">Vidéos</string>
<string name="account_bottom_menu_channels">Chaînes</string> <string name="account_bottom_menu_channels">Chaînes</string>
<string name="account_bottom_menu_about">À propos</string> <string name="account_bottom_menu_about">À propos</string>
@ -343,4 +343,8 @@
<string name="title_activity_select_server">Sélectionner un serveur</string> <string name="title_activity_select_server">Sélectionner un serveur</string>
<string name="server_book_del_alert_title">Retirer un serveur</string> <string name="server_book_del_alert_title">Retirer un serveur</string>
<string name="server_book_del_alert_msg">Voulez-vous vraiment retirer ce serveur de votre carnet d\'adresses ?</string> <string name="server_book_del_alert_msg">Voulez-vous vraiment retirer ce serveur de votre carnet d\'adresses ?</string>
<string name="menu_video_options_quality_automated">Automatique</string>
<string name="server_selection_nsfw_instance">Instance avec du contenu adulte</string>
<string name="hello_blank_fragment">Bonjour ! Fragment vide</string>
<string name="server_selection_video_totals">Vidéos : %s, Vidéos locales : %s</string>
</resources> </resources>

View File

@ -285,8 +285,8 @@
<string name="video_meta_button_license">Ceadachas</string> <string name="video_meta_button_license">Ceadachas</string>
<string name="video_meta_button_language">Cànan</string> <string name="video_meta_button_language">Cànan</string>
<string name="video_meta_button_tags">Tagaichean</string> <string name="video_meta_button_tags">Tagaichean</string>
<string name="menu_video_options_playback_speed">Luaths na cluiche</string> <string name="menu_video_options_playback_speed" formatted="true">Luaths na cluiche (%1$s)</string>
<string name="menu_video_options_quality">Càileachd</string> <string name="menu_video_options_quality" formatted="true">Càileachd (%1$s)</string>
<string name="account_bottom_menu_videos">Videothan</string> <string name="account_bottom_menu_videos">Videothan</string>
<string name="account_bottom_menu_channels">Seanailean</string> <string name="account_bottom_menu_channels">Seanailean</string>
<string name="account_bottom_menu_about">Mu dhèidhinn</string> <string name="account_bottom_menu_about">Mu dhèidhinn</string>

View File

@ -286,8 +286,8 @@
<string name="video_meta_button_license">Licenza</string> <string name="video_meta_button_license">Licenza</string>
<string name="video_meta_button_language">Lingua</string> <string name="video_meta_button_language">Lingua</string>
<string name="video_meta_button_tags">Parole chiave</string> <string name="video_meta_button_tags">Parole chiave</string>
<string name="menu_video_options_playback_speed">Velocità di riproduzione</string> <string name="menu_video_options_playback_speed" formatted="true">Velocità di riproduzione (%1$s)</string>
<string name="menu_video_options_quality">Qualità</string> <string name="menu_video_options_quality" formatted="true">Qualità (%1$s)</string>
<string name="account_bottom_menu_videos">Video</string> <string name="account_bottom_menu_videos">Video</string>
<string name="account_bottom_menu_channels">Canali</string> <string name="account_bottom_menu_channels">Canali</string>
<string name="account_bottom_menu_about">A proposito</string> <string name="account_bottom_menu_about">A proposito</string>

View File

@ -88,8 +88,8 @@
<string name="video_meta_button_license">ラインセンス</string> <string name="video_meta_button_license">ラインセンス</string>
<string name="video_meta_button_language">言語</string> <string name="video_meta_button_language">言語</string>
<string name="video_meta_button_tags">タグ</string> <string name="video_meta_button_tags">タグ</string>
<string name="menu_video_options_playback_speed">再生速度</string> <string name="menu_video_options_playback_speed" formatted="true">再生速度 (%1$s)</string>
<string name="menu_video_options_quality">クオリティ</string> <string name="menu_video_options_quality" formatted="true">クオリティ(%1$s)</string>
<string name="account_bottom_menu_videos">ビデオ</string> <string name="account_bottom_menu_videos">ビデオ</string>
<string name="account_bottom_menu_channels">チャンネル</string> <string name="account_bottom_menu_channels">チャンネル</string>
<string name="account_bottom_menu_about">情報</string> <string name="account_bottom_menu_about">情報</string>

View File

@ -51,8 +51,8 @@
<string name="video_meta_button_license">Lisens</string> <string name="video_meta_button_license">Lisens</string>
<string name="video_meta_button_language">Språk</string> <string name="video_meta_button_language">Språk</string>
<string name="video_meta_button_tags">Etiketter</string> <string name="video_meta_button_tags">Etiketter</string>
<string name="menu_video_options_playback_speed">Avspillingshastighet</string> <string name="menu_video_options_playback_speed" formatted="true">Avspillingshastighet (%1$s)</string>
<string name="menu_video_options_quality">Kvalitet</string> <string name="menu_video_options_quality" formatted="true">Kvalitet (%1$s)</string>
<string name="account_bottom_menu_videos">Videoer</string> <string name="account_bottom_menu_videos">Videoer</string>
<string name="account_bottom_menu_channels">Kanaler</string> <string name="account_bottom_menu_channels">Kanaler</string>
<string name="account_bottom_menu_about">Om</string> <string name="account_bottom_menu_about">Om</string>

View File

@ -275,8 +275,8 @@
<string name="video_meta_button_license">Licentie</string> <string name="video_meta_button_license">Licentie</string>
<string name="video_meta_button_language">Taal</string> <string name="video_meta_button_language">Taal</string>
<string name="video_meta_button_tags">Labels</string> <string name="video_meta_button_tags">Labels</string>
<string name="menu_video_options_playback_speed">Afspeelsnelheid</string> <string name="menu_video_options_playback_speed" formatted="true">Afspeelsnelheid (%1$s)</string>
<string name="menu_video_options_quality">Kwaliteit</string> <string name="menu_video_options_quality" formatted="true">Kwaliteit (%1$s)</string>
<string name="account_bottom_menu_videos">Video\'s</string> <string name="account_bottom_menu_videos">Video\'s</string>
<string name="account_bottom_menu_channels">Kanalen</string> <string name="account_bottom_menu_channels">Kanalen</string>
<string name="account_bottom_menu_about">Over</string> <string name="account_bottom_menu_about">Over</string>

View File

@ -48,8 +48,8 @@
<string name="account_about_account">Konto:</string> <string name="account_about_account">Konto:</string>
<string name="account_bottom_menu_channels">Kanały</string> <string name="account_bottom_menu_channels">Kanały</string>
<string name="account_bottom_menu_videos">Filmy</string> <string name="account_bottom_menu_videos">Filmy</string>
<string name="menu_video_options_quality">Jakość</string> <string name="menu_video_options_quality" formatted="true">Jakość (%1$s)</string>
<string name="menu_video_options_playback_speed">Prędkość odtwarzania</string> <string name="menu_video_options_playback_speed" formatted="true">Prędkość odtwarzania (%1$s)</string>
<string name="video_meta_button_tags">Znaczniki</string> <string name="video_meta_button_tags">Znaczniki</string>
<string name="video_meta_button_language">Język</string> <string name="video_meta_button_language">Język</string>
<string name="video_meta_button_license">Licencja</string> <string name="video_meta_button_license">Licencja</string>

View File

@ -277,8 +277,8 @@
<string name="video_meta_button_license">Лицензия</string> <string name="video_meta_button_license">Лицензия</string>
<string name="video_meta_button_language">Язык</string> <string name="video_meta_button_language">Язык</string>
<string name="video_meta_button_tags">Теги</string> <string name="video_meta_button_tags">Теги</string>
<string name="menu_video_options_playback_speed">Скорость воспроизведения</string> <string name="menu_video_options_playback_speed" formatted="true">Скорость воспроизведения (%1$s)</string>
<string name="menu_video_options_quality">Качество</string> <string name="menu_video_options_quality" formatted="true">Качество (%1$s)</string>
<string name="account_about_description">Описание:</string> <string name="account_about_description">Описание:</string>
<string name="api_error">Что-то пошло не так, пожалуйста, попробуйте позже!</string> <string name="api_error">Что-то пошло не так, пожалуйста, попробуйте позже!</string>
<string name="action_set_url">Выберите сервер</string> <string name="action_set_url">Выберите сервер</string>

View File

@ -272,8 +272,8 @@
<string name="video_meta_button_license">Licens</string> <string name="video_meta_button_license">Licens</string>
<string name="video_meta_button_language">Språk</string> <string name="video_meta_button_language">Språk</string>
<string name="video_meta_button_tags">Taggar</string> <string name="video_meta_button_tags">Taggar</string>
<string name="menu_video_options_playback_speed">Uppspelningshastighet</string> <string name="menu_video_options_playback_speed" formatted="true">Uppspelningshastighet (%1$s)</string>
<string name="menu_video_options_quality">Kvalitet</string> <string name="menu_video_options_quality" formatted="true">Kvalitet (%1$s)</string>
<string name="account_bottom_menu_videos">Videor</string> <string name="account_bottom_menu_videos">Videor</string>
<string name="account_bottom_menu_channels">Kanaler</string> <string name="account_bottom_menu_channels">Kanaler</string>
<string name="account_bottom_menu_about">Om</string> <string name="account_bottom_menu_about">Om</string>

View File

@ -291,8 +291,8 @@
<string name="video_meta_button_license">Lisans</string> <string name="video_meta_button_license">Lisans</string>
<string name="video_meta_button_language">Dil</string> <string name="video_meta_button_language">Dil</string>
<string name="video_meta_button_tags">Etiketler</string> <string name="video_meta_button_tags">Etiketler</string>
<string name="menu_video_options_playback_speed">Oynatma hızı</string> <string name="menu_video_options_playback_speed" formatted="true">Oynatma hızı (%1$s)</string>
<string name="menu_video_options_quality">Kalite</string> <string name="menu_video_options_quality" formatted="true">Kalite (%1$s)</string>
<!-- Constants, Don't translate --> <!-- Constants, Don't translate -->
<string name="action_bar_title_account">Hesap</string> <string name="action_bar_title_account">Hesap</string>
<string name="bottom_nav_title_recent">Yeniler</string> <string name="bottom_nav_title_recent">Yeniler</string>
@ -342,7 +342,7 @@
<string name="settings_activity_video_list_category_title">Video Listesi</string> <string name="settings_activity_video_list_category_title">Video Listesi</string>
<string name="title_activity_settings2">SettingsActivity2</string> <string name="title_activity_settings2">SettingsActivity2</string>
<string name="title_activity_me">Hesap</string> <string name="title_activity_me">Hesap</string>
<string name="title_activity_select_server">Sunucu Seç</string> <string name="title_activity_select_server">Sunucu Ara</string>
<string name="server_book_del_alert_msg">Bu sunucuyu adres defterinden kaldırmak istediğinizden emin misiniz\?</string> <string name="server_book_del_alert_msg">Bu sunucuyu adres defterinden kaldırmak istediğinizden emin misiniz\?</string>
<string name="server_book_del_alert_title">Sunucuyu Kaldır</string> <string name="server_book_del_alert_title">Sunucuyu Kaldır</string>
<string name="bn_rBD">Bengalce (Bangladeş)</string> <string name="bn_rBD">Bengalce (Bangladeş)</string>
@ -353,4 +353,7 @@
<string name="pref_background_behavior">Arka planda oynatma yapılandırması</string> <string name="pref_background_behavior">Arka planda oynatma yapılandırması</string>
<string name="pref_background_stop">Tüm oynatmaları durdur</string> <string name="pref_background_stop">Tüm oynatmaları durdur</string>
<string name="pref_background_audio">Arka planda ses akışı olarak devam et</string> <string name="pref_background_audio">Arka planda ses akışı olarak devam et</string>
<string name="server_selection_nsfw_instance">İş Yeri İçin Uygun Olmayan (NSFW) Örnek</string>
<string name="server_selection_video_totals">Video: %s, Yerel Video: %s</string>
<string name="menu_video_options_quality_automated">Otomatik</string>
</resources> </resources>

View File

@ -112,8 +112,8 @@
<string name="video_meta_button_category">类别</string> <string name="video_meta_button_category">类别</string>
<string name="video_meta_button_license">许可</string> <string name="video_meta_button_license">许可</string>
<string name="video_meta_button_tags">标签</string> <string name="video_meta_button_tags">标签</string>
<string name="menu_video_options_playback_speed">播放速度</string> <string name="menu_video_options_playback_speed" formatted="true">播放速度 (%1$s)</string>
<string name="menu_video_options_quality">画质</string> <string name="menu_video_options_quality" formatted="true">画质 (%1$s)</string>
<string name="account_bottom_menu_videos">视频</string> <string name="account_bottom_menu_videos">视频</string>
<string name="account_bottom_menu_channels">频道</string> <string name="account_bottom_menu_channels">频道</string>
<string name="account_bottom_menu_about">关于</string> <string name="account_bottom_menu_about">关于</string>

View File

@ -279,8 +279,8 @@
<string name="video_meta_button_license">授權條款</string> <string name="video_meta_button_license">授權條款</string>
<string name="video_meta_button_language">語言</string> <string name="video_meta_button_language">語言</string>
<string name="video_meta_button_tags">標籤</string> <string name="video_meta_button_tags">標籤</string>
<string name="menu_video_options_playback_speed">播放速度</string> <string name="menu_video_options_playback_speed" formatted="true">播放速度 (%1$s)</string>
<string name="menu_video_options_quality">畫質</string> <string name="menu_video_options_quality" formatted="true">畫質 (%1$s)</string>
<string name="account_bottom_menu_videos">影片</string> <string name="account_bottom_menu_videos">影片</string>
<string name="account_bottom_menu_channels">頻道</string> <string name="account_bottom_menu_channels">頻道</string>
<string name="account_bottom_menu_about">關於</string> <string name="account_bottom_menu_about">關於</string>
@ -339,4 +339,6 @@
<string name="pref_background_float">繼續以懸浮視窗播放影片</string> <string name="pref_background_float">繼續以懸浮視窗播放影片</string>
<string name="pref_background_stop">停止所有播放</string> <string name="pref_background_stop">停止所有播放</string>
<string name="pref_background_audio">以背景音訊串流繼續</string> <string name="pref_background_audio">以背景音訊串流繼續</string>
<string name="server_selection_video_totals">影片:%s本地影片%s</string>
<string name="server_selection_nsfw_instance">NSFW 站臺</string>
</resources> </resources>

View File

@ -1,6 +1,64 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" translatable="false">Thorium</string>
<!-- Prefs Settings-->
<string name="pref_language_app_key" translatable="false">pref_language_app</string>
<string name="pref_theme_key" translatable="false">pref_theme</string>
<string name="pref_dark_mode_key" translatable="false">pref_dark_mode</string>
<string name="pref_show_nsfw_key" translatable="false">pref_show_nsfw</string>
<string name="pref_video_language_key" translatable="false">pref_language</string>
<string name="pref_back_pause_key" translatable="false">pref_back_pause</string>
<string name="pref_background_behavior_key" translatable="false">pref_background_behavior</string>
<string name="pref_torrent_player_key" translatable="false">pref_torrent_player</string>
<!-- defaults -->
<string name="pref_default_api_base_url" formatted="false" translatable="false">https://troll.tv</string>
<string name="app_default_theme" translatable="false">AppTheme.BLUE</string>
<!-- Pref internal -->
<string name="pref_token_access" translatable="false">pref_token_access</string>
<string name="pref_token_refresh" translatable="false">pref_token_refresh</string>
<string name="pref_token_expiration" translatable="false">pref_token_expiration</string>
<string name="pref_token_type" translatable="false">pref_token_type</string>
<string name="pref_auth_username" translatable="false">pref_auth_username</string>
<string name="pref_auth_password" translatable="false">pref_auth_password</string>
<string name="pref_api_base_key" translatable="false">pref_api_base</string>
<string name="pref_quality_key" translatable="false">pref_quality</string>
<!-- Pref internal keys -->
<string name="pref_background_audio_key" translatable="false">backgroundAudio</string>
<string name="pref_background_stop_key" translatable="false">backgroundStop</string>
<string name="pref_background_float_key" translatable="false">backgroundFloat</string>
<string name="peertube_required_server_version" translatable="false">1.0.0-alpha.7</string>
<string name="app_background_audio" translatable="false">BACKGROUND_AUDIO</string>
<string name="video_option_speed_icon" translatable="false">{faw-play-circle}</string>
<string name="video_option_quality_icon" translatable="false">{faw-cog}</string>
<string name="video_speed_active_icon" translatable="false">{faw-check}</string>
<string name="video_quality_active_icon" translatable="false">{faw-check}</string>
<string name="video_expand_icon" translatable="false">{faw-expand}</string>
<string name="video_compress_icon" translatable="false">{faw-compress}</string>
<string name="video_more_icon" translatable="false">{faw-ellipsis-v}</string>
<string name="video_thumbs_up_icon" translatable="false">{faw-thumbs-up}</string>
<string name="video_thumbs_down_icon" translatable="false">{faw-thumbs-down}</string>
<string name="video_share_icon" translatable="false">{faw-share}</string>
<string name="video_download_icon" translatable="false">{faw-download}</string>
<string name="video_save_icon" translatable="false">{faw-save}</string>
<string name="meta_data_owner_seperator" translatable="false">\@</string>
<string name="meta_data_seperator" translatable="false">\u0020-\u0020</string>
<string name="title_activity_video_play" translatable="false">VideoPlayActivity</string>
<string name="playback_channel_name" translatable="false">PeerTube</string>
<string name="peertube_instance_search_default_description" translatable="false">PeerTube, a federated (ActivityPub) video streaming platform using P2P (BitTorrent) directly in the web browser with WebTorrent and Angular.</string>
<string-array name="backgroundBehavior"> <string-array name="backgroundBehavior">
<item>@string/pref_background_audio</item> <item>@string/pref_background_audio</item>
@ -9,9 +67,9 @@
</string-array> </string-array>
<string-array name="backgroundBehaviorValues"> <string-array name="backgroundBehaviorValues">
<item>backgroundAudio</item> <item>@string/pref_background_audio_key</item>
<item>backgroundStop</item> <item>@string/pref_background_stop_key</item>
<item>backgroundFloat</item> <item>@string/pref_background_float_key</item>
</string-array> </string-array>
<string-array name="themeArray"> <string-array name="themeArray">
@ -475,7 +533,7 @@
<item>zh-rTW</item> <item>zh-rTW</item>
</string-array> </string-array>
<string-array name = "supportedLanguagesArray"> <string-array name="supportedLanguagesArray">
<item>@string/ar</item> <item>@string/ar</item>
<item>@string/bn</item> <item>@string/bn</item>
<item>@string/bn_rBD</item> <item>@string/bn_rBD</item>
@ -502,7 +560,7 @@
</string-array> </string-array>
<string-array name="empty_array"/> <string-array name="empty_array" />
<string-array name="quality"> <string-array name="quality">
<item>Low</item> <item>Low</item>

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" translatable="false">Thorium</string>
<string name="title_activity_video_play" translatable="false">VideoPlayActivity</string>
<string name="title_activity_settings">Settings</string> <string name="title_activity_settings">Settings</string>
<string name="title_activity_login">Sign in</string> <string name="title_activity_login">Sign in</string>
<!-- Strings related to login --> <!-- Strings related to login -->
@ -29,9 +28,7 @@
<string name="bottom_nav_title_account">Account</string> <string name="bottom_nav_title_account">Account</string>
<!-- Strings related to Settings --> <!-- Strings related to Settings -->
<!-- Strings related to Video meta data --> <!-- Strings related to Video meta data -->
<string name="meta_data_seperator" translatable="false">\u0020-\u0020</string>
<string name="meta_data_views">\u0020Views</string> <string name="meta_data_views">\u0020Views</string>
<string name="meta_data_owner_seperator" translatable="false">\@</string>
<string name="video_row_video_thumbnail">Video Thumbnail</string> <string name="video_row_video_thumbnail">Video Thumbnail</string>
<string name="video_row_account_avatar">Account Avatar</string> <string name="video_row_account_avatar">Account Avatar</string>
<string name="title_activity_url_video_play">UrlVideoPlayActivity</string> <string name="title_activity_url_video_play">UrlVideoPlayActivity</string>
@ -40,7 +37,6 @@
<string name="no_data_available">No Results</string> <string name="no_data_available">No Results</string>
<string name="descr_overflow_button">More</string> <string name="descr_overflow_button">More</string>
<string name="menu_share">Share</string> <string name="menu_share">Share</string>
<string name="playback_channel_name" translatable="false">PeerTube</string>
<string name="invalid_url">Invalid URL.</string> <string name="invalid_url">Invalid URL.</string>
<!-- settings/preferences --> <!-- settings/preferences -->
<string name="pref_title_dark_mode">Dark Mode</string> <string name="pref_title_dark_mode">Dark Mode</string>
@ -56,7 +52,6 @@
<string name="pref_description_show_nsfw">Show NSFW content</string> <string name="pref_description_show_nsfw">Show NSFW content</string>
<string name="pref_language">Language filter</string> <string name="pref_language">Language filter</string>
<string name="pref_description_language">Select a video language, instead of showing all videos in all languages.</string> <string name="pref_description_language">Select a video language, instead of showing all videos in all languages.</string>
<string name="pref_default_api_base_url" formatted="false" translatable="false">https://troll.tv</string>
<string name="pref_title_peertube_server">PeerTube Server</string> <string name="pref_title_peertube_server">PeerTube Server</string>
<string name="pref_title_background_play">Background Playback</string> <string name="pref_title_background_play">Background Playback</string>
<string name="pref_description_background_play">If enabled, continues to play video in background.</string> <string name="pref_description_background_play">If enabled, continues to play video in background.</string>
@ -292,18 +287,7 @@
<string name="video_speed_10">Normal</string> <string name="video_speed_10">Normal</string>
<string name="video_speed_15">1.5x</string> <string name="video_speed_15">1.5x</string>
<string name="video_speed_20">2x</string> <string name="video_speed_20">2x</string>
<string name="video_option_speed_icon" translatable="false">{faw-play-circle}</string>
<string name="video_option_quality_icon" translatable="false">{faw-cog}</string>
<string name="video_speed_active_icon" translatable="false">{faw-check}</string>
<string name="video_quality_active_icon" translatable="false">{faw-check}</string>
<string name="video_expand_icon" translatable="false">{faw-expand}</string>
<string name="video_compress_icon" translatable="false">{faw-compress}</string>
<string name="video_more_icon" translatable="false">{faw-ellipsis-v}</string>
<string name="video_thumbs_up_icon" translatable="false">{faw-thumbs-up}</string>
<string name="video_thumbs_down_icon" translatable="false">{faw-thumbs-down}</string>
<string name="video_share_icon" translatable="false">{faw-share}</string>
<string name="video_download_icon" translatable="false">{faw-download}</string>
<string name="video_save_icon" translatable="false">{faw-save}</string>
<string name="action_set_url">Select Server</string> <string name="action_set_url">Select Server</string>
<string name="server_selection_signup_allowed">Signup Allowed: %s</string> <string name="server_selection_signup_allowed">Signup Allowed: %s</string>
<string name="server_selection_signup_allowed_yes">Yes</string> <string name="server_selection_signup_allowed_yes">Yes</string>
@ -324,8 +308,8 @@
<string name="video_meta_button_license">License</string> <string name="video_meta_button_license">License</string>
<string name="video_meta_button_language">Language</string> <string name="video_meta_button_language">Language</string>
<string name="video_meta_button_tags">Tags</string> <string name="video_meta_button_tags">Tags</string>
<string name="menu_video_options_playback_speed">Playback speed</string> <string name="menu_video_options_playback_speed" formatted="true">Playback speed (%1$s)</string>
<string name="menu_video_options_quality">Quality</string> <string name="menu_video_options_quality" formatted="true">Quality (%1$s)</string>
<string name="account_bottom_menu_videos">Videos</string> <string name="account_bottom_menu_videos">Videos</string>
<string name="account_bottom_menu_channels">Channels</string> <string name="account_bottom_menu_channels">Channels</string>
<string name="account_bottom_menu_about">About</string> <string name="account_bottom_menu_about">About</string>
@ -352,10 +336,7 @@
<string name="server_book_add_password">Password</string> <string name="server_book_add_password">Password</string>
<string name="server_book_add_add_button">Add</string> <string name="server_book_add_add_button">Add</string>
<string name="server_book_list_has_login">Has Login</string> <string name="server_book_list_has_login">Has Login</string>
<string name="video_rating_none" translatable="false">none</string>
<string name="video_rating_like" translatable="false">like</string>
<string name="video_rating_dislike" translatable="false">dislike</string>
<string name="peertube_required_server_version" translatable="false">1.0.0-alpha.7</string>
<string name="login_current_server_hint">Current Server</string> <string name="login_current_server_hint">Current Server</string>
<string name="title_activity_server_address_book">Address Book</string> <string name="title_activity_server_address_book">Address Book</string>
<string name="video_speed_075">0.75x</string> <string name="video_speed_075">0.75x</string>
@ -363,7 +344,7 @@
<string name="server_book_del_alert_title">Remove Server</string> <string name="server_book_del_alert_title">Remove Server</string>
<string name="server_book_del_alert_msg">Are you sure you want to remove this server from the address book?</string> <string name="server_book_del_alert_msg">Are you sure you want to remove this server from the address book?</string>
<string name="title_activity_select_server">Select Server</string> <string name="title_activity_select_server">Search Server</string>
<string name="title_activity_me">Account</string> <string name="title_activity_me">Account</string>
<string name="title_activity_settings2">SettingsActivity2</string> <string name="title_activity_settings2">SettingsActivity2</string>
@ -372,18 +353,11 @@
<string name="settings_activity_about_category_title">About</string> <string name="settings_activity_about_category_title">About</string>
<string name="settings_activity_look_and_feel_category_title"><![CDATA[Look & Feel]]></string> <string name="settings_activity_look_and_feel_category_title"><![CDATA[Look & Feel]]></string>
<string name="peertube_instance_search_default_description" translatable="false">PeerTube, a federated (ActivityPub) video streaming platform using P2P (BitTorrent) directly in the web browser with WebTorrent and Angular.</string>
<string name="server_selection_nsfw_instance">NSFW Instance</string> <string name="server_selection_nsfw_instance">NSFW Instance</string>
<string name="server_selection_video_totals">Videos: %s, Local Videos: %s</string> <string name="server_selection_video_totals">Videos: %s, Local Videos: %s</string>
<string name="menu_video_options_quality_automated">Automated</string>
<!-- Constants, Don't translate --> <string name="pref_title_buildtime">Build Time</string>
<string name="pref_token_access" translatable="false">pref_token_access</string>
<string name="pref_token_refresh" translatable="false">pref_token_refresh</string>
<string name="pref_token_expiration" translatable="false">pref_token_expiration</string>
<string name="pref_token_type" translatable="false">pref_token_type</string>
<string name="pref_auth_username" translatable="false">pref_auth_username</string>
<string name="pref_auth_password" translatable="false">pref_auth_password</string>
</resources> </resources>

View File

@ -1,78 +0,0 @@
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<!--<SwitchPreference-->
<!--android:key="pref_background_play"-->
<!--android:title="@string/pref_title_background_play"-->
<!--android:summary="@string/pref_description_background_play"-->
<!--android:defaultValue="true" />-->
<SwitchPreference
android:key="pref_show_nsfw"
android:title="@string/pref_title_show_nsfw"
android:summary="@string/pref_description_show_nsfw"
android:defaultValue="false" />
<MultiSelectListPreference
android:defaultValue="@array/empty_array"
android:entries="@array/languageArray"
android:entryValues="@array/languageValues"
android:key="pref_language"
android:summary="@string/pref_description_language"
android:title="@string/pref_language" />
<SwitchPreference
android:defaultValue="true"
android:key="pref_back_pause"
android:summary="@string/pref_description_back_pause"
android:title="@string/pref_title_back_pause" />
<ListPreference
android:defaultValue="@array/empty_array"
android:entries="@array/supportedLanguagesArray"
android:entryValues="@array/supportedLanguagesValues"
android:key="pref_language_app"
android:summary="@string/pref_description_language_app"
android:title="@string/pref_language_app" />
/>
<ListPreference
android:defaultValue="@array/empty_array"
android:entries="@array/backgroundBehavior"
android:entryValues="@array/backgroundBehaviorValues"
android:key="pref_background_behavior"
android:summary="@string/pref_background_behavior_summary"
android:title="@string/pref_background_behavior" />
/>
<ListPreference
android:title="@string/pref_title_app_theme"
android:summary="@string/pref_description_app_theme"
android:key="pref_theme"
android:defaultValue="AppTheme.BLUE"
android:entries="@array/themeArray"
android:entryValues="@array/themeValues" />
<SwitchPreference
android:key="pref_dark_mode"
android:title="@string/pref_title_dark_mode"
android:summary="@string/pref_description_dark_mode"
android:defaultValue="false" />
<SwitchPreference
android:key="pref_torrent_player"
android:title="@string/pref_title_torrent_player"
android:summary="@string/pref_description_torrent_player"
android:defaultValue="false" />
<Preference
android:title="@string/pref_title_version"
android:summary="@string/versionName" />
<Preference
android:title="@string/pref_title_license"
android:summary="@string/pref_description_license" />
</PreferenceScreen>

View File

@ -1,82 +1,98 @@
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"> <PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory app:title="@string/settings_activity_look_and_feel_category_title"> <PreferenceCategory app:title="@string/settings_activity_look_and_feel_category_title" app:iconSpaceReserved="false">
<ListPreference <ListPreference
app:defaultValue="@array/empty_array" app:defaultValue="@array/empty_array"
app:entries="@array/supportedLanguagesArray" app:entries="@array/supportedLanguagesArray"
app:entryValues="@array/supportedLanguagesValues" app:entryValues="@array/supportedLanguagesValues"
app:key="pref_language_app" app:key="@string/pref_language_app_key"
app:summary="@string/pref_description_language_app" app:summary="@string/pref_description_language_app"
app:title="@string/pref_language_app" /> app:title="@string/pref_language_app"
app:iconSpaceReserved="false"/>
<ListPreference <ListPreference
app:defaultValue="AppTheme.BLUE" app:defaultValue="AppTheme.BLUE"
app:entries="@array/themeArray" app:entries="@array/themeArray"
app:entryValues="@array/themeValues" app:entryValues="@array/themeValues"
app:key="pref_theme" app:key="@string/pref_theme_key"
app:summary="@string/pref_description_app_theme" app:summary="@string/pref_description_app_theme"
app:title="@string/pref_title_app_theme" /> app:title="@string/pref_title_app_theme"
app:iconSpaceReserved="false"/>
<SwitchPreference <SwitchPreference
app:defaultValue="false" app:defaultValue="false"
app:key="pref_dark_mode" app:key="@string/pref_dark_mode_key"
app:summary="@string/pref_description_dark_mode" app:summary="@string/pref_description_dark_mode"
app:title="@string/pref_title_dark_mode" /> app:title="@string/pref_title_dark_mode"
app:iconSpaceReserved="false"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory app:title="@string/settings_activity_video_list_category_title"> <PreferenceCategory app:title="@string/settings_activity_video_list_category_title" app:iconSpaceReserved="false">
<SwitchPreference <SwitchPreference
app:defaultValue="false" app:defaultValue="false"
app:key="pref_show_nsfw" app:key="@string/pref_show_nsfw_key"
app:summary="@string/pref_description_show_nsfw" app:summary="@string/pref_description_show_nsfw"
app:title="@string/pref_title_show_nsfw" /> app:title="@string/pref_title_show_nsfw"
app:iconSpaceReserved="false"/>
<MultiSelectListPreference <MultiSelectListPreference
app:defaultValue="@array/empty_array" app:defaultValue="@array/empty_array"
app:entries="@array/languageArray" app:entries="@array/languageArray"
app:entryValues="@array/languageValues" app:entryValues="@array/languageValues"
app:key="pref_language" app:key="@string/pref_video_language_key"
app:summary="@string/pref_description_language" app:summary="@string/pref_description_language"
app:title="@string/pref_language" /> app:title="@string/pref_language"
app:iconSpaceReserved="false"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory app:title="@string/settings_activity_video_playback_category_title"> <PreferenceCategory app:title="@string/settings_activity_video_playback_category_title" app:iconSpaceReserved="false">
<SwitchPreference <SwitchPreference
app:defaultValue="true" app:defaultValue="true"
app:key="pref_back_pause" app:key="@string/pref_back_pause_key"
app:summary="@string/pref_description_back_pause" app:summary="@string/pref_description_back_pause"
app:title="@string/pref_title_back_pause" /> app:title="@string/pref_title_back_pause"
app:iconSpaceReserved="false"/>
<ListPreference <ListPreference
app:defaultValue="@array/empty_array" app:defaultValue="@array/empty_array"
app:entries="@array/backgroundBehavior" app:entries="@array/backgroundBehavior"
app:entryValues="@array/backgroundBehaviorValues" app:entryValues="@array/backgroundBehaviorValues"
app:key="pref_background_behavior" app:key="@string/pref_background_behavior_key"
app:summary="@string/pref_background_behavior_summary" app:summary="@string/pref_background_behavior_summary"
app:title="@string/pref_background_behavior" /> app:title="@string/pref_background_behavior"
app:iconSpaceReserved="false"/>
<SwitchPreference <SwitchPreference
app:defaultValue="false" app:defaultValue="false"
app:key="pref_torrent_player" app:key="@string/pref_torrent_player_key"
app:summary="@string/pref_description_torrent_player" app:summary="@string/pref_description_torrent_player"
app:title="@string/pref_title_torrent_player" /> app:title="@string/pref_title_torrent_player"
app:iconSpaceReserved="false"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory app:title="@string/settings_activity_about_category_title"> <PreferenceCategory app:title="@string/settings_activity_about_category_title" app:iconSpaceReserved="false">
<Preference <Preference
app:summary="@string/versionName" app:summary="@string/versionName"
app:title="@string/pref_title_version" /> app:title="@string/pref_title_version"
app:iconSpaceReserved="false"/>
<Preference
app:summary="@string/buildTime"
app:title="@string/pref_title_buildtime"
app:iconSpaceReserved="false"/>
<Preference <Preference
app:summary="@string/pref_description_license" app:summary="@string/pref_description_license"
app:title="@string/pref_title_license" /> app:title="@string/pref_title_license"
app:iconSpaceReserved="false"/>
</PreferenceCategory> </PreferenceCategory>