Merge branch 'master' into 'develop'

Master

See merge request sschueller/peertube!8
This commit is contained in:
Stefan Schüller 2020-11-22 16:22:07 +01:00
commit 1467abe70c
32 changed files with 270 additions and 26 deletions

View File

@ -5,11 +5,12 @@
3. Pull github develop 3. Pull github develop
4. Pull weblate develop 4. Pull weblate develop
5. Add change logs (fastlane/metadata/android/en-US/changelogs/XXX.txt) 5. Add change logs (fastlane/metadata/android/en-US/changelogs/XXX.txt)
6. Push to gitlab and github 6. Run ci-script/update-changelog.sh
7. Merge request into master and merge 7. Push to gitlab
8. Add Release Tag on master branch 8. Merge request into master and merge
9. Release to play store 9. Add Release Tag on master branch
10. Wait for gitlab -> github sync 10. Release to play store
11. Run publishGithub 11. Wait for gitlab -> github sync
12. Run publishGithub

View File

@ -93,6 +93,7 @@ android {
implementation "com.google.android.exoplayer:exoplayer-hls:$libVersions.exoplayer" implementation "com.google.android.exoplayer:exoplayer-hls:$libVersions.exoplayer"
implementation "com.google.android.exoplayer:exoplayer-smoothstreaming:$libVersions.exoplayer" implementation "com.google.android.exoplayer:exoplayer-smoothstreaming:$libVersions.exoplayer"
implementation "com.google.android.exoplayer:extension-mediasession:$libVersions.exoplayer" implementation "com.google.android.exoplayer:extension-mediasession:$libVersions.exoplayer"
implementation "com.google.android.exoplayer:extension-okhttp:$libVersions.exoplayer"
// date formatter // date formatter
implementation 'org.ocpsoft.prettytime:prettytime:4.0.4.Final' implementation 'org.ocpsoft.prettytime:prettytime:4.0.4.Final'

View File

@ -97,7 +97,7 @@ public class AccountActivity extends CommonActivity {
apiBaseURL = APIUrlHelper.getUrlWithVersion(this); apiBaseURL = APIUrlHelper.getUrlWithVersion(this);
userService = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetUserService.class); userService = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(this)).create(GetUserService.class);
recyclerViewVideos = findViewById(R.id.account_video_recyclerView); recyclerViewVideos = findViewById(R.id.account_video_recyclerView);
recyclerViewChannels = findViewById(R.id.account_channel_recyclerView); recyclerViewChannels = findViewById(R.id.account_channel_recyclerView);
@ -227,7 +227,7 @@ public class AccountActivity extends CommonActivity {
isLoadingVideos = false; isLoadingVideos = false;
GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class); GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(this)).create(GetVideoDataService.class);
Call<VideoList> call; Call<VideoList> call;
call = service.getAccountVideosData(displayNameAndHost, videosStart, videosCount, videosSort); call = service.getAccountVideosData(displayNameAndHost, videosStart, videosCount, videosSort);

View File

@ -119,7 +119,7 @@ public class MeActivity extends CommonActivity {
String apiBaseURL = APIUrlHelper.getUrlWithVersion(this); String apiBaseURL = APIUrlHelper.getUrlWithVersion(this);
String baseURL = APIUrlHelper.getUrl(this); String baseURL = APIUrlHelper.getUrl(this);
GetUserService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetUserService.class); GetUserService service = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(this)).create(GetUserService.class);
Call<Me> call = service.getMe(); Call<Me> call = service.getMe();

View File

@ -148,7 +148,7 @@ public class SearchServerActivity extends CommonActivity {
GetServerListDataService service = RetrofitInstance.getRetrofitInstance( GetServerListDataService service = RetrofitInstance.getRetrofitInstance(
APIUrlHelper.getServerIndexUrl(SearchServerActivity.this) APIUrlHelper.getServerIndexUrl(SearchServerActivity.this)
).create(GetServerListDataService.class); , APIUrlHelper.useInsecureConnection(this)).create(GetServerListDataService.class);
if ( !searchtext.equals( lastSearchtext ) ) if ( !searchtext.equals( lastSearchtext ) )
{ {

View File

@ -17,14 +17,18 @@
*/ */
package net.schueller.peertube.activity; package net.schueller.peertube.activity;
import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.view.View; import android.preference.PreferenceManager;
import android.util.Log;
import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog.Builder;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.SwitchPreference;
import net.schueller.peertube.BuildConfig; import net.schueller.peertube.BuildConfig;
import net.schueller.peertube.R; import net.schueller.peertube.R;
@ -68,6 +72,43 @@ public class SettingsActivity extends CommonActivity {
assert pref != null; assert pref != null;
pref.setSummary(Long.toString(BuildConfig.BUILD_TIME)); pref.setSummary(Long.toString(BuildConfig.BUILD_TIME));
// double check disabling SSL
final SwitchPreference insecure = (SwitchPreference) findPreference("pref_accept_insecure");
if (insecure != null) {
insecure.setOnPreferenceChangeListener((preference, newValue) -> {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getContext());
SharedPreferences.Editor editor = sharedPref.edit();
boolean currentValue = sharedPref.getBoolean("pref_accept_insecure", false);
if (newValue instanceof Boolean && ((Boolean) newValue) != currentValue) {
final boolean enable = (Boolean) newValue;
Log.v("pref", "enable: " + enable);
Log.v("pref", "currentValue: " + currentValue);
if (enable) {
new Builder(preference.getContext())
.setTitle(R.string.pref_insecure_confirm_title)
.setMessage(R.string.pref_insecure_confirm_message)
.setIcon(R.drawable.ic_info_black_24dp)
.setNegativeButton(R.string.pref_insecure_confirm_no, (dialog, whichButton) -> {
// do nothing
})
.setPositiveButton(R.string.pref_insecure_confirm_yes, (dialog, whichButton) -> {
// OK has been pressed => force the new value and update the checkbox display
editor.putBoolean("pref_accept_insecure", true);
editor.apply();
insecure.setChecked(true);
}).create().show();
// by default ignore the pref change, which can only be validated when OK is pressed
return false;
}
}
return true;
});
}
} }
} }
} }

View File

@ -325,13 +325,13 @@ public class VideoListActivity extends CommonActivity {
Set<String> languages = sharedPref.getStringSet(getString(R.string.pref_video_language_key), 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, APIUrlHelper.useInsecureConnection(this)).create(GetVideoDataService.class);
Call<VideoList> call; Call<VideoList> call;
if (!searchQuery.equals("")) { if (!searchQuery.equals("")) {
call = service.searchVideosData(start, count, sort, nsfw, searchQuery, filter, languages); call = service.searchVideosData(start, count, sort, nsfw, searchQuery, filter, languages);
} else if (subscriptions) { } else if (subscriptions) {
GetUserService userService = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetUserService.class); GetUserService userService = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(this)).create(GetUserService.class);
call = userService.getVideosSubscripions(start, count, sort); call = userService.getVideosSubscripions(start, count, sort);
} else { } else {
call = service.getVideosData(start, count, sort, nsfw, filter, languages); call = service.getVideosData(start, count, sort, nsfw, filter, languages);

View File

@ -100,7 +100,7 @@ public class VideoMetaDataFragment extends Fragment {
Activity activity = getActivity(); Activity activity = getActivity();
String apiBaseURL = APIUrlHelper.getUrlWithVersion(context); String apiBaseURL = APIUrlHelper.getUrlWithVersion(context);
GetVideoDataService videoDataService = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class); GetVideoDataService videoDataService = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(context)).create(GetVideoDataService.class);
// Thumbs up // Thumbs up
Button thumbsUpButton = activity.findViewById(R.id.video_thumbs_up); Button thumbsUpButton = activity.findViewById(R.id.video_thumbs_up);
@ -326,7 +326,7 @@ public class VideoMetaDataFragment extends Fragment {
RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json"), "{\"rating\":\"" + ratePayload + "\"}"); RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json"), "{\"rating\":\"" + ratePayload + "\"}");
String apiBaseURL = APIUrlHelper.getUrlWithVersion(getContext()); String apiBaseURL = APIUrlHelper.getUrlWithVersion(getContext());
GetVideoDataService videoDataService = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class); GetVideoDataService videoDataService = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(getContext())).create(GetVideoDataService.class);
Call<ResponseBody> call = videoDataService.rateVideo(video.getId(), body); Call<ResponseBody> call = videoDataService.rateVideo(video.getId(), body);

View File

@ -184,7 +184,7 @@ public class VideoPlayerFragment extends Fragment implements VideoRendererEventL
// get video details from api // get video details from api
String apiBaseURL = APIUrlHelper.getUrlWithVersion(context); String apiBaseURL = APIUrlHelper.getUrlWithVersion(context);
GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(GetVideoDataService.class); GetVideoDataService service = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(context)).create(GetVideoDataService.class);
Call<Video> call = service.getVideoData(mVideoUuid); Call<Video> call = service.getVideoData(mVideoUuid);

View File

@ -43,6 +43,11 @@ public class APIUrlHelper{
return APIUrlHelper.getUrl(context) + "/api/v1/"; return APIUrlHelper.getUrl(context) + "/api/v1/";
} }
public static Boolean useInsecureConnection(Context context) {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
return sharedPref.getBoolean(context.getString(R.string.pref_accept_insecure), false);
}
public static String getShareUrl(Context context, String videoUuid) { public static String getShareUrl(Context context, String videoUuid) {
return APIUrlHelper.getUrl(context) + "/videos/watch/" + videoUuid; return APIUrlHelper.getUrl(context) + "/videos/watch/" + videoUuid;
} }

View File

@ -17,6 +17,11 @@
*/ */
package net.schueller.peertube.network; package net.schueller.peertube.network;
import static net.schueller.peertube.network.UnsafeOkHttpClient.getUnsafeOkHttpClientBuilder;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import net.schueller.peertube.R;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import retrofit2.Retrofit; import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.converter.gson.GsonConverterFactory;
@ -26,11 +31,17 @@ public class RetrofitInstance {
private static Retrofit retrofit; private static Retrofit retrofit;
private static String baseUrl; private static String baseUrl;
public static Retrofit getRetrofitInstance(String newBaseUrl) { public static Retrofit getRetrofitInstance(String newBaseUrl, boolean insecure) {
if (retrofit == null || !newBaseUrl.equals(baseUrl)) { if (retrofit == null || !newBaseUrl.equals(baseUrl)) {
baseUrl = newBaseUrl; baseUrl = newBaseUrl;
OkHttpClient.Builder okhttpClientBuilder = new OkHttpClient.Builder(); OkHttpClient.Builder okhttpClientBuilder;
if (!insecure) {
okhttpClientBuilder = new OkHttpClient.Builder();
} else {
okhttpClientBuilder = getUnsafeOkHttpClientBuilder();
}
okhttpClientBuilder.addInterceptor(new AuthorizationInterceptor()); okhttpClientBuilder.addInterceptor(new AuthorizationInterceptor());
okhttpClientBuilder.authenticator(new AccessTokenAuthenticator()); okhttpClientBuilder.authenticator(new AccessTokenAuthenticator());

View File

@ -0,0 +1,68 @@
/*
* 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.network;
import android.annotation.SuppressLint;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import okhttp3.OkHttpClient;
import okhttp3.OkHttpClient.Builder;
// Take from https://stackoverflow.com/questions/25509296/trusting-all-certificates-with-okhttp/25992879#25992879
public class UnsafeOkHttpClient {
public static Builder getUnsafeOkHttpClientBuilder() {
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
@SuppressLint("TrustAllX509TrustManager")
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}
@SuppressLint("TrustAllX509TrustManager")
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]);
builder.hostnameVerifier((hostname, session) -> true);
return builder;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@ -50,7 +50,7 @@ public class LoginService {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context);
AuthenticationService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(AuthenticationService.class); AuthenticationService service = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(context)).create(AuthenticationService.class);
Call<OauthClient> call = service.getOauthClientLocal(); Call<OauthClient> call = service.getOauthClientLocal();
@ -134,7 +134,7 @@ public class LoginService {
String apiBaseURL = APIUrlHelper.getUrlWithVersion(context); String apiBaseURL = APIUrlHelper.getUrlWithVersion(context);
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
AuthenticationService service = RetrofitInstance.getRetrofitInstance(apiBaseURL).create(AuthenticationService.class); AuthenticationService service = RetrofitInstance.getRetrofitInstance(apiBaseURL, APIUrlHelper.useInsecureConnection(context)).create(AuthenticationService.class);
String refreshToken = sharedPreferences.getString(AppApplication.getContext().getString(R.string.pref_token_refresh), null); String refreshToken = sharedPreferences.getString(AppApplication.getContext().getString(R.string.pref_token_refresh), null);
String userName = sharedPreferences.getString(AppApplication.getContext().getString(R.string.pref_auth_username), null); String userName = sharedPreferences.getString(AppApplication.getContext().getString(R.string.pref_auth_username), null);

View File

@ -51,6 +51,8 @@ import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.audio.AudioAttributes; import com.google.android.exoplayer2.audio.AudioAttributes;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector; import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator; import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator;
import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSource;
import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSourceFactory;
import com.google.android.exoplayer2.source.ExtractorMediaSource; import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.ui.PlayerNotificationManager; import com.google.android.exoplayer2.ui.PlayerNotificationManager;
@ -60,13 +62,16 @@ import com.google.android.exoplayer2.util.Util;
import net.schueller.peertube.R; import net.schueller.peertube.R;
import net.schueller.peertube.activity.VideoPlayActivity; import net.schueller.peertube.activity.VideoPlayActivity;
import net.schueller.peertube.helper.APIUrlHelper;
import net.schueller.peertube.helper.MetaDataHelper; import net.schueller.peertube.helper.MetaDataHelper;
import net.schueller.peertube.model.Video; import net.schueller.peertube.model.Video;
import okhttp3.OkHttpClient;
import static android.media.session.PlaybackState.ACTION_PAUSE; import static android.media.session.PlaybackState.ACTION_PAUSE;
import static android.media.session.PlaybackState.ACTION_PLAY; import static android.media.session.PlaybackState.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.activity.VideoListActivity.EXTRA_VIDEOID; import static net.schueller.peertube.activity.VideoListActivity.EXTRA_VIDEOID;
import static net.schueller.peertube.network.UnsafeOkHttpClient.getUnsafeOkHttpClientBuilder;
public class VideoPlayerService extends Service { public class VideoPlayerService extends Service {
@ -209,8 +214,18 @@ public class VideoPlayerService extends Service {
Log.v(TAG, "playVideo..."); Log.v(TAG, "playVideo...");
// Produces DataSource instances through which media data is loaded. // Produces DataSource instances through which media data is loaded.
DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getApplicationContext(), // DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getApplicationContext(),
Util.getUserAgent(getApplicationContext(), "PeerTube"), null); // Util.getUserAgent(getApplicationContext(), "PeerTube"), null);
OkHttpClient.Builder okhttpClientBuilder;
if (!APIUrlHelper.useInsecureConnection(this)) {
okhttpClientBuilder = new OkHttpClient.Builder();
} else {
okhttpClientBuilder = getUnsafeOkHttpClientBuilder();
}
DataSource.Factory dataSourceFactory = new OkHttpDataSourceFactory(okhttpClientBuilder.build(), Util.getUserAgent(getApplicationContext(), "PeerTube"));
// This is the MediaSource representing the media to be played. // This is the MediaSource representing the media to be played.
ExtractorMediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory) ExtractorMediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory)

View File

@ -15,6 +15,8 @@
<string name="pref_background_behavior_key" translatable="false">pref_background_behavior</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> <string name="pref_torrent_player_key" translatable="false">pref_torrent_player</string>
<string name="pref_accept_insecure" translatable="false">pref_accept_insecure</string>
<!-- defaults --> <!-- defaults -->
<string name="pref_default_api_base_url" formatted="false" translatable="false">https://troll.tv</string> <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> <string name="app_default_theme" translatable="false">AppTheme.BLUE</string>

View File

@ -67,6 +67,8 @@
<string name="pref_background_behavior_summary">How a playing video responds when going to background</string> <string name="pref_background_behavior_summary">How a playing video responds when going to background</string>
<string name="clear_search_history">Clear Search History</string> <string name="clear_search_history">Clear Search History</string>
<string name="clear_search_history_prompt">Do you want to permanently delete the search history?</string> <string name="clear_search_history_prompt">Do you want to permanently delete the search history?</string>
<string name="pref_description_accept_insecure">Ignore insecure connections. Use this only if you know the server you are connecting to. Requires App Restart.</string>
<string name="pref_title_accept_insecure">Disable SSL Certificate Check</string>
<!-- languages --> <!-- languages -->
<string name="ab">Abkhazian</string> <string name="ab">Abkhazian</string>
<string name="aa">Afar</string> <string name="aa">Afar</string>
@ -353,4 +355,9 @@
<string name="pref_title_buildtime">Build Time</string> <string name="pref_title_buildtime">Build Time</string>
<string name="authentication_token_refresh_failed">Could not refresh token</string> <string name="authentication_token_refresh_failed">Could not refresh token</string>
<string name="authentication_token_refresh_success">Token refreshed</string> <string name="authentication_token_refresh_success">Token refreshed</string>
<string name="settings_activity_advanced_category_title">Advanced</string>
<string name="pref_insecure_confirm_title">Warning!</string>
<string name="pref_insecure_confirm_no">No</string>
<string name="pref_insecure_confirm_yes">Yes</string>
<string name="pref_insecure_confirm_message">You are about the disable all SSL Certification validation in Thorium. Disabling this can be very dangerous if the peertube server is not under your control, because a man-in-the-middle attack could direct traffic to another server without your knowledge. An attacker could record passwords and other personal data.</string>
</resources> </resources>

View File

@ -77,6 +77,17 @@
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory app:title="@string/settings_activity_advanced_category_title" app:iconSpaceReserved="false">
<SwitchPreference
app:defaultValue="false"
app:key="@string/pref_accept_insecure"
app:summary="@string/pref_description_accept_insecure"
app:title="@string/pref_title_accept_insecure"
app:iconSpaceReserved="false"/>
</PreferenceCategory>
<PreferenceCategory app:title="@string/settings_activity_about_category_title" app:iconSpaceReserved="false"> <PreferenceCategory app:title="@string/settings_activity_about_category_title" app:iconSpaceReserved="false">
<Preference <Preference

View File

@ -7,7 +7,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.0.1' classpath 'com.android.tools.build:gradle:4.1.1'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
repo="sschueller/easyrepost" repo="sschueller/peertube-android"
username="sschueller" username="sschueller"
# set work dir # set work dir

View File

@ -0,0 +1 @@
- Authentifizierungsaktualisierung

View File

@ -0,0 +1,33 @@
Thorium ist ein PeerTube-Client, der eine Verbindung zu jedem PeerTube-Server mit Version v1.1.0-alpha.2 oder höher herstellen kann.
PeerTube ist eine föderierte (ActivityPub) Video-Streaming-Plattform, die P2P (BitTorrent) direkt im Webbrowser verwendet. Weitere Informationen finden Sie unter https://joinpeertube.org/ und eine Liste von Servern.
Dieser Client wird vorkonfiguriert mit einem PeerTube-Server geliefert, der vom Ersteller der Anwendung verwaltet wird nicht das PeerTube-Projekt selbst, das mehr unter http://instances.joinpeertube.org/ aufgelistet ist , damit Sie einen Vorgeschmack darauf bekommen, wozu der Client in der Lage ist. Wählen Sie Ihren Server, um Ihre Erfahrung zu optimieren!
Aktuelle Merkmale:
- Verbindung zu jedem PeerTube-Server
- Torrent-Video oder direkte Wiedergabe
- PeerTube durchsuchen
- Video herunterladen / weitergeben
- Dunkel-Modus
- Wiedergabe im Hintergrund
- Vollbild-Wiedergabe im Querformat
- Wiedergabegeschwindigkeit
- NSFW-Inhalt filtern
- Authentifizierung / Anmeldung
- Video gefällt mir / gefällt mir nicht
Demnächst:
- Videos kommentieren
- Registrieren
- Benutzer-/Kanal-Übersichtsseite
- Bericht Videos
Genehmigungen:
- Speicherzugang, erforderlich für Torrent-Herunterladen oder Video-Herunterladen.
Lizenziert unter der GNU Affero General Public License v3.0
Genehmigungen dieser stärksten Copyleft-Lizenz sind an die Bedingung geknüpft, den vollständigen Quellcode der lizenzierten Werke und Modifikationen, zu denen auch größere Werke gehören, die ein lizenziertes Werk verwenden, unter der gleichen Lizenz zur Verfügung zu stellen. Urheberrechts- und Lizenzhinweise müssen erhalten bleiben. Mitwirkende stellen eine ausdrückliche Gewährung von Patentrechten zur Verfügung. Wenn eine modifizierte Version verwendet wird, um einen Dienst über ein Netzwerk anzubieten, muss der vollständige Quellcode der modifizierten Version zur Verfügung gestellt werden.
Quellcode unter: https://github.com/sschueller/peertube-android/

View File

@ -0,0 +1 @@
Thorium ist ein inoffizieller PeerTube-Abspieler

View File

@ -0,0 +1 @@
Inoffizieller PeerTube-Client

View File

@ -0,0 +1 @@
https://www.youtube.com/watch?v=PJIsiuSdpq8

View File

@ -0,0 +1 @@
- Aggiornamento dell'autenticazione

View File

@ -0,0 +1 @@
- uscita F-Droid per correggere la distribuzione automatica

View File

@ -0,0 +1,7 @@
- Aggiunto il supporto del reindirizzamento ipertestuale nella descrizione (@freeboub)
- vari crash fix (@freeboub)
- evitare di andare a pip quando si esce dall'applicazione a causa del pulsante di condivisione (@freeboub)
- Aggiunto la possibilità di filtrare la lista dei server (@freeboub)
- Gestione degli errori del rifattore Toast per dividere l'errore di rete (@freeboub)
- Mantenere il rapporto d'aspetto video per pip (@freeboub)
- la barra di navigazione non è stata ripristinata

View File

@ -0,0 +1,33 @@
Thorium è un client PeerTube in grado di connettersi a qualsiasi server peertube che esegue la versione v1.1.0-alpha.2 o successiva.
PeerTube è una piattaforma di streaming video federata (ActivityPub) che utilizza P2P (BitTorrent) direttamente nel browser web. Per ulteriori informazioni, visitare https://joinpeertube.org/ per ulteriori informazioni e un elenco dei server.
Questo client viene preconfigurato con un server PeerTube gestito dal creatore dell'applicazione non il progetto PeerTube stesso, che elenca di più su http://instances.joinpeertube.org/ per consentire di avere un assaggio di ciò che il client è in grado di. Scegli il tuo server per ottimizzare la tua esperienza!
Caratteristiche attuali:
- Connettersi a qualsiasi server PeerTube
- Video Torrent o riproduzione diretta
- Ricerca PeerTube
- Scarica / Condividi video
- Temi / Modalità scuro
- Riproduzione nello sfondo
- Riproduzione a schermo intero in orizzontale
- Velocità di riproduzione
- Filtrare il contenuto NSFW
- Autenticazione / accesso
- Video mi piace /non mi piace
Comming Presto:
- Commenta i video
- Registrati
- Pagina Panoramica utente/canale
- Segnala video
Autorizzazioni:
- Accesso di archiviazione, necessario per lo scaricamento Torrent o lo scaricamento video.
Concesso in licenza ai sensi della GNU Affero General Public License v3.0
Le autorizzazioni di questa licenza copyleft più forte sono condizionate a rendere disponibile il codice sorgente completo delle opere e delle modifiche con licenza, che includono opere più grandi utilizzando un lavoro concesso in licenza, sotto la stessa licenza. Le note sul copyright e sulla licenza devono essere conservate. I contributori forniscono una concessione espressa dei diritti di brevetto. Quando una versione modificata viene utilizzata per fornire un servizio in rete, è necessario reso disponibile il codice sorgente completo della versione modificata.
Codice sorgente all'indirizzo: https://github.com/sschueller/peertube-android/

View File

@ -0,0 +1 @@
Thorium è un lettore PeerTube non ufficiale

View File

@ -0,0 +1 @@
Cliente PeerTube non ufficiale

View File

@ -0,0 +1 @@
https://www.youtube.com/watch?v=PJIsiuSdpq8

View File

@ -1,6 +1,6 @@
#Fri Jun 12 19:07:10 CEST 2020 #Sun Nov 22 12:39:32 CET 2020
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip