1
0
mirror of https://framagit.org/tom79/fedilab-tube synced 2025-06-05 21:09:11 +02:00

51 Commits

Author SHA1 Message Date
74e45b1820 Quick fix 2020-12-18 18:36:32 +01:00
0a1336f0e0 Release 1.10.2 2020-12-18 18:00:47 +01:00
d5a0dcb980 Fix issue #152 2020-12-18 16:49:18 +01:00
83e7c41ca0 Merge branch 'l10n_develop' into develop 2020-12-18 16:35:05 +01:00
1d1b0c11a9 fix CI 2020-12-18 14:41:48 +01:00
3b2c4e2ac6 New translations strings.xml (Chinese Traditional) 2020-12-18 14:41:27 +01:00
2d77fe580f New translations strings.xml (Chinese Simplified) 2020-12-18 14:41:23 +01:00
7ae20f43f8 New translations strings.xml (Swedish) 2020-12-18 14:41:19 +01:00
f03c1b206b New translations strings.xml (Russian) 2020-12-18 14:41:16 +01:00
d99a58f2cf New translations strings.xml (Portuguese) 2020-12-18 14:41:12 +01:00
5aeaf7f34b New translations strings.xml (Polish) 2020-12-18 14:41:09 +01:00
af0b484d16 New translations strings.xml (Dutch) 2020-12-18 14:41:06 +01:00
0a6791b752 New translations strings.xml (Korean) 2020-12-18 14:41:02 +01:00
e73e306d05 New translations strings.xml (Japanese) 2020-12-18 14:40:58 +01:00
52189abbff New translations strings.xml (Italian) 2020-12-18 14:40:53 +01:00
d721f12d74 New translations strings.xml (Greek) 2020-12-18 14:40:49 +01:00
69f28bb647 New translations strings.xml (German) 2020-12-18 14:40:45 +01:00
2b2295d831 New translations strings.xml (Arabic) 2020-12-18 14:40:41 +01:00
179586b8c4 New translations strings.xml (Spanish) 2020-12-18 14:40:38 +01:00
1afad9e06a New translations strings.xml (French) 2020-12-18 14:40:35 +01:00
59c73fd864 New translations strings.xml (Romanian) 2020-12-18 14:40:30 +01:00
6820344750 Fix #145 and #153 2020-12-18 14:31:36 +01:00
680504791c New translations strings.xml (Chinese Traditional) 2020-12-17 17:53:31 +01:00
41e500a8f8 New translations strings.xml (Chinese Simplified) 2020-12-17 17:53:28 +01:00
448af1ef9a New translations strings.xml (Swedish) 2020-12-17 17:53:23 +01:00
041e8c0bd6 New translations strings.xml (Russian) 2020-12-17 17:53:19 +01:00
0b7300e93a New translations strings.xml (Polish) 2020-12-17 17:53:16 +01:00
94c5f5a705 New translations strings.xml (Dutch) 2020-12-17 17:53:12 +01:00
fa2f8a7b05 New translations strings.xml (Korean) 2020-12-17 17:53:09 +01:00
aeb288142e New translations strings.xml (Japanese) 2020-12-17 17:53:06 +01:00
635c43f458 New translations strings.xml (Italian) 2020-12-17 17:53:03 +01:00
d36138431b New translations strings.xml (Greek) 2020-12-17 17:52:58 +01:00
9cdf857730 New translations strings.xml (German) 2020-12-17 17:52:55 +01:00
52a6152af6 New translations strings.xml (Arabic) 2020-12-17 17:52:52 +01:00
9d3312c081 New translations strings.xml (Spanish) 2020-12-17 17:52:48 +01:00
1146236f46 New translations strings.xml (Portuguese) 2020-12-17 17:52:44 +01:00
ec19ee1e55 New translations strings.xml (French) 2020-12-17 17:52:39 +01:00
cc37e40158 New translations strings.xml (Romanian) 2020-12-17 17:52:05 +01:00
bdd12de34d Fix issues #150 #149 #148 #147 2020-12-17 17:37:40 +01:00
e64692d0d3 Merge branch 'l10n_develop' into 'develop'
New Crowdin updates

See merge request tom79/fedilab-tube!55
2020-12-17 14:37:10 +01:00
7da8c0f664 New Crowdin updates 2020-12-17 14:37:10 +01:00
fc41c077dc move fastlane 2020-12-17 14:16:49 +01:00
50800da4b9 move fastlane 2020-12-17 14:01:35 +01:00
a9219e8a91 move fastlane 2020-12-17 14:00:12 +01:00
5eedadef47 New instance acad + matomo (acad flavor only) 2020-12-16 17:24:23 +01:00
14cde8e625 Fixes 2020-12-16 10:14:46 +01:00
1f2ecd591d Matomo for acad flavor 2020-12-14 16:41:29 +01:00
9a2eb6cd49 Support openid 2020-12-14 14:42:28 +01:00
aa38514bcb Merge branch 'develop' of https://framagit.org/tom79/fedilab-tube into develop 2020-12-14 08:27:49 +01:00
d3ffc32d9b Merge branch 'develop' of https://framagit.org/tom79/fedilab-tube into develop
 Conflicts:
	app/src/main/java/app/fedilab/fedilabtube/PeertubeActivity.java
	app/src/main/java/app/fedilab/fedilabtube/drawer/CommentListAdapter.java
	app/src/main/java/app/fedilab/fedilabtube/helper/CommentDecorationHelper.java
	app/src/main/res/layout/activity_peertube.xml
2020-11-16 08:24:35 +01:00
a6dfd842e3 improve comments 2020-11-09 15:49:29 +01:00
109 changed files with 831 additions and 359 deletions

View File

@ -68,7 +68,7 @@ assembleDebug:
cache: cache:
key: "${CI_COMMIT_TAG}" key: "${CI_COMMIT_TAG}"
paths: paths:
- app/build/outputs/apk/fdroid_acad/debug/app-fdroid_acad-debug.apk - app/build/outputs/apk/fdroid_peertube_apps_educ/debug/app-fdroid_peertube_apps_educ-debug.apk
- app/build/outputs/apk/fdroid_full/debug/app-fdroid_full-debug.apk - app/build/outputs/apk/fdroid_full/debug/app-fdroid_full-debug.apk
policy: push policy: push
script: script:
@ -76,11 +76,11 @@ assembleDebug:
# Basic android and gradle stuff # Basic android and gradle stuff
# Check linting # Check linting
lintFdroid_acadDebug: lintfdroid_peertube_apps_educDebug:
interruptible: true interruptible: true
stage: build stage: build
script: script:
- ./gradlew -Pci --console=plain :app:lintFdroid_acadDebug -PbuildDir=lint - ./gradlew -Pci --console=plain :app:lintfdroid_peertube_apps_educDebug -PbuildDir=lint
except: except:
- tags - tags
@ -110,7 +110,7 @@ putApkOnTags:
cache: cache:
key: "${CI_COMMIT_TAG}" key: "${CI_COMMIT_TAG}"
paths: paths:
- app/build/outputs/apk/fdroid_acad/debug/app-fdroid_acad-debug.apk - app/build/outputs/apk/fdroid_peertube_apps_educ/debug/app-fdroid_peertube_apps_educ-debug.apk
- app/build/outputs/apk/fdroid_full/debug/app-fdroid_full-debug.apk - app/build/outputs/apk/fdroid_full/debug/app-fdroid_full-debug.apk
policy: pull policy: pull
script: script:
@ -120,11 +120,11 @@ putApkOnTags:
- export NC_UPLOAD_URL="${NC_REMOTE_DIR}/${CI_COMMIT_TAG}" - export NC_UPLOAD_URL="${NC_REMOTE_DIR}/${CI_COMMIT_TAG}"
- export NC_DOWNLOAD_URL="${NC_SHARE_URL}/download?path=%2F${CI_COMMIT_TAG}%2F&files=" - export NC_DOWNLOAD_URL="${NC_SHARE_URL}/download?path=%2F${CI_COMMIT_TAG}%2F&files="
- 'export HEADER="Private-Token: ${GITLAB_API_TOKEN}"' - 'export HEADER="Private-Token: ${GITLAB_API_TOKEN}"'
- export acadUrl="${NC_DOWNLOAD_URL}app-fdroid_acad-debug.apk" - export acadUrl="${NC_DOWNLOAD_URL}app-fdroid_peertube_apps_educ-debug.apk"
- export fullUrl="${NC_DOWNLOAD_URL}app-fdroid_full-debug.apk" - export fullUrl="${NC_DOWNLOAD_URL}app-fdroid_full-debug.apk"
- 'curl -s -u "${NC_USER}:${NC_PASSWORD}" -X MKCOL "${NC_UPLOAD_URL}"' - 'curl -s -u "${NC_USER}:${NC_PASSWORD}" -X MKCOL "${NC_UPLOAD_URL}"'
- 'curl -s -u "${NC_USER}:${NC_PASSWORD}" -T app/build/outputs/apk/fdroid_full/debug/app-fdroid_full-debug.apk "${NC_UPLOAD_URL}/app-fdroid_full-debug.apk"' - 'curl -s -u "${NC_USER}:${NC_PASSWORD}" -T app/build/outputs/apk/fdroid_full/debug/app-fdroid_full-debug.apk "${NC_UPLOAD_URL}/app-fdroid_full-debug.apk"'
- 'curl -s -u "${NC_USER}:${NC_PASSWORD}" -T app/build/outputs/apk/fdroid_acad/debug/app-fdroid_acad-debug.apk "${NC_UPLOAD_URL}/app-fdroid_acad-debug.apk"' - 'curl -s -u "${NC_USER}:${NC_PASSWORD}" -T app/build/outputs/apk/fdroid_peertube_apps_educ/debug/app-fdroid_peertube_apps_educ-debug.apk "${NC_UPLOAD_URL}/app-fdroid_peertube_apps_educ-debug.apk"'
- export description=$(curl -s --header "${HEADER}" "${DESCRIPTION_URL}" | jq .release.description | sed -e 's@"@@g') - export description=$(curl -s --header "${HEADER}" "${DESCRIPTION_URL}" | jq .release.description | sed -e 's@"@@g')
- if [[ $description == 'null' ]]; then export METHOD="POST"; echo -e "[Get the acad version](${acadUrl})\n\n[Get the full version](${fullUrl})" > /tmp/text; fi - if [[ $description == 'null' ]]; then export METHOD="POST"; echo -e "[Get the acad version](${acadUrl})\n\n[Get the full version](${fullUrl})" > /tmp/text; fi
- if [[ $description != 'null' ]]; then export METHOD="PUT"; echo -e "${description}\n\n[Get the acad version](${acadUrl})\n\n[Get the full version](${fullUrl})" > /tmp/text; fi - if [[ $description != 'null' ]]; then export METHOD="PUT"; echo -e "${description}\n\n[Get the acad version](${acadUrl})\n\n[Get the full version](${fullUrl})" > /tmp/text; fi

View File

@ -9,8 +9,8 @@ android {
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 30 targetSdkVersion 30
versionCode 31 versionCode 33
versionName "1.10.1" versionName "1.10.2"
multiDexEnabled true multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
@ -38,8 +38,9 @@ android {
checkReleaseBuilds false checkReleaseBuilds false
abortOnError false abortOnError false
} }
//boolean full_instances if set to false means TubeAcad
productFlavors { productFlavors {
fdroid_acad { fdroid_peertube_apps_educ {
applicationId "app.fedilab.fedilabtube" applicationId "app.fedilab.fedilabtube"
resValue "string", "app_name", "TubeAcad" resValue "string", "app_name", "TubeAcad"
resValue "string", "app_id", "app.fedilab.fedilabtube" resValue "string", "app_id", "app.fedilab.fedilabtube"
@ -50,7 +51,7 @@ android {
buildConfigField "boolean", "sepia_search", "false" buildConfigField "boolean", "sepia_search", "false"
buildConfigField "boolean", "instance_switcher", "true" buildConfigField "boolean", "instance_switcher", "true"
} }
google_acad { google_peertube_apps_educ {
applicationId "app.fedilab.fedilabtube" applicationId "app.fedilab.fedilabtube"
resValue "string", "app_name", "TubeAcad" resValue "string", "app_name", "TubeAcad"
resValue "string", "app_id", "app.fedilab.fedilabtube" resValue "string", "app_id", "app.fedilab.fedilabtube"
@ -109,23 +110,29 @@ android {
} }
sourceSets { sourceSets {
fdroid_acad { fdroid_peertube_apps_educ {
res.srcDirs = ['src/main/res', 'src/acad/res'] res.srcDirs = ['src/main/res', 'src/acad/res']
java.srcDirs = ['src/main/java', 'src/acad/java']
} }
google_acad { google_peertube_apps_educ {
res.srcDirs = ['src/main/res', 'src/acad/res'] res.srcDirs = ['src/main/res', 'src/acad/res']
java.srcDirs = ['src/main/java', 'src/acad/java']
} }
fdroid_full { fdroid_full {
res.srcDirs = ['src/main/res', 'src/full/res'] res.srcDirs = ['src/main/res', 'src/full/res']
java.srcDirs = ['src/main/java', 'src/full/java']
} }
google_full { google_full {
res.srcDirs = ['src/main/res', 'src/full/res'] res.srcDirs = ['src/main/res', 'src/full/res']
java.srcDirs = ['src/main/java', 'src/full/java']
} }
queermotion { queermotion {
res.srcDirs = ['src/main/res', 'src/queermotion/res'] res.srcDirs = ['src/main/res', 'src/queermotion/res']
java.srcDirs = ['src/main/java', 'src/full/java']
} }
bittube { bittube {
res.srcDirs = ['src/main/res', 'src/bittube/res'] res.srcDirs = ['src/main/res', 'src/bittube/res']
java.srcDirs = ['src/main/java', 'src/full/java']
} }
} }
} }
@ -189,4 +196,8 @@ dependencies {
implementation 'org.slf4j:slf4j-simple:1.7.30' implementation 'org.slf4j:slf4j-simple:1.7.30'
fdroid_peertube_apps_educImplementation 'org.matomo.sdk:tracker:4.1.2'
google_peertube_apps_educImplementation 'org.matomo.sdk:tracker:4.1.2'
} }

View File

@ -0,0 +1,35 @@
package app.fedilab.fedilabtube;
/* Copyright 2020 Thomas Schneider
*
* This file is a part of TubeLab
*
* 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.
*
* TubeLab 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 TubeLab; if not,
* see <http://www.gnu.org/licenses>. */
import org.matomo.sdk.Matomo;
import org.matomo.sdk.Tracker;
import org.matomo.sdk.TrackerBuilder;
public class FedilabTube extends BaseFedilabTube {
private Tracker mMatomoTracker;
public synchronized Tracker getTracker() {
if (mMatomoTracker != null) return mMatomoTracker;
mMatomoTracker = TrackerBuilder.createDefault("https://wa.phm.education.gouv.fr/snp/matomo.php", 11).build(Matomo.getInstance(this));
return mMatomoTracker;
}
}

View File

@ -0,0 +1,47 @@
package app.fedilab.fedilabtube;
/* Copyright 2020 Thomas Schneider
*
* This file is a part of TubeLab
*
* 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.
*
* TubeLab 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 TubeLab; if not,
* see <http://www.gnu.org/licenses>. */
import android.app.Activity;
import android.content.Context;
import org.matomo.sdk.Tracker;
import org.matomo.sdk.extra.TrackHelper;
public class Matomo {
public static void sendScreen(Context _mcontext, String path, String title) {
Tracker tracker = ((FedilabTube) ((Activity) _mcontext).getApplication()).getTracker();
TrackHelper.track().screen(path).title(title).with(tracker);
}
public static void sendEvent(Context _mcontext, String category, String action, String label, float value) {
Tracker tracker = ((FedilabTube) ((Activity) _mcontext).getApplication()).getTracker();
TrackHelper.track().event(category, action).name(label).value(value).with(tracker);
}
public static void sendValue(Context _mcontext, String path, int index, String dimensionValue) {
Tracker tracker = ((FedilabTube) ((Activity) _mcontext).getApplication()).getTracker();
TrackHelper.track().screen(path).dimension(index, dimensionValue).with(tracker);
}
public static void trackInstall(Context _mcontext) {
Tracker tracker = ((FedilabTube) ((Activity) _mcontext).getApplication()).getTracker();
TrackHelper.track().download().with(tracker);
}
}

View File

@ -0,0 +1,20 @@
package app.fedilab.fedilabtube;
/* Copyright 2020 Thomas Schneider
*
* This file is a part of TubeLab
*
* 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.
*
* TubeLab 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 TubeLab; if not,
* see <http://www.gnu.org/licenses>. */
public class FedilabTube extends BaseFedilabTube {
}

View File

@ -0,0 +1,41 @@
package app.fedilab.fedilabtube;
/* Copyright 2020 Thomas Schneider
*
* This file is a part of TubeLab
*
* 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.
*
* TubeLab 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 TubeLab; if not,
* see <http://www.gnu.org/licenses>. */
import android.content.Context;
@SuppressWarnings({"unused", "RedundantSuppression"})
public class Matomo {
public static void sendScreen(Context _mcontext, String path, String title) {
//Do nothing
}
public static void sendEvent(Context _mcontext, String category, String action, String label, float value) {
//Do nothing
}
public static void sendValue(Context _mcontext, String path, int index, String dimensionValue) {
//Do nothing
}
public static void trackInstall(Context _mcontext) {
//Do nothing
}
}

View File

@ -74,6 +74,7 @@ import static app.fedilab.fedilabtube.helper.Helper.peertubeInformation;
public class AllPlaylistsActivity extends AppCompatActivity implements PlaylistAdapter.AllPlaylistRemoved { public class AllPlaylistsActivity extends AppCompatActivity implements PlaylistAdapter.AllPlaylistRemoved {
private static final int PICK_AVATAR = 467;
PlaylistAdapter playlistAdapter; PlaylistAdapter playlistAdapter;
private HashMap<Integer, String> privacyToSend; private HashMap<Integer, String> privacyToSend;
private String idChannel; private String idChannel;
@ -81,7 +82,6 @@ public class AllPlaylistsActivity extends AppCompatActivity implements PlaylistA
private Playlist playlistToEdit; private Playlist playlistToEdit;
private List<ChannelData.Channel> myChannels; private List<ChannelData.Channel> myChannels;
private ChannelData.Channel selectedChannel; private ChannelData.Channel selectedChannel;
private static final int PICK_AVATAR = 467;
private AddPlaylistBinding bindingDialog; private AddPlaylistBinding bindingDialog;
private Uri inputData; private Uri inputData;
private ActivityAllPlaylistBinding binding; private ActivityAllPlaylistBinding binding;

View File

@ -35,7 +35,7 @@ import app.fedilab.fedilabtube.helper.ThemeHelper;
import app.fedilab.fedilabtube.services.GlobalUploadObserver; import app.fedilab.fedilabtube.services.GlobalUploadObserver;
import app.fedilab.fedilabtube.worker.WorkHelper; import app.fedilab.fedilabtube.worker.WorkHelper;
public class FedilabTube extends MultiDexApplication { public class BaseFedilabTube extends MultiDexApplication {
static String UPLOAD_CHANNEL_ID = "upload_info_peertube"; static String UPLOAD_CHANNEL_ID = "upload_info_peertube";
@ -48,12 +48,12 @@ public class FedilabTube extends MultiDexApplication {
Configuration myConfig = new Configuration.Builder() Configuration myConfig = new Configuration.Builder()
.setMinimumLoggingLevel(android.util.Log.INFO) .setMinimumLoggingLevel(android.util.Log.INFO)
.build(); .build();
WorkManager.initialize(FedilabTube.this, myConfig); WorkManager.initialize(BaseFedilabTube.this, myConfig);
if (interval >= 15) { if (interval >= 15) {
WorkHelper.fetchNotifications(this, interval); WorkHelper.fetchNotifications(this, interval);
} }
createNotificationChannel(); createNotificationChannel();
UploadServiceConfig.initialize(FedilabTube.this, UPLOAD_CHANNEL_ID, true); UploadServiceConfig.initialize(BaseFedilabTube.this, UPLOAD_CHANNEL_ID, true);
new GlobalRequestObserver(this, new GlobalUploadObserver()); new GlobalRequestObserver(this, new GlobalUploadObserver());
} }
@ -63,7 +63,7 @@ public class FedilabTube extends MultiDexApplication {
protected void attachBaseContext(Context base) { protected void attachBaseContext(Context base) {
super.attachBaseContext(base); super.attachBaseContext(base);
MultiDex.install(FedilabTube.this); MultiDex.install(BaseFedilabTube.this);
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
int themePref = sharedpreferences.getInt(Helper.SET_THEME, Helper.DEFAULT_MODE); int themePref = sharedpreferences.getInt(Helper.SET_THEME, Helper.DEFAULT_MODE);
ThemeHelper.switchTo(themePref); ThemeHelper.switchTo(themePref);

View File

@ -26,6 +26,8 @@ import android.util.Patterns;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@ -35,6 +37,9 @@ import androidx.core.content.ContextCompat;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI; import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
import app.fedilab.fedilabtube.client.entities.Error; import app.fedilab.fedilabtube.client.entities.Error;
@ -56,6 +61,7 @@ public class LoginActivity extends AppCompatActivity {
private static String client_id; private static String client_id;
private static String client_secret; private static String client_secret;
private ActivityLoginBinding binding; private ActivityLoginBinding binding;
private String acadInstance;
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
@Override @Override
@ -117,17 +123,89 @@ public class LoginActivity extends AppCompatActivity {
if (!hasFocus) { if (!hasFocus) {
if (binding.loginUid.getText() != null && android.util.Patterns.EMAIL_ADDRESS.matcher(binding.loginUid.getText().toString().trim()).matches()) { if (binding.loginUid.getText() != null && android.util.Patterns.EMAIL_ADDRESS.matcher(binding.loginUid.getText().toString().trim()).matches()) {
String[] emailArray = binding.loginUid.getText().toString().split("@"); String[] emailArray = binding.loginUid.getText().toString().split("@");
if (emailArray.length > 1 && Arrays.asList(HelperAcadInstance.openid).contains(emailArray[1])) { if (emailArray.length > 1) {
binding.loginButton.callOnClick(); binding.loginButton.callOnClick();
} }
} }
} }
}); });
binding.loginUidContainer.setVisibility(View.GONE);
binding.loginPasswdContainer.setVisibility(View.GONE);
binding.loginInstanceContainer.setVisibility(View.GONE);
binding.createAnAccountPeertube.setVisibility(View.GONE);
binding.instancePickerTitle.setVisibility(View.VISIBLE);
binding.instancePicker.setVisibility(View.VISIBLE);
HashMap<String, String> instancesMap = new HashMap<>(HelperAcadInstance.instances_themes);
Iterator<Map.Entry<String, String>> it = instancesMap.entrySet().iterator();
String[] academiesKey = new String[HelperAcadInstance.instances_themes.size()];
String[] academiesValue = new String[HelperAcadInstance.instances_themes.size()];
String acad = HelperInstance.getLiveInstance(LoginActivity.this);
int position = 0;
int i = 0;
while (it.hasNext()) {
Map.Entry<String, String> pair = it.next();
academiesKey[i] = pair.getKey();
academiesValue[i] = pair.getValue();
if (pair.getValue().compareTo(acad) == 0) {
position = i;
}
it.remove();
i++;
}
binding.instancePicker.setSelection(position, true);
ArrayAdapter<String> adapterChannel = new ArrayAdapter<>(LoginActivity.this,
android.R.layout.simple_spinner_dropdown_item, academiesKey);
binding.instancePicker.setAdapter(adapterChannel);
binding.instancePicker.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
acadInstance = academiesValue[position];
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
} }
binding.loginButton.setOnClickListener(v -> { binding.loginButton.setOnClickListener(v -> {
if (!BuildConfig.full_instances) {
new Thread(() -> {
try {
Oauth oauth = new RetrofitPeertubeAPI(LoginActivity.this, acadInstance, null).oauthClient(null, null, null, null);
if (oauth == null) {
runOnUiThread(() -> {
binding.loginButton.setEnabled(true);
Toasty.error(LoginActivity.this, getString(R.string.client_error), Toast.LENGTH_LONG).show();
});
return;
}
client_id = oauth.getClient_id();
client_secret = oauth.getClient_secret();
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.CLIENT_ID, client_id);
editor.putString(Helper.CLIENT_SECRET, client_secret);
editor.apply();
Intent intent = new Intent(LoginActivity.this, WebviewConnectActivity.class);
Bundle b = new Bundle();
b.putString("url", "https://" + acadInstance + "/plugins/auth-openid-connect/0.0.1/auth/openid-connect");
intent.putExtras(b);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
runOnUiThread(() -> {
binding.loginButton.setEnabled(true);
Toasty.error(LoginActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show();
});
}
}).start();
} else {
if (binding.loginUid.getText() != null && binding.loginUid.getText().toString().contains("@") && !android.util.Patterns.EMAIL_ADDRESS.matcher(binding.loginUid.getText().toString().trim()).matches()) { if (binding.loginUid.getText() != null && binding.loginUid.getText().toString().contains("@") && !android.util.Patterns.EMAIL_ADDRESS.matcher(binding.loginUid.getText().toString().trim()).matches()) {
Toasty.error(LoginActivity.this, getString(R.string.email_error)).show(); Toasty.error(LoginActivity.this, getString(R.string.email_error)).show();
return; return;
@ -141,8 +219,9 @@ public class LoginActivity extends AppCompatActivity {
binding.loginButton.setEnabled(true); binding.loginButton.setEnabled(true);
return; return;
} }
host = emailArray[1];
instance = HelperInstance.getPeertubeUrl(host); instance = HelperInstance.getLiveInstance(LoginActivity.this);
host = instance;
} else { } else {
if (binding.loginInstance.getText() == null || binding.loginInstance.getText().toString().trim().length() == 0) { if (binding.loginInstance.getText() == null || binding.loginInstance.getText().toString().trim().length() == 0) {
Toasty.error(LoginActivity.this, getString(R.string.not_valide_instance)).show(); Toasty.error(LoginActivity.this, getString(R.string.not_valide_instance)).show();
@ -176,40 +255,7 @@ public class LoginActivity extends AppCompatActivity {
} }
String finalInstance = instance; String finalInstance = instance;
String finalHost = host; String finalHost = host;
if (Arrays.asList(HelperAcadInstance.openid).contains(host) && !BuildConfig.full_instances) { if (BuildConfig.full_instances) {
new Thread(() -> {
try {
Oauth oauth = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).oauthClient(null, null, null, null);
if (oauth == null) {
runOnUiThread(() -> {
binding.loginButton.setEnabled(true);
Toasty.error(LoginActivity.this, getString(R.string.client_error), Toast.LENGTH_LONG).show();
});
return;
}
client_id = oauth.getClient_id();
client_secret = oauth.getClient_secret();
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.CLIENT_ID, client_id);
editor.putString(Helper.CLIENT_SECRET, client_secret);
editor.apply();
Intent intent = new Intent(LoginActivity.this, WebviewConnectActivity.class);
Bundle b = new Bundle();
b.putString("url", "https://" + HelperInstance.getPeertubeUrl(finalHost) + "/plugins/auth-openid-connect/0.0.1/auth/openid-connect");
intent.putExtras(b);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
runOnUiThread(() -> {
binding.loginButton.setEnabled(true);
Toasty.error(LoginActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show();
});
}
}).start();
} else {
new Thread(() -> { new Thread(() -> {
Oauth oauth = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).oauthClient(Helper.CLIENT_NAME_VALUE, Helper.WEBSITE_VALUE, Helper.OAUTH_SCOPES_PEERTUBE, Helper.WEBSITE_VALUE); Oauth oauth = new RetrofitPeertubeAPI(LoginActivity.this, finalInstance, null).oauthClient(Helper.CLIENT_NAME_VALUE, Helper.WEBSITE_VALUE, Helper.OAUTH_SCOPES_PEERTUBE, Helper.WEBSITE_VALUE);
if (oauth == null) { if (oauth == null) {
@ -253,7 +299,7 @@ public class LoginActivity extends AppCompatActivity {
} }
}).start(); }).start();
} }
}
}); });
} }

View File

@ -58,8 +58,11 @@ import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -80,6 +83,7 @@ import app.fedilab.fedilabtube.databinding.ActivityMainBinding;
import app.fedilab.fedilabtube.fragment.DisplayOverviewFragment; import app.fedilab.fedilabtube.fragment.DisplayOverviewFragment;
import app.fedilab.fedilabtube.fragment.DisplayVideosFragment; import app.fedilab.fedilabtube.fragment.DisplayVideosFragment;
import app.fedilab.fedilabtube.helper.Helper; import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.helper.HelperAcadInstance;
import app.fedilab.fedilabtube.helper.HelperInstance; import app.fedilab.fedilabtube.helper.HelperInstance;
import app.fedilab.fedilabtube.helper.PlaylistExportHelper; import app.fedilab.fedilabtube.helper.PlaylistExportHelper;
import app.fedilab.fedilabtube.helper.SwitchAccountHelper; import app.fedilab.fedilabtube.helper.SwitchAccountHelper;
@ -97,7 +101,7 @@ import su.litvak.chromecast.api.v2.MediaStatus;
import static app.fedilab.fedilabtube.MainActivity.TypeOfConnection.NORMAL; import static app.fedilab.fedilabtube.MainActivity.TypeOfConnection.NORMAL;
import static app.fedilab.fedilabtube.MainActivity.TypeOfConnection.SURFING; import static app.fedilab.fedilabtube.MainActivity.TypeOfConnection.SURFING;
import static app.fedilab.fedilabtube.helper.Helper.peertubeInformation; import static app.fedilab.fedilabtube.helper.Helper.peertubeInformation;
import static app.fedilab.fedilabtube.helper.HelperAcadInstance.academies;
public class MainActivity extends AppCompatActivity implements ChromeCastsListener { public class MainActivity extends AppCompatActivity implements ChromeCastsListener {
@ -107,16 +111,53 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
public static UserMe userMe; public static UserMe userMe;
public static InstanceData.InstanceConfig instanceConfig; public static InstanceData.InstanceConfig instanceConfig;
public static TypeOfConnection typeOfConnection; public static TypeOfConnection typeOfConnection;
public static List<ChromeCast> chromeCasts;
public static ChromeCast chromeCast;
public static boolean chromecastActivated = false;
private DisplayVideosFragment recentFragment, locaFragment, trendingFragment, subscriptionFragment, mostLikedFragment; private DisplayVideosFragment recentFragment, locaFragment, trendingFragment, subscriptionFragment, mostLikedFragment;
private DisplayOverviewFragment overviewFragment; private DisplayOverviewFragment overviewFragment;
private ActivityMainBinding binding; private ActivityMainBinding binding;
private final BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= item -> {
int itemId = item.getItemId();
String type = null;
if (itemId == R.id.navigation_discover) {
setTitleCustom(R.string.title_discover);
binding.viewpager.setCurrentItem(0);
type = HelperAcadInstance.DISCOVER;
} else if (itemId == R.id.navigation_subscription) {
binding.viewpager.setCurrentItem(1);
setTitleCustom(R.string.subscriptions);
type = HelperAcadInstance.SUBSCRIPTIONS;
} else if (itemId == R.id.navigation_trending) {
setTitleCustom(R.string.title_trending);
if (Helper.isLoggedIn(MainActivity.this)) {
binding.viewpager.setCurrentItem(2);
} else {
binding.viewpager.setCurrentItem(1);
}
type = HelperAcadInstance.TRENDING;
} else if (itemId == R.id.navigation_most_liked) {
setTitleCustom(R.string.title_most_liked);
binding.viewpager.setCurrentItem(2);
type = HelperAcadInstance.MOSTLIKED;
} else if (itemId == R.id.navigation_recently_added) {
setTitleCustom(R.string.title_recently_added);
binding.viewpager.setCurrentItem(3);
type = HelperAcadInstance.RECENTLY_ADDED;
} else if (itemId == R.id.navigation_local) {
setTitleCustom(R.string.title_local);
binding.viewpager.setCurrentItem(4);
type = HelperAcadInstance.LOCAL;
}
if (type != null) {
Matomo.sendScreen(MainActivity.this, "TIMELINE", type);
}
return true;
};
private BroadcastReceiver manage_chromecast; private BroadcastReceiver manage_chromecast;
public static List<ChromeCast> chromeCasts;
public static ChromeCast chromeCast;
private VideoData.Video castedTube; private VideoData.Video castedTube;
public static boolean chromecastActivated = false;
@SuppressLint("ApplySharedPref") @SuppressLint("ApplySharedPref")
public static void showRadioButtonDialogFullInstances(Activity activity, boolean storeInDb) { public static void showRadioButtonDialogFullInstances(Activity activity, boolean storeInDb) {
final SharedPreferences sharedpreferences = activity.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); final SharedPreferences sharedpreferences = activity.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
@ -190,35 +231,6 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
} }
} }
private final BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= item -> {
int itemId = item.getItemId();
if (itemId == R.id.navigation_discover) {
setTitleCustom(R.string.title_discover);
binding.viewpager.setCurrentItem(0);
} else if (itemId == R.id.navigation_subscription) {
binding.viewpager.setCurrentItem(1);
setTitleCustom(R.string.subscriptions);
} else if (itemId == R.id.navigation_trending) {
setTitleCustom(R.string.title_trending);
if (Helper.isLoggedIn(MainActivity.this)) {
binding.viewpager.setCurrentItem(2);
} else {
binding.viewpager.setCurrentItem(1);
}
} else if (itemId == R.id.navigation_most_liked) {
setTitleCustom(R.string.title_most_liked);
binding.viewpager.setCurrentItem(2);
} else if (itemId == R.id.navigation_recently_added) {
setTitleCustom(R.string.title_recently_added);
binding.viewpager.setCurrentItem(3);
} else if (itemId == R.id.navigation_local) {
setTitleCustom(R.string.title_local);
binding.viewpager.setCurrentItem(4);
}
return true;
};
@Override @Override
public void newChromeCastDiscovered(ChromeCast chromeCast) { public void newChromeCastDiscovered(ChromeCast chromeCast) {
if (chromeCasts == null) { if (chromeCasts == null) {
@ -341,9 +353,8 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
typeOfConnection = TypeOfConnection.UNKNOWN; typeOfConnection = TypeOfConnection.UNKNOWN;
BottomNavigationView navView = findViewById(R.id.nav_view);
navView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener); binding.navView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
if (getSupportActionBar() != null) { if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayShowTitleEnabled(false); getSupportActionBar().setDisplayShowTitleEnabled(false);
@ -382,6 +393,8 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
} }
binding.viewpager.setOffscreenPageLimit(5); binding.viewpager.setOffscreenPageLimit(5);
Matomo.sendEvent(MainActivity.this, "UTILISATEUR", "DEMARRAGE", HelperInstance.getLiveInstance(MainActivity.this), Helper.isLoggedIn(MainActivity.this) ? 1 : 0);
binding.viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { binding.viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override @Override
@ -416,11 +429,11 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
setTitleCustom(R.string.title_discover); setTitleCustom(R.string.title_discover);
if (Helper.isLoggedIn(MainActivity.this)) { if (Helper.isLoggedIn(MainActivity.this)) {
navView.inflateMenu(R.menu.bottom_nav_menu_connected); binding.navView.inflateMenu(R.menu.bottom_nav_menu_connected);
refreshToken(); refreshToken();
} else { } else {
navView.inflateMenu(R.menu.bottom_nav_menu); binding.navView.inflateMenu(R.menu.bottom_nav_menu);
} }
peertubeInformation = new PeertubeInformation(); peertubeInformation = new PeertubeInformation();
peertubeInformation.setCategories(new LinkedHashMap<>()); peertubeInformation.setCategories(new LinkedHashMap<>());
@ -768,13 +781,16 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
String type = null;
String action = "TIMELINE";
if (item.getItemId() == R.id.action_change_instance) { if (item.getItemId() == R.id.action_change_instance) {
if (BuildConfig.full_instances) { if (BuildConfig.full_instances) {
showRadioButtonDialogFullInstances(MainActivity.this, false); showRadioButtonDialogFullInstances(MainActivity.this, false);
} else { } else {
showRadioButtonDialog(); showRadioButtonDialog();
} }
return true; action = "CHANGE_INSTANCE";
type = "";
} else if (item.getItemId() == R.id.action_settings) { } else if (item.getItemId() == R.id.action_settings) {
Intent intent = new Intent(MainActivity.this, SettingsActivity.class); Intent intent = new Intent(MainActivity.this, SettingsActivity.class);
startActivity(intent); startActivity(intent);
@ -790,32 +806,30 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
} }
startActivity(intent); startActivity(intent);
} }
return true;
} else if (item.getItemId() == R.id.action_upload) { } else if (item.getItemId() == R.id.action_upload) {
Intent intent = new Intent(MainActivity.this, PeertubeUploadActivity.class); Intent intent = new Intent(MainActivity.this, PeertubeUploadActivity.class);
startActivity(intent); startActivity(intent);
return true;
} else if (item.getItemId() == R.id.action_myvideos) { } else if (item.getItemId() == R.id.action_myvideos) {
Intent intent = new Intent(MainActivity.this, VideosTimelineActivity.class); Intent intent = new Intent(MainActivity.this, VideosTimelineActivity.class);
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putSerializable("type", TimelineVM.TimelineType.MY_VIDEOS); bundle.putSerializable("type", TimelineVM.TimelineType.MY_VIDEOS);
intent.putExtras(bundle); intent.putExtras(bundle);
startActivity(intent); startActivity(intent);
return true; type = HelperAcadInstance.MYVIDEOS;
} else if (item.getItemId() == R.id.action_history) { } else if (item.getItemId() == R.id.action_history) {
Intent intent = new Intent(MainActivity.this, VideosTimelineActivity.class); Intent intent = new Intent(MainActivity.this, VideosTimelineActivity.class);
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putSerializable("type", TimelineVM.TimelineType.HISTORY); bundle.putSerializable("type", TimelineVM.TimelineType.HISTORY);
intent.putExtras(bundle); intent.putExtras(bundle);
startActivity(intent); startActivity(intent);
return true; type = HelperAcadInstance.HISTORY;
} else if (item.getItemId() == R.id.action_most_liked) { } else if (item.getItemId() == R.id.action_most_liked) {
Intent intent = new Intent(MainActivity.this, VideosTimelineActivity.class); Intent intent = new Intent(MainActivity.this, VideosTimelineActivity.class);
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putSerializable("type", TimelineVM.TimelineType.MOST_LIKED); bundle.putSerializable("type", TimelineVM.TimelineType.MOST_LIKED);
intent.putExtras(bundle); intent.putExtras(bundle);
startActivity(intent); startActivity(intent);
return true; type = HelperAcadInstance.MOSTLIKED;
} else if (item.getItemId() == R.id.action_playlist) { } else if (item.getItemId() == R.id.action_playlist) {
Intent intent; Intent intent;
if (Helper.isLoggedIn(MainActivity.this)) { if (Helper.isLoggedIn(MainActivity.this)) {
@ -824,15 +838,12 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
intent = new Intent(MainActivity.this, AllLocalPlaylistsActivity.class); intent = new Intent(MainActivity.this, AllLocalPlaylistsActivity.class);
} }
startActivity(intent); startActivity(intent);
return true;
} else if (item.getItemId() == R.id.action_sepia_search) { } else if (item.getItemId() == R.id.action_sepia_search) {
Intent intent = new Intent(MainActivity.this, SepiaSearchActivity.class); Intent intent = new Intent(MainActivity.this, SepiaSearchActivity.class);
startActivity(intent); startActivity(intent);
return true;
} else if (item.getItemId() == R.id.action_about) { } else if (item.getItemId() == R.id.action_about) {
Intent intent = new Intent(MainActivity.this, AboutActivity.class); Intent intent = new Intent(MainActivity.this, AboutActivity.class);
startActivity(intent); startActivity(intent);
return true;
} else if (item.getItemId() == R.id.action_incognito) { } else if (item.getItemId() == R.id.action_incognito) {
item.setChecked(!item.isChecked()); item.setChecked(!item.isChecked());
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
@ -851,8 +862,10 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
}).start(); }).start();
return false; return false;
} }
if (type != null) {
return super.onOptionsItemSelected(item); Matomo.sendScreen(MainActivity.this, action, type);
}
return true;
} }
@ -880,14 +893,23 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); final SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
String acad = HelperInstance.getLiveInstance(MainActivity.this); String acad = HelperInstance.getLiveInstance(MainActivity.this);
int i = 0; int i = 0;
for (String item : academies) { HashMap<String, String> instancesMap = new HashMap<>(HelperAcadInstance.instances_themes);
if (HelperInstance.getPeertubeUrl(item).compareTo(acad) == 0) { Iterator<Map.Entry<String, String>> it = instancesMap.entrySet().iterator();
break; String[] academiesKey = new String[HelperAcadInstance.instances_themes.size()];
String[] academiesValue = new String[HelperAcadInstance.instances_themes.size()];
int position = 0;
while (it.hasNext()) {
Map.Entry<String, String> pair = it.next();
academiesKey[i] = pair.getKey();
academiesValue[i] = pair.getValue();
if (pair.getValue().compareTo(acad) == 0) {
position = i;
} }
it.remove();
i++; i++;
} }
alt_bld.setSingleChoiceItems(academies, i, (dialog, item) -> { alt_bld.setSingleChoiceItems(academiesKey, position, (dialog, item) -> {
String newInstance = academies[item]; String newInstance = academiesValue[item];
SharedPreferences.Editor editor = sharedpreferences.edit(); SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(Helper.PREF_INSTANCE, newInstance); editor.putString(Helper.PREF_INSTANCE, newInstance);
editor.commit(); editor.commit();
@ -914,6 +936,12 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
} }
} }
public enum TypeOfConnection {
UNKNOWN,
NORMAL,
SURFING
}
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter { private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
ScreenSlidePagerAdapter(FragmentManager fm) { ScreenSlidePagerAdapter(FragmentManager fm) {
@ -958,10 +986,4 @@ public class MainActivity extends AppCompatActivity implements ChromeCastsListen
return 5; return 5;
} }
} }
public enum TypeOfConnection {
UNKNOWN,
NORMAL,
SURFING
}
} }

View File

@ -96,6 +96,7 @@ import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelector; import com.google.android.exoplayer2.trackselection.TrackSelector;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
import com.google.android.exoplayer2.ui.DefaultTimeBar;
import com.google.android.exoplayer2.ui.PlayerControlView; import com.google.android.exoplayer2.ui.PlayerControlView;
import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
@ -103,6 +104,7 @@ import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util; import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.VideoListener; import com.google.android.exoplayer2.video.VideoListener;
import com.google.android.material.snackbar.Snackbar;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -233,7 +235,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
@Override @Override
public void onStreamStarted(Torrent torrent) { public void onStreamStarted(Torrent torrent) {
startStream(torrent.getVideoFile().getAbsolutePath(), null, autoPlay, -1, null, null, true); startStream(peertube, torrent.getVideoFile().getAbsolutePath(), null, autoPlay, -1, null, null, true);
} }
@Override @Override
@ -315,7 +317,10 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
sepiaSearch = b.getBoolean("sepia_search", false); sepiaSearch = b.getBoolean("sepia_search", false);
peertube = b.getParcelable("video"); peertube = b.getParcelable("video");
} }
new Thread(() -> {
String videoId = peertube != null ? peertube.getUuid() : videoUuid;
new RetrofitPeertubeAPI(PeertubeActivity.this).postView(videoId);
}).start();
willPlayFromIntent = manageIntentUrl(intent); willPlayFromIntent = manageIntentUrl(intent);
binding.peertubeDescriptionMore.setOnClickListener(v -> { binding.peertubeDescriptionMore.setOnClickListener(v -> {
@ -486,6 +491,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
return; return;
} }
peertube = apiResponse.getPeertubes().get(0); peertube = apiResponse.getPeertubes().get(0);
Matomo.sendScreen(PeertubeActivity.this, "VIDEO_REGARDEE", peertube.getUuid());
if (peertube.isNsfw()) { if (peertube.isNsfw()) {
binding.videoSensitive.setVisibility(View.VISIBLE); binding.videoSensitive.setVisibility(View.VISIBLE);
} else { } else {
@ -958,7 +964,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
binding.loader.setVisibility(View.GONE); binding.loader.setVisibility(View.GONE);
return; return;
} }
if (apiResponse.getPeertubes() == null || apiResponse.getPeertubes().get(0) == null || apiResponse.getPeertubes().get(0).getFileUrl(null, PeertubeActivity.this) == null) { if (apiResponse.getPeertubes() == null || apiResponse.getPeertubes().get(0) == null || (!apiResponse.getPeertubes().get(0).isLive() && apiResponse.getPeertubes().get(0).getFileUrl(null, PeertubeActivity.this) == null)) {
Toasty.error(PeertubeActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show(); Toasty.error(PeertubeActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show();
binding.loader.setVisibility(View.GONE); binding.loader.setVisibility(View.GONE);
return; return;
@ -974,6 +980,23 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
userHistory.setCurrentTime(previousPositionHistory); userHistory.setCurrentTime(previousPositionHistory);
peertube.setUserHistory(userHistory); peertube.setUserHistory(userHistory);
PlayerControlView controlView = binding.doubleTapPlayerView.findViewById(R.id.exo_controller);
DefaultTimeBar exo_progress = controlView.findViewById(R.id.exo_progress);
TextView exo_duration = controlView.findViewById(R.id.exo_duration);
TextView exo_live_badge = controlView.findViewById(R.id.exo_live_badge);
if (peertube.isLive()) {
exo_progress.setVisibility(View.INVISIBLE);
exo_duration.setVisibility(View.GONE);
exo_live_badge.setVisibility(View.VISIBLE);
exo_live_badge.setText(R.string.live);
exo_live_badge.setBackgroundResource(R.drawable.rounded_live);
} else {
exo_progress.setVisibility(View.VISIBLE);
exo_live_badge.setVisibility(View.GONE);
exo_duration.setBackground(null);
}
if (peertube.getUserHistory() != null) { if (peertube.getUserHistory() != null) {
position = peertube.getUserHistory().getCurrentTime() * 1000; position = peertube.getUserHistory().getCurrentTime() * 1000;
} }
@ -1025,7 +1048,13 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
LinkedHashMap<Integer, String> categoryInit = new LinkedHashMap<>(peertubeInformation.getCategories()); LinkedHashMap<Integer, String> categoryInit = new LinkedHashMap<>(peertubeInformation.getCategories());
info_category.setText(categoryInit.get(peertube.getCategory().getId())); info_category.setText(categoryInit.get(peertube.getCategory().getId()));
if (peertube.isLive()) {
info_duration.setText(R.string.live);
info_duration.setBackgroundResource(R.drawable.rounded_live);
} else {
info_duration.setText(Helper.secondsToString(peertube.getDuration())); info_duration.setText(Helper.secondsToString(peertube.getDuration()));
}
String format = DateFormat.getDateInstance(DateFormat.LONG).format(peertube.getPublishedAt()); String format = DateFormat.getDateInstance(DateFormat.LONG).format(peertube.getPublishedAt());
info_published_at.setText(format); info_published_at.setText(format);
List<String> tags = peertube.getTags(); List<String> tags = peertube.getTags();
@ -1169,8 +1198,9 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
binding.doubleTapPlayerView.setPlayer(player); binding.doubleTapPlayerView.setPlayer(player);
binding.loader.setVisibility(View.GONE); binding.loader.setVisibility(View.GONE);
startStream( startStream(
apiResponse.getPeertubes().get(0).getFileUrl(null, PeertubeActivity.this), apiResponse.getPeertubes().get(0),
apiResponse.getPeertubes().get(0).getStreamingPlaylists().size() > 0 ? apiResponse.getPeertubes().get(0).getStreamingPlaylists().get(0).getPlaylistUrl() : null, null,
null,
autoPlay, position, null, null, true); autoPlay, position, null, null, true);
player.prepare(); player.prepare();
player.setPlayWhenReady(autoPlay); player.setPlayWhenReady(autoPlay);
@ -1259,7 +1289,8 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
} }
private void stream(String videoURL, String streamingPlaylistsURLS, boolean autoPlay, long position, Uri subtitles, String lang) { private void stream(VideoData.Video video, String resolution, boolean autoPlay, long position, Uri subtitles, String lang) {
String videoURL = video.getFileUrl(resolution, PeertubeActivity.this);
if (videoURL != null && !videoURL.endsWith("m3u8")) { if (videoURL != null && !videoURL.endsWith("m3u8")) {
if (videoURL.endsWith(".torrent")) { if (videoURL.endsWith(".torrent")) {
torrentStream.startStream(videoURL); torrentStream.startStream(videoURL);
@ -1298,10 +1329,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
} }
} }
} else { } else {
if (streamingPlaylistsURLS == null && videoURL != null) { MediaItem mediaItem = new MediaItem.Builder().setUri(Uri.parse(videoURL)).build();
streamingPlaylistsURLS = videoURL;
}
MediaItem mediaItem = new MediaItem.Builder().setUri(Uri.parse(streamingPlaylistsURLS)).build();
HlsMediaSource hlsMediaSource = new HlsMediaSource.Factory(new DefaultHttpDataSourceFactory(System.getProperty("http.agent"))) HlsMediaSource hlsMediaSource = new HlsMediaSource.Factory(new DefaultHttpDataSourceFactory(System.getProperty("http.agent")))
.createMediaSource(mediaItem); .createMediaSource(mediaItem);
player.setMediaSource(hlsMediaSource); player.setMediaSource(hlsMediaSource);
@ -1340,8 +1368,21 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
} }
} }
private void startStream(String videoURL, String streamingPlaylistsURLS, boolean autoPlay, long position, Uri subtitles, String lang, boolean promptNSFW) { private void startStream(VideoData.Video video, String torrentLocal, String resolution, boolean autoPlay, long position, Uri subtitles, String lang, boolean promptNSFW) {
String videoURL;
if (torrentLocal != null) {
videoURL = torrentLocal;
} else {
videoURL = peertube.getFileUrl(resolution, PeertubeActivity.this);
}
if (peertube != null && peertube.isWaitTranscoding() && peertube.isLive()) {
View parentLayout = findViewById(android.R.id.content);
Snackbar snackbar = Snackbar.make(parentLayout, R.string.live_not_started, Snackbar.LENGTH_INDEFINITE);
snackbar.setAction(R.string.close, view -> finish());
snackbar.show();
return;
}
chromeCastVideoURL = videoURL; chromeCastVideoURL = videoURL;
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE); SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
String nsfwAction = sharedpreferences.getString(getString(R.string.set_video_sensitive_choice), Helper.BLUR); String nsfwAction = sharedpreferences.getString(getString(R.string.set_video_sensitive_choice), Helper.BLUR);
@ -1357,13 +1398,13 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
finish(); finish();
}); });
dialogBuilder.setPositiveButton(R.string.play, (dialog, id) -> { dialogBuilder.setPositiveButton(R.string.play, (dialog, id) -> {
stream(videoURL, streamingPlaylistsURLS, autoPlay, position, subtitles, lang); stream(video, resolution, autoPlay, position, subtitles, lang);
dialog.dismiss(); dialog.dismiss();
}); });
alertDialog = dialogBuilder.create(); alertDialog = dialogBuilder.create();
alertDialog.show(); alertDialog.show();
} else { } else {
stream(videoURL, streamingPlaylistsURLS, autoPlay, position, subtitles, lang); stream(video, resolution, autoPlay, position, subtitles, lang);
} }
@ -1591,6 +1632,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
@Override @Override
public void onAnimationStart(Animation animation) { public void onAnimationStart(Animation animation) {
} }
@Override @Override
public void onAnimationEnd(Animation animation) { public void onAnimationEnd(Animation animation) {
binding.peertubeInformationContainer.setVisibility(View.GONE); binding.peertubeInformationContainer.setVisibility(View.GONE);
@ -1743,8 +1785,9 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
binding.doubleTapPlayerView.setPlayer(player); binding.doubleTapPlayerView.setPlayer(player);
binding.loader.setVisibility(View.GONE); binding.loader.setVisibility(View.GONE);
startStream( startStream(
peertube.getFileUrl(res, PeertubeActivity.this), peertube,
peertube.getStreamingPlaylists().size() > 0 ? peertube.getStreamingPlaylists().get(0).getPlaylistUrl() : null, null,
res,
true, position, null, null, false); true, position, null, null, false);
} }
break; break;
@ -1783,7 +1826,8 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
binding.mediaVideo.player(player); binding.mediaVideo.player(player);
binding.doubleTapPlayerView.setPlayer(player); binding.doubleTapPlayerView.setPlayer(player);
startStream( startStream(
peertube.getFileUrl(null, PeertubeActivity.this), peertube,
null,
null, null,
true, true,
newPosition, newPosition,
@ -1842,7 +1886,6 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
} }
public void closeSubMenuMenuOptions() { public void closeSubMenuMenuOptions() {
DisplayMetrics displayMetrics = new DisplayMetrics(); DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
@ -2020,8 +2063,8 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
} }
} else if (peertube.isCommentsEnabled() && statusAction == REPLY) { } else if (peertube.isCommentsEnabled() && statusAction == REPLY) {
if (apiResponse.getComments() != null && apiResponse.getComments().size() > 0) { if (apiResponse.getComments() != null && apiResponse.getComments().size() > 0) {
commentsThread.add(position, apiResponse.getComments().get(0)); commentsThread.add(position + 1, apiResponse.getComments().get(0));
commentReplyListAdapter.notifyItemInserted(position); commentReplyListAdapter.notifyItemInserted(position + 1);
} }
} else if (statusAction == RetrofitPeertubeAPI.ActionType.REPORT_ACCOUNT) { } else if (statusAction == RetrofitPeertubeAPI.ActionType.REPORT_ACCOUNT) {
Toasty.success(PeertubeActivity.this, getString(R.string.successful_report), Toasty.LENGTH_LONG).show(); Toasty.success(PeertubeActivity.this, getString(R.string.successful_report), Toasty.LENGTH_LONG).show();
@ -2063,6 +2106,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
openMainMenuOptions(); openMainMenuOptions();
} }
}); });
} }
private void setRequestedOrientationCustom(int orientationCustom) { private void setRequestedOrientationCustom(int orientationCustom) {
@ -2272,8 +2316,6 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
} }
enum videoOrientation { enum videoOrientation {
LANDSCAPE, LANDSCAPE,
PORTRAIT PORTRAIT

View File

@ -163,8 +163,7 @@ public class PeertubeRegisterActivity extends AppCompatActivity {
} }
}); });
} else { } else {
String host = emailArray[1]; instance = HelperInstance.getLiveInstance(PeertubeRegisterActivity.this);
instance = HelperInstance.getPeertubeUrl(host);
} }
if (instance != null) { if (instance != null) {
instance = instance.toLowerCase().trim(); instance = instance.toLowerCase().trim();

View File

@ -37,7 +37,6 @@ import androidx.core.content.ContextCompat;
import androidx.documentfile.provider.DocumentFile; import androidx.documentfile.provider.DocumentFile;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import net.gotev.uploadservice.data.UploadNotificationAction; import net.gotev.uploadservice.data.UploadNotificationAction;
import net.gotev.uploadservice.data.UploadNotificationConfig; import net.gotev.uploadservice.data.UploadNotificationConfig;
import net.gotev.uploadservice.data.UploadNotificationStatusConfig; import net.gotev.uploadservice.data.UploadNotificationStatusConfig;

View File

@ -160,16 +160,14 @@ public class ShowChannelActivity extends AppCompatActivity {
if (accounts != null && accounts.size() > 0) { if (accounts != null && accounts.size() > 0) {
if (accounts.size() > 1) { if (accounts.size() > 1) {
final OwnAccountsAdapter accountsListAdapter = new OwnAccountsAdapter(ShowChannelActivity.this, accounts); final OwnAccountsAdapter accountsListAdapter = new OwnAccountsAdapter(ShowChannelActivity.this, accounts);
builderSingle.setAdapter(accountsListAdapter, (dialog, which) -> { builderSingle.setAdapter(accountsListAdapter, (dialog, which) -> new Thread(() -> {
new Thread(() -> {
try { try {
RetrofitPeertubeAPI peertubeAPI = new RetrofitPeertubeAPI(ShowChannelActivity.this, accounts.get(which).getHost(), accounts.get(which).getToken()); RetrofitPeertubeAPI peertubeAPI = new RetrofitPeertubeAPI(ShowChannelActivity.this, accounts.get(which).getHost(), accounts.get(which).getToken());
peertubeAPI.post(FOLLOW, channel.getAcct(), null); peertubeAPI.post(FOLLOW, channel.getAcct(), null);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
}).start(); }).start());
});
} else { } else {
RetrofitPeertubeAPI peertubeAPI = new RetrofitPeertubeAPI(ShowChannelActivity.this, accounts.get(0).getHost(), accounts.get(0).getToken()); RetrofitPeertubeAPI peertubeAPI = new RetrofitPeertubeAPI(ShowChannelActivity.this, accounts.get(0).getHost(), accounts.get(0).getToken());
peertubeAPI.post(FOLLOW, channel.getAcct(), null); peertubeAPI.post(FOLLOW, channel.getAcct(), null);
@ -362,7 +360,11 @@ public class ShowChannelActivity extends AppCompatActivity {
public void manageVIewRelationship(APIResponse apiResponse) { public void manageVIewRelationship(APIResponse apiResponse) {
if (apiResponse.getError() != null) { if (apiResponse.getError() != null) {
if (apiResponse.getError().getError().length() > 500) {
Toasty.info(ShowChannelActivity.this, getString(R.string.remote_account), Toast.LENGTH_LONG).show();
} else {
Toasty.error(ShowChannelActivity.this, apiResponse.getError().getError(), Toast.LENGTH_LONG).show(); Toasty.error(ShowChannelActivity.this, apiResponse.getError().getError(), Toast.LENGTH_LONG).show();
}
return; return;
} }
this.relationship = apiResponse.getRelationships(); this.relationship = apiResponse.getRelationships();

View File

@ -122,8 +122,11 @@ public class WebviewConnectActivity extends AppCompatActivity {
oauthParams.setClient_id(sharedpreferences.getString(Helper.CLIENT_ID, null)); oauthParams.setClient_id(sharedpreferences.getString(Helper.CLIENT_ID, null));
oauthParams.setClient_secret(sharedpreferences.getString(Helper.CLIENT_SECRET, null)); oauthParams.setClient_secret(sharedpreferences.getString(Helper.CLIENT_SECRET, null));
oauthParams.setGrant_type("password"); oauthParams.setGrant_type("password");
oauthParams.setScope("upload");
oauthParams.setResponse_type("code");
oauthParams.setUsername(username); oauthParams.setUsername(username);
oauthParams.setExternalAuthToken(externalAuthToken); oauthParams.setExternalAuthToken(externalAuthToken);
oauthParams.setPassword(externalAuthToken);
String instance = new URL(url).getHost(); String instance = new URL(url).getHost();
Token token = null; Token token = null;
try { try {

View File

@ -103,6 +103,21 @@ public interface PeertubeService {
@GET("client/locales/{local}/server.json") @GET("client/locales/{local}/server.json")
Call<Map<String, String>> getTranslations(@Path("local") String local); Call<Map<String, String>> getTranslations(@Path("local") String local);
//TOKEN
//Refresh
@FormUrlEncoded
@POST("users/token")
Call<Token> createOpenIdToken(
@Field("client_id") String client_id,
@Field("client_secret") String client_secret,
@Field("response_type") String response_type,
@Field("grant_type") String grant_type,
@Field("scope") String scope,
@Field("username") String username,
@Field("password") String password,
@Field("externalAuthToken") String externalAuthToken);
//TOKEN //TOKEN
//Refresh //Refresh
@FormUrlEncoded @FormUrlEncoded
@ -169,27 +184,55 @@ public interface PeertubeService {
//Timelines Authenticated //Timelines Authenticated
//Subscriber timeline //Subscriber timeline
@GET("users/me/subscriptions/videos?sort=-publishedAt") @GET("users/me/subscriptions/videos?sort=-publishedAt")
Call<VideoData> getSubscriptionVideos(@Header("Authorization") String credentials, @Query("start") String maxId, @Query("count") String count, @Query("languageOneOf") List<String> languageOneOf); Call<VideoData> getSubscriptionVideos(
@Header("Authorization") String credentials,
@Query("start") String maxId,
@Query("count") String coun,
@Query("languageOneOf") List<String> languageOneOf);
//Overview videos //Overview videos
@GET("overviews/videos") @GET("overviews/videos")
Call<OverviewVideo> getOverviewVideos(@Header("Authorization") String credentials, @Query("page") String page, @Query("languageOneOf") List<String> languageOneOf); Call<OverviewVideo> getOverviewVideos(
@Header("Authorization") String credentials,
@Query("page") String page,
@Query("nsfw") String nsfw,
@Query("languageOneOf") List<String> languageOneOf);
//Most liked videos //Most liked videos
@GET("videos?sort=-likes") @GET("videos?sort=-likes")
Call<VideoData> getMostLikedVideos(@Header("Authorization") String credentials, @Query("start") String maxId, @Query("count") String count, @Query("languageOneOf") List<String> languageOneOf); Call<VideoData> getMostLikedVideos(
@Header("Authorization") String credentials,
@Query("start") String maxId,
@Query("count") String count,
@Query("nsfw") String nsfw,
@Query("languageOneOf") List<String> languageOneOf);
//Trending videos //Trending videos
@GET("videos?sort=-trending") @GET("videos?sort=-trending")
Call<VideoData> getTrendingVideos(@Header("Authorization") String credentials, @Query("start") String maxId, @Query("count") String count, @Query("languageOneOf") List<String> languageOneOf); Call<VideoData> getTrendingVideos(
@Header("Authorization") String credentials,
@Query("start") String maxId,
@Query("count") String count,
@Query("nsfw") String nsfw,
@Query("languageOneOf") List<String> languageOneOf);
//Recently added videos //Recently added videos
@GET("videos?sort=-publishedAt") @GET("videos?sort=-publishedAt")
Call<VideoData> getRecentlyAddedVideos(@Header("Authorization") String credentials, @Query("start") String maxId, @Query("count") String count, @Query("languageOneOf") List<String> languageOneOf); Call<VideoData> getRecentlyAddedVideos(
@Header("Authorization") String credentials,
@Query("start") String maxId,
@Query("count") String count,
@Query("nsfw") String nsfw,
@Query("languageOneOf") List<String> languageOneOf);
//Local videos //Local videos
@GET("videos?sort=-publishedAt&filter=local") @GET("videos?sort=-publishedAt&filter=local")
Call<VideoData> getLocalVideos(@Header("Authorization") String credentials, @Query("start") String maxId, @Query("count") String count, @Query("languageOneOf") List<String> languageOneOf); Call<VideoData> getLocalVideos(
@Header("Authorization") String credentials,
@Query("start") String maxId,
@Query("count") String count,
@Query("nsfw") String nsfw,
@Query("languageOneOf") List<String> languageOneOf);
//History //History
@GET("users/me/history/videos") @GET("users/me/history/videos")
@ -197,6 +240,7 @@ public interface PeertubeService {
@Header("Authorization") String credentials, @Header("Authorization") String credentials,
@Query("start") String maxId, @Query("start") String maxId,
@Query("count") String count, @Query("count") String count,
@Query("nsfw") String nsfw,
@Query("startDate") String startDate, @Query("startDate") String startDate,
@Query("endDate") String endDate @Query("endDate") String endDate
); );
@ -211,7 +255,8 @@ public interface PeertubeService {
@Header("Authorization") String credentials, @Header("Authorization") String credentials,
@Query("search") String search, @Query("search") String search,
@Query("start") String maxId, @Query("start") String maxId,
@Query("count") String count); @Query("count") String count,
@Query("nsfw") String nsfw);
//Search channels //Search channels
@GET("search/video-channels") @GET("search/video-channels")
@ -228,7 +273,8 @@ public interface PeertubeService {
@Header("Authorization") String credentials, @Header("Authorization") String credentials,
@Query("tagsOneOf") List<String> tagsOneOf, @Query("tagsOneOf") List<String> tagsOneOf,
@Query("start") String maxId, @Query("start") String maxId,
@Query("count") String count); @Query("count") String count,
@Query("nsfw") String nsfw);
//Get notifications //Get notifications
@GET("users/me/notifications") @GET("users/me/notifications")
@ -254,9 +300,17 @@ public interface PeertubeService {
@GET("users/me/videos?sort=-publishedAt") @GET("users/me/videos?sort=-publishedAt")
Call<VideoData> getMyVideos(@Header("Authorization") String credentials, @Query("start") String maxId, @Query("count") String count); Call<VideoData> getMyVideos(@Header("Authorization") String credentials, @Query("start") String maxId, @Query("count") String count);
//Get my video //Get user videos
@GET("accounts/{name}/videos?sort=-publishedAt") @GET("accounts/{name}/videos?sort=-publishedAt")
Call<VideoData> getVideosForAccount(@Path("name") String name, @Query("start") String maxId, @Query("count") String count); Call<VideoData> getVideosForAccount(
@Path("name") String name,
@Query("start") String maxId,
@Query("count") String count,
@Query("nsfw") String nsfw
);
@POST("videos/{id}/views")
Call<String> postView(@Path("id") String id);
@Multipart @Multipart
@PUT("videos/{id}") @PUT("videos/{id}")
@ -303,7 +357,11 @@ public interface PeertubeService {
Call<ChannelData> getAllChannels(); Call<ChannelData> getAllChannels();
@GET("video-channels/{channelHandle}/videos") @GET("video-channels/{channelHandle}/videos")
Call<VideoData> getChannelVideos(@Path("channelHandle") String channelHandle, @Query("start") String maxId, @Query("count") String count); Call<VideoData> getChannelVideos(
@Path("channelHandle") String channelHandle,
@Query("start") String maxId,
@Query("count") String count,
@Query("nsfw") String nsfw);
@POST("video-channels") @POST("video-channels")
Call<ChannelData.ChannelCreation> addChannel(@Header("Authorization") String credentials, @Body ChannelParams channelParams); Call<ChannelData.ChannelCreation> addChannel(@Header("Authorization") String credentials, @Body ChannelParams channelParams);

View File

@ -23,6 +23,7 @@ import android.net.Uri;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.webkit.MimeTypeMap; import android.webkit.MimeTypeMap;
import android.webkit.URLUtil;
import androidx.documentfile.provider.DocumentFile; import androidx.documentfile.provider.DocumentFile;
@ -90,7 +91,7 @@ import retrofit2.Response;
import retrofit2.Retrofit; import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.converter.gson.GsonConverterFactory;
@SuppressWarnings({"unused", "RedundantSuppression"}) @SuppressWarnings({"unused", "RedundantSuppression", "ConstantConditions"})
public class RetrofitPeertubeAPI { public class RetrofitPeertubeAPI {
private final String finalUrl; private final String finalUrl;
@ -99,6 +100,7 @@ public class RetrofitPeertubeAPI {
private final String count; private final String count;
private String token; private String token;
private Set<String> selection; private Set<String> selection;
private String showNSFWVideos = "both";
public RetrofitPeertubeAPI(Context context) { public RetrofitPeertubeAPI(Context context) {
_context = context; _context = context;
@ -106,6 +108,14 @@ public class RetrofitPeertubeAPI {
finalUrl = "https://" + HelperInstance.getLiveInstance(context) + "/api/v1/"; finalUrl = "https://" + HelperInstance.getLiveInstance(context) + "/api/v1/";
SharedPreferences sharedpreferences = _context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); SharedPreferences sharedpreferences = _context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
count = String.valueOf(sharedpreferences.getInt(Helper.SET_VIDEOS_PER_PAGE, Helper.VIDEOS_PER_PAGE)); count = String.valueOf(sharedpreferences.getInt(Helper.SET_VIDEOS_PER_PAGE, Helper.VIDEOS_PER_PAGE));
String currentSensitive = sharedpreferences.getString(_context.getString(R.string.set_video_sensitive_choice), Helper.BLUR);
if (currentSensitive.compareTo(Helper.DO_NOT_LIST) == 0) {
showNSFWVideos = "false";
} else if (currentSensitive.compareTo(Helper.BLUR) == 0) {
showNSFWVideos = "both";
} else {
showNSFWVideos = "true";
}
} }
public RetrofitPeertubeAPI(Context context, String instance, String token) { public RetrofitPeertubeAPI(Context context, String instance, String token) {
@ -115,18 +125,21 @@ public class RetrofitPeertubeAPI {
finalUrl = "https://" + instance + "/api/v1/"; finalUrl = "https://" + instance + "/api/v1/";
SharedPreferences sharedpreferences = _context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); SharedPreferences sharedpreferences = _context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
count = String.valueOf(sharedpreferences.getInt(Helper.SET_VIDEOS_PER_PAGE, Helper.VIDEOS_PER_PAGE)); count = String.valueOf(sharedpreferences.getInt(Helper.SET_VIDEOS_PER_PAGE, Helper.VIDEOS_PER_PAGE));
String currentSensitive = sharedpreferences.getString(_context.getString(R.string.set_video_sensitive_choice), Helper.BLUR);
if (currentSensitive.compareTo(Helper.DO_NOT_LIST) == 0) {
showNSFWVideos = "false";
} else if (currentSensitive.compareTo(Helper.BLUR) == 0) {
showNSFWVideos = "both";
} else {
showNSFWVideos = "true";
}
} }
public static void updateCredential(Activity activity, String token, String client_id, String client_secret, String refresh_token, String host) { public static void updateCredential(Activity activity, String token, String client_id, String client_secret, String refresh_token, String host) {
new Thread(() -> { new Thread(() -> {
AccountData.Account account; AccountData.Account account;
String instance; String instance = host;
if (host.startsWith("tube") || BuildConfig.full_instances) {
instance = host;
} else {
instance = HelperInstance.getPeertubeUrl(host);
}
try { try {
UserMe userMe = new RetrofitPeertubeAPI(activity, instance, token).verifyCredentials(); UserMe userMe = new RetrofitPeertubeAPI(activity, instance, token).verifyCredentials();
account = userMe.getAccount(); account = userMe.getAccount();
@ -194,6 +207,9 @@ public class RetrofitPeertubeAPI {
} }
private PeertubeService initTranslation() { private PeertubeService initTranslation() {
if (!URLUtil.isValidUrl("https://" + instance)) {
return null;
}
Retrofit retrofit = new Retrofit.Builder() Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://" + instance) .baseUrl("https://" + instance)
.addConverterFactory(GsonConverterFactory.create()) .addConverterFactory(GsonConverterFactory.create())
@ -208,7 +224,9 @@ public class RetrofitPeertubeAPI {
public Token manageToken(OauthParams oauthParams) throws Error { public Token manageToken(OauthParams oauthParams) throws Error {
PeertubeService peertubeService = init(); PeertubeService peertubeService = init();
Call<Token> refreshTokenCall = null; Call<Token> refreshTokenCall = null;
if (oauthParams.getGrant_type().compareTo("password") == 0) { if (oauthParams.getExternalAuthToken() != null) {
refreshTokenCall = peertubeService.createOpenIdToken(oauthParams.getClient_id(), oauthParams.getClient_secret(), oauthParams.getResponse_type(), oauthParams.getGrant_type(), oauthParams.getScope(), oauthParams.getUsername(), oauthParams.getPassword(), oauthParams.getExternalAuthToken());
} else if (oauthParams.getGrant_type().compareTo("password") == 0) {
refreshTokenCall = peertubeService.createToken(oauthParams.getClient_id(), oauthParams.getClient_secret(), oauthParams.getGrant_type(), oauthParams.getUsername(), oauthParams.getPassword()); refreshTokenCall = peertubeService.createToken(oauthParams.getClient_id(), oauthParams.getClient_secret(), oauthParams.getGrant_type(), oauthParams.getUsername(), oauthParams.getPassword());
} else if (oauthParams.getGrant_type().compareTo("refresh_token") == 0) { } else if (oauthParams.getGrant_type().compareTo("refresh_token") == 0) {
refreshTokenCall = peertubeService.refreshToken(oauthParams.getClient_id(), oauthParams.getClient_secret(), oauthParams.getRefresh_token(), oauthParams.getGrant_type()); refreshTokenCall = peertubeService.refreshToken(oauthParams.getClient_id(), oauthParams.getClient_secret(), oauthParams.getRefresh_token(), oauthParams.getGrant_type());
@ -245,6 +263,19 @@ public class RetrofitPeertubeAPI {
} }
/**
* POST a view count for a video
*/
public void postView(String videoUuid) {
PeertubeService peertubeService = init();
Call<String> postViewCall = peertubeService.postView(videoUuid);
try {
Response<String> dd = postViewCall.execute();
} catch (IOException ignored) {
}
}
/** /**
* Retrieve notifications * Retrieve notifications
* *
@ -335,7 +366,7 @@ public class RetrofitPeertubeAPI {
public APIResponse getVideosForChannel(String channelId, String max_id) { public APIResponse getVideosForChannel(String channelId, String max_id) {
APIResponse apiResponse = new APIResponse(); APIResponse apiResponse = new APIResponse();
PeertubeService peertubeService = init(); PeertubeService peertubeService = init();
Call<VideoData> videoCall = peertubeService.getChannelVideos(channelId, max_id, count); Call<VideoData> videoCall = peertubeService.getChannelVideos(channelId, max_id, count, showNSFWVideos);
if (videoCall != null) { if (videoCall != null) {
try { try {
Response<VideoData> response = videoCall.execute(); Response<VideoData> response = videoCall.execute();
@ -380,7 +411,7 @@ public class RetrofitPeertubeAPI {
public APIResponse getHistory(String max_id, String startDate, String endDate) { public APIResponse getHistory(String max_id, String startDate, String endDate) {
APIResponse apiResponse = new APIResponse(); APIResponse apiResponse = new APIResponse();
PeertubeService peertubeService = init(); PeertubeService peertubeService = init();
Call<VideoData> videoCall = peertubeService.getHistory(getToken(), max_id, count, startDate, endDate); Call<VideoData> videoCall = peertubeService.getHistory(getToken(), max_id, count, showNSFWVideos, startDate, endDate);
if (videoCall != null) { if (videoCall != null) {
try { try {
Response<VideoData> response = videoCall.execute(); Response<VideoData> response = videoCall.execute();
@ -409,29 +440,29 @@ public class RetrofitPeertubeAPI {
videoCall = peertubeService.getMyVideos(getToken(), max_id, count); videoCall = peertubeService.getMyVideos(getToken(), max_id, count);
break; break;
case ACCOUNT_VIDEOS: case ACCOUNT_VIDEOS:
videoCall = peertubeService.getVideosForAccount(forAccount, max_id, count); videoCall = peertubeService.getVideosForAccount(forAccount, max_id, count, showNSFWVideos);
break; break;
case SUBSCRIBTIONS: case SUBSCRIBTIONS:
if (forAccount == null) { if (forAccount == null) {
videoCall = peertubeService.getSubscriptionVideos(getToken(), max_id, count, filter); videoCall = peertubeService.getSubscriptionVideos(getToken(), max_id, count, filter);
} else { } else {
videoCall = peertubeService.getChannelVideos(forAccount, max_id, count); videoCall = peertubeService.getChannelVideos(forAccount, max_id, count, showNSFWVideos);
} }
break; break;
case MOST_LIKED: case MOST_LIKED:
videoCall = peertubeService.getMostLikedVideos(getToken(), max_id, count, filter); videoCall = peertubeService.getMostLikedVideos(getToken(), max_id, count, showNSFWVideos, filter);
break; break;
case LOCAL: case LOCAL:
videoCall = peertubeService.getLocalVideos(getToken(), max_id, count, filter); videoCall = peertubeService.getLocalVideos(getToken(), max_id, count, showNSFWVideos, filter);
break; break;
case TRENDING: case TRENDING:
videoCall = peertubeService.getTrendingVideos(getToken(), max_id, count, filter); videoCall = peertubeService.getTrendingVideos(getToken(), max_id, count, showNSFWVideos, filter);
break; break;
case HISTORY: case HISTORY:
videoCall = peertubeService.getHistory(getToken(), max_id, count, null, null); videoCall = peertubeService.getHistory(getToken(), max_id, count, showNSFWVideos, null, null);
break; break;
case RECENT: case RECENT:
videoCall = peertubeService.getRecentlyAddedVideos(getToken(), max_id, count, filter); videoCall = peertubeService.getRecentlyAddedVideos(getToken(), max_id, count, showNSFWVideos, filter);
break; break;
} }
if (videoCall != null) { if (videoCall != null) {
@ -462,7 +493,7 @@ public class RetrofitPeertubeAPI {
APIResponse apiResponse = new APIResponse(); APIResponse apiResponse = new APIResponse();
PeertubeService peertubeService = init(); PeertubeService peertubeService = init();
ArrayList<String> filter = selection != null ? new ArrayList<>(selection) : null; ArrayList<String> filter = selection != null ? new ArrayList<>(selection) : null;
Call<OverviewVideo> overviewVideoCall = peertubeService.getOverviewVideos(getToken(), page, filter); Call<OverviewVideo> overviewVideoCall = peertubeService.getOverviewVideos(getToken(), page, showNSFWVideos, filter);
try { try {
Response<OverviewVideo> response = overviewVideoCall.execute(); Response<OverviewVideo> response = overviewVideoCall.execute();
if (response.isSuccessful() && response.body() != null) { if (response.isSuccessful() && response.body() != null) {
@ -902,7 +933,7 @@ public class RetrofitPeertubeAPI {
*/ */
public APIResponse searchNextVideos(List<String> tags) { public APIResponse searchNextVideos(List<String> tags) {
PeertubeService peertubeService = init(); PeertubeService peertubeService = init();
Call<VideoData> searchVideosCall = peertubeService.searchNextVideo(getToken(), tags, "0", "20"); Call<VideoData> searchVideosCall = peertubeService.searchNextVideo(getToken(), tags, "0", "20", showNSFWVideos);
APIResponse apiResponse = new APIResponse(); APIResponse apiResponse = new APIResponse();
try { try {
Response<VideoData> response = searchVideosCall.execute(); Response<VideoData> response = searchVideosCall.execute();
@ -928,7 +959,7 @@ public class RetrofitPeertubeAPI {
*/ */
public APIResponse searchPeertube(String query, String max_id) { public APIResponse searchPeertube(String query, String max_id) {
PeertubeService peertubeService = init(); PeertubeService peertubeService = init();
Call<VideoData> searchVideosCall = peertubeService.searchVideos(getToken(), query, max_id, count); Call<VideoData> searchVideosCall = peertubeService.searchVideos(getToken(), query, max_id, count, showNSFWVideos);
APIResponse apiResponse = new APIResponse(); APIResponse apiResponse = new APIResponse();
try { try {
Response<VideoData> response = searchVideosCall.execute(); Response<VideoData> response = searchVideosCall.execute();

View File

@ -88,6 +88,8 @@ public class VideoData {
private List<File> files; private List<File> files;
@SerializedName("id") @SerializedName("id")
private String id; private String id;
@SerializedName("isLive")
private boolean isLive = false;
@SerializedName("isLocal") @SerializedName("isLocal")
private boolean isLocal; private boolean isLocal;
@SerializedName("language") @SerializedName("language")
@ -163,6 +165,7 @@ public class VideoData {
this.files = new ArrayList<>(); this.files = new ArrayList<>();
in.readList(this.files, File.class.getClassLoader()); in.readList(this.files, File.class.getClassLoader());
this.id = in.readString(); this.id = in.readString();
this.isLive = in.readByte() != 0;
this.isLocal = in.readByte() != 0; this.isLocal = in.readByte() != 0;
this.language = in.readParcelable(ItemStr.class.getClassLoader()); this.language = in.readParcelable(ItemStr.class.getClassLoader());
this.licence = in.readParcelable(Item.class.getClassLoader()); this.licence = in.readParcelable(Item.class.getClassLoader());
@ -194,18 +197,9 @@ public class VideoData {
public String getFileUrl(String resolution, Context context) { public String getFileUrl(String resolution, Context context) {
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
int mode = sharedpreferences.getInt(Helper.SET_VIDEO_MODE, Helper.VIDEO_MODE_NORMAL); int mode = sharedpreferences.getInt(Helper.SET_VIDEO_MODE, Helper.VIDEO_MODE_NORMAL);
List<File> files = getAllFile(context);
if (files != null && files.size() > 0) { if (files != null && files.size() > 0) {
return getFile(context, files, resolution, mode); return getFile(context, files, resolution, mode);
} else if (streamingPlaylists != null && streamingPlaylists.size() > 0) {
List<File> files = new ArrayList<>();
for (StreamingPlaylists streamingPlaylists : streamingPlaylists) {
if (streamingPlaylists.getFiles().size() > 0) {
files.addAll(streamingPlaylists.getFiles());
} else {
return streamingPlaylists.getPlaylistUrl();
}
}
return getFile(context, files, resolution, mode);
} }
return null; return null;
} }
@ -213,7 +207,7 @@ public class VideoData {
public List<File> getAllFile(Context context) { public List<File> getAllFile(Context context) {
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
int mode = sharedpreferences.getInt(Helper.SET_VIDEO_MODE, Helper.VIDEO_MODE_NORMAL); int mode = sharedpreferences.getInt(Helper.SET_VIDEO_MODE, Helper.VIDEO_MODE_NORMAL);
if (files != null) { if (files != null && files.size() > 0) {
return files; return files;
} else if (streamingPlaylists != null) { } else if (streamingPlaylists != null) {
List<File> files = new ArrayList<>(); List<File> files = new ArrayList<>();
@ -222,7 +216,7 @@ public class VideoData {
} }
return files; return files;
} }
return null; return files;
} }
@ -413,6 +407,14 @@ public class VideoData {
this.id = id; this.id = id;
} }
public boolean isLive() {
return isLive;
}
public void setLive(boolean live) {
isLive = live;
}
public boolean isLocal() { public boolean isLocal() {
return isLocal; return isLocal;
} }
@ -668,6 +670,7 @@ public class VideoData {
dest.writeString(this.embedUrl); dest.writeString(this.embedUrl);
dest.writeList(this.files); dest.writeList(this.files);
dest.writeString(this.id); dest.writeString(this.id);
dest.writeByte(this.isLive ? (byte) 1 : (byte) 0);
dest.writeByte(this.isLocal ? (byte) 1 : (byte) 0); dest.writeByte(this.isLocal ? (byte) 1 : (byte) 0);
dest.writeParcelable(this.language, flags); dest.writeParcelable(this.language, flags);
dest.writeParcelable(this.licence, flags); dest.writeParcelable(this.licence, flags);

View File

@ -23,7 +23,6 @@ import com.google.gson.annotations.SerializedName;
import java.util.List; import java.util.List;
@SuppressWarnings({"unused", "RedundantSuppression"}) @SuppressWarnings({"unused", "RedundantSuppression"})
public class VideoPlaylistData { public class VideoPlaylistData {

View File

@ -38,7 +38,8 @@ public class OauthParams {
private String refresh_token; private String refresh_token;
@SerializedName("access_token") @SerializedName("access_token")
private String access_token; private String access_token;
@SerializedName("response_type")
private String response_type;
public String getClient_secret() { public String getClient_secret() {
return client_secret; return client_secret;
@ -111,4 +112,12 @@ public class OauthParams {
public void setAccess_token(String access_token) { public void setAccess_token(String access_token) {
this.access_token = access_token; this.access_token = access_token;
} }
public String getResponse_type() {
return response_type;
}
public void setResponse_type(String response_type) {
this.response_type = response_type;
}
} }

View File

@ -19,11 +19,14 @@ import android.graphics.Color;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils; import androidx.core.graphics.ColorUtils;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import java.util.List; import java.util.List;
import app.fedilab.fedilabtube.client.data.ChannelData; import app.fedilab.fedilabtube.client.data.ChannelData;
import app.fedilab.fedilabtube.databinding.DrawerHorizontalAccountBinding; import app.fedilab.fedilabtube.databinding.DrawerHorizontalAccountBinding;
import app.fedilab.fedilabtube.helper.Helper; import app.fedilab.fedilabtube.helper.Helper;

View File

@ -75,11 +75,11 @@ public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
private final List<Comment> comments; private final List<Comment> comments;
private final CommentListAdapter commentListAdapter; private final CommentListAdapter commentListAdapter;
private final boolean isThread; private final boolean isThread;
private final String instance;
private final boolean sepiaSearch;
public AllCommentRemoved allCommentRemoved; public AllCommentRemoved allCommentRemoved;
boolean isVideoOwner; boolean isVideoOwner;
private Context context; private Context context;
private final String instance;
private final boolean sepiaSearch;
public CommentListAdapter(List<Comment> comments, boolean isVideoOwner, boolean isThread, String instance, boolean sepiaSearch) { public CommentListAdapter(List<Comment> comments, boolean isVideoOwner, boolean isThread, String instance, boolean sepiaSearch) {
this.comments = comments; this.comments = comments;

View File

@ -147,7 +147,15 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
Helper.loadGiF(context, instance, video.getChannel().getAvatar() != null ? video.getChannel().getAvatar().getPath() : null, holder.binding.peertubeProfile); Helper.loadGiF(context, instance, video.getChannel().getAvatar() != null ? video.getChannel().getAvatar().getPath() : null, holder.binding.peertubeProfile);
holder.binding.peertubeTitle.setText(video.getName()); holder.binding.peertubeTitle.setText(video.getName());
if (video.isLive()) {
holder.binding.peertubeDuration.setText(R.string.live);
holder.binding.peertubeDuration.setBackgroundResource(R.drawable.rounded_live);
} else {
holder.binding.peertubeDuration.setText(Helper.secondsToString(video.getDuration())); holder.binding.peertubeDuration.setText(Helper.secondsToString(video.getDuration()));
holder.binding.peertubeDuration.setBackgroundResource(R.drawable.rounded_corner);
}
holder.binding.peertubeDate.setText(String.format(" - %s", Helper.dateDiff(context, video.getCreatedAt()))); holder.binding.peertubeDate.setText(String.format(" - %s", Helper.dateDiff(context, video.getCreatedAt())));
holder.binding.peertubeViews.setText(context.getString(R.string.number_view_video, Helper.withSuffix(video.getViews()))); holder.binding.peertubeViews.setText(context.getString(R.string.number_view_video, Helper.withSuffix(video.getViews())));
@ -400,14 +408,6 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
} }
} }
public interface RelationShipListener {
Map<String, Boolean> getRelationShip();
}
public interface PlaylistListener {
Map<String, List<PlaylistExist>> getPlaylist();
}
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
private void loadImage(ImageView target, String instance, String urlPreview, String thumbnail, boolean blur) { private void loadImage(ImageView target, String instance, String urlPreview, String thumbnail, boolean blur) {
if (urlPreview == null || urlPreview.startsWith("null")) { if (urlPreview == null || urlPreview.startsWith("null")) {
@ -470,6 +470,14 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
} }
public interface RelationShipListener {
Map<String, Boolean> getRelationShip();
}
public interface PlaylistListener {
Map<String, List<PlaylistExist>> getPlaylist();
}
static class ViewHolder extends RecyclerView.ViewHolder { static class ViewHolder extends RecyclerView.ViewHolder {
DrawerPeertubeBinding binding; DrawerPeertubeBinding binding;

View File

@ -33,7 +33,6 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.widget.PopupMenu; import androidx.appcompat.widget.PopupMenu;
import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityCompat;

View File

@ -68,8 +68,8 @@ import static app.fedilab.fedilabtube.PeertubeUploadActivity.MY_PERMISSIONS_REQU
public class DisplayChannelsFragment extends Fragment implements ChannelListAdapter.AllChannelRemoved, ChannelListAdapter.EditAlertDialog { public class DisplayChannelsFragment extends Fragment implements ChannelListAdapter.AllChannelRemoved, ChannelListAdapter.EditAlertDialog {
private Context context;
private static final int PICK_AVATAR = 467; private static final int PICK_AVATAR = 467;
private Context context;
private ChannelListAdapter channelListAdapter; private ChannelListAdapter channelListAdapter;
private List<ChannelData.Channel> channels; private List<ChannelData.Channel> channels;
private String name; private String name;

View File

@ -30,7 +30,6 @@ import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.EditText; import android.widget.EditText;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.Toast; import android.widget.Toast;

View File

@ -127,6 +127,7 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
startDate = bundle.getString("startDate", null); startDate = bundle.getString("startDate", null);
endDate = bundle.getString("endDate", null); endDate = bundle.getString("endDate", null);
} }
if (channel != null) { if (channel != null) {
channelId = channel.getAcct(); channelId = channel.getAcct();
} else if (account != null) { } else if (account != null) {
@ -324,9 +325,14 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
if (this.peertubes == null || apiResponse == null || (apiResponse.getError() != null)) { if (this.peertubes == null || apiResponse == null || (apiResponse.getError() != null)) {
if (apiResponse == null) if (apiResponse == null)
Toasty.error(context, context.getString(R.string.toast_error), Toast.LENGTH_LONG).show(); Toasty.error(context, context.getString(R.string.toast_error), Toast.LENGTH_LONG).show();
else { else if (apiResponse.getError() != null) {
if (apiResponse.getError().getError().length() > 500) {
Toasty.info(context, getString(R.string.remote_account), Toast.LENGTH_LONG).show();
} else {
Toasty.error(context, apiResponse.getError().getError(), Toast.LENGTH_LONG).show(); Toasty.error(context, apiResponse.getError().getError(), Toast.LENGTH_LONG).show();
} }
}
binding.swipeContainer.setRefreshing(false); binding.swipeContainer.setRefreshing(false);
flag_loading = false; flag_loading = false;
return; return;
@ -436,12 +442,10 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
@Override @Override
public void onDestroyView() { public void onDestroyView() {
if (binding.lvVideos != null) {
try { try {
binding.lvVideos.setAdapter(null); binding.lvVideos.setAdapter(null);
} catch (Exception ignored) { } catch (Exception ignored) {
} }
}
super.onDestroyView(); super.onDestroyView();
} }

View File

@ -16,6 +16,7 @@ package app.fedilab.fedilabtube.helper;
import java.util.List; import java.util.List;
import app.fedilab.fedilabtube.client.data.CommentData; import app.fedilab.fedilabtube.client.data.CommentData;
public class CommentDecorationHelper { public class CommentDecorationHelper {

View File

@ -80,7 +80,6 @@ import static android.content.Context.DOWNLOAD_SERVICE;
public class Helper { public class Helper {
public static PeertubeInformation peertubeInformation;
public static final int RELOAD_MYVIDEOS = 10; public static final int RELOAD_MYVIDEOS = 10;
public static final String SET_VIDEO_MODE = "set_video_mode"; public static final String SET_VIDEO_MODE = "set_video_mode";
public static final String SET_QUALITY_MODE = "set_quality_mode"; public static final String SET_QUALITY_MODE = "set_quality_mode";
@ -132,8 +131,7 @@ public class Helper {
public static final int VIDEOS_PER_PAGE = 10; public static final int VIDEOS_PER_PAGE = 10;
public static final String RECEIVE_ACTION = "receive_action"; public static final String RECEIVE_ACTION = "receive_action";
public static final String SET_UNFOLLOW_VALIDATION = "set_unfollow_validation"; public static final String SET_UNFOLLOW_VALIDATION = "set_unfollow_validation";
public static PeertubeInformation peertubeInformation;
/** /**
* Convert a date in String -> format yyyy-MM-dd HH:mm:ss * Convert a date in String -> format yyyy-MM-dd HH:mm:ss

View File

@ -14,49 +14,25 @@ package app.fedilab.fedilabtube.helper;
* You should have received a copy of the GNU General Public License along with TubeLab; if not, * You should have received a copy of the GNU General Public License along with TubeLab; if not,
* see <http://www.gnu.org/licenses>. */ * see <http://www.gnu.org/licenses>. */
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
public class HelperAcadInstance { public class HelperAcadInstance {
//List of available academies public static Map<String, String> instances_themes;
public static String[] openid = {
"ac-normandie.fr",
"education.fr",
"education.gouv.fr"
//TODO: remove this one used for tests
// "ac-orleans-tours.fr"
};
public static String[] academies = {
"ac-aix-marseille.fr",
"ac-amiens.fr",
"ac-besancon.fr",
"ac-bordeaux.fr",
"clermont-ferrand.fr",
"ac-corse.fr",
"ac-creteil.fr",
"ac-dijon.fr",
"ac-grenoble.fr",
"education.fr",
"ac-lille.fr",
"ac-limoges.fr",
"ac-lyon.fr",
"ac-mayotte.fr",
"ac-montpellier.fr",
"ac-nancy.fr",
"ac-nantes.fr",
"ac-normandie.fr",
"ac-orleans-tours.fr",
"ac-paris.fr",
"ac-poitiers.fr",
"outremer.fr",
"ac-rennes.fr",
"ac-strasbourg.fr",
"ac-toulouse.fr",
"ac-versailles.fr"
};
public static String LOCAL = "LOCALES";
public static String DISCOVER = "DECOUVRIR";
public static String MOSTLIKED = "PLUS_APPRECIEES";
public static String RECENTLY_ADDED = "AJOUTE_RECEMMENT";
public static String TRENDING = "TENDANCE";
public static String HISTORY = "HISTORIQUE";
public static String SUBSCRIPTIONS = "ABONNEMENTS";
public static String MYVIDEOS = "VIDEOS";
//List of available emails
public static String[] valideEmails = { public static String[] valideEmails = {
"ac-aix-marseille.fr", "ac-aix-marseille.fr",
"ac-amiens.fr", "ac-amiens.fr",
@ -95,4 +71,20 @@ public class HelperAcadInstance {
"igesr.gouv.fr" "igesr.gouv.fr"
}; };
static {
Map<String, String> is = new LinkedHashMap<>();
is.put("Normandie", "tube-normandie.beta.education.fr");
is.put("Enseignement professionnel", "tube-enseignement-professionnel.apps.education.fr");
is.put("Action éducative", "tube-action-educative.apps.education.fr");
is.put("Numérique éducatif", "tube-numerique-educatif.apps.education.fr");
is.put("Institutionnel", "tube-institutionnelle.apps.education.fr");
is.put("2d - langues vivantes", "tube-2d-langues-vivantes.apps.education.fr");
is.put("2d - éducation physique et sportive", "tube-2d-education-physique-et-sportive.apps.education.fr");
is.put("2d - arts, lettres et sciences humaines", "tube-2d-arts-lettres-sciences-humaines.apps.education.fr");
is.put("Maternelle", "tube-maternelle.apps.education.fr");
is.put("Cycle 2", "tube-cycle-2.apps.education.fr");
is.put("Cycle 3", "tube-cycle-3.apps.education.fr");
instances_themes = Collections.unmodifiableMap(is);
}
} }

View File

@ -23,40 +23,6 @@ import app.fedilab.fedilabtube.BuildConfig;
* see <http://www.gnu.org/licenses>. */ * see <http://www.gnu.org/licenses>. */
public class HelperInstance { public class HelperInstance {
/**
* Returns the peertube URL depending of the academic domain name
*
* @param acad String academic domain name
* @return String the peertube URL
*/
public static String getPeertubeUrl(String acad) {
if (BuildConfig.full_instances) {
return acad;
}
if (acad.compareTo("education.gouv.fr") == 0 || acad.compareTo("igesr.gouv.fr") == 0) {
acad = "education.fr";
} else if (acad.compareTo("ac-nancy-metz.fr") == 0) {
acad = "ac-nancy.fr";
} else if (acad.compareTo("clermont.fr") == 0) {
acad = "clermont-ferrand.fr";
} else if (acad.compareTo("ac-wf.wf") == 0 || acad.compareTo("ac-mayotte.fr") == 0 || acad.compareTo("ac-noumea.nc") == 0
|| acad.compareTo("ac-guadeloupe.fr") == 0 || acad.compareTo("monvr.pf") == 0 || acad.compareTo("ac-reunion.fr") == 0 ||
acad.compareTo("ac-martinique.fr") == 0 || acad.compareTo("ac-guyane.fr") == 0
) {
acad = "outremer.fr";
}
if (!acad.contains("ac-lyon.fr")) {
//TODO: remove hack for test with openid
/*if( acad.contains("orleans-tours.fr")) {
return "tube-normandie.beta.education.fr";
}*/
return "tube-" + acad.replaceAll("ac-|\\.fr", "") + ".beta.education.fr";
} else {
return "tube.ac-lyon.fr";
}
}
/** /**
* Returns the instance of the authenticated user * Returns the instance of the authenticated user
@ -75,15 +41,11 @@ public class HelperInstance {
} else if (BuildConfig.FLAVOR.compareTo("queermotion") == 0) { } else if (BuildConfig.FLAVOR.compareTo("queermotion") == 0) {
return sharedpreferences.getString(Helper.PREF_INSTANCE, "queermotion.org"); return sharedpreferences.getString(Helper.PREF_INSTANCE, "queermotion.org");
} else { } else {
acad = sharedpreferences.getString(Helper.PREF_INSTANCE, "tube.ac-lyon.fr"); acad = sharedpreferences.getString(Helper.PREF_INSTANCE, "tube-institutionnelle.apps.education.fr");
if (acad == null) { if (acad == null) {
acad = "tube.ac-lyon.fr"; acad = "tube-institutionnelle.apps.education.fr";
} }
if (acad.startsWith("tube-")) {
return acad; return acad;
} else {
return getPeertubeUrl(acad);
}
} }
} }

View File

@ -72,7 +72,12 @@ public class AccountsVM extends AndroidViewModel {
Context _mContext = getApplication().getApplicationContext(); Context _mContext = getApplication().getApplicationContext();
new Thread(() -> { new Thread(() -> {
try { try {
RetrofitPeertubeAPI retrofitPeertubeAPI = new RetrofitPeertubeAPI(_mContext); RetrofitPeertubeAPI retrofitPeertubeAPI;
if (acct.split("@").length > 1) {
retrofitPeertubeAPI = new RetrofitPeertubeAPI(_mContext, acct.split("@")[1], null);
} else {
retrofitPeertubeAPI = new RetrofitPeertubeAPI(_mContext);
}
APIResponse apiResponse = retrofitPeertubeAPI.getAccount(acct); APIResponse apiResponse = retrofitPeertubeAPI.getAccount(acct);
Handler mainHandler = new Handler(Looper.getMainLooper()); Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse); Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse);

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke
android:width="1dp"
android:color="@color/red_1" />
<solid android:color="@color/red_1" />
<padding
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<corners android:radius="5dp" />
</shape>

View File

@ -120,6 +120,36 @@
android:importantForAutofill="no" /> android:importantForAutofill="no" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/instance_picker_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="@string/instances_picker"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Spinner
android:id="@+id/instance_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="20dp"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/login_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/instance_picker_title" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="login_passwd_container,instance_picker" />
<Button <Button
android:id="@+id/login_button" android:id="@+id/login_button"
style="@style/Base.Widget.AppCompat.Button.Colored" style="@style/Base.Widget.AppCompat.Button.Colored"
@ -139,7 +169,7 @@
android:textSize="20sp" android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/login_passwd_container" /> app:layout_constraintTop_toBottomOf="@id/barrier" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout> </LinearLayout>

View File

@ -112,21 +112,22 @@
android:id="@+id/number_of_replies" android:id="@+id/number_of_replies"
app:layout_constraintTop_toBottomOf="@+id/comment_content" app:layout_constraintTop_toBottomOf="@+id/comment_content"
app:layout_constraintStart_toStartOf="@id/comment_account_profile" app:layout_constraintStart_toStartOf="@id/comment_account_profile"
android:layout_marginEnd="15dp"
app:layout_constraintEnd_toStartOf="@+id/replyButton"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="?attr/colorAccent"/> android:textColor="?attr/colorAccent" />
<TextView <TextView
app:layout_constraintTop_toBottomOf="@+id/comment_content" android:layout_marginStart="10dp"
app:layout_constraintStart_toStartOf="@id/comment_account_profile" app:layout_constraintStart_toEndOf="@id/number_of_replies"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:id="@+id/replyButton" android:id="@+id/replyButton"
app:layout_constraintTop_toTopOf="@+id/number_of_replies"
android:text="@string/reply" android:text="@string/reply"
android:textColor="?attr/colorAccent" android:textColor="?attr/colorAccent"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"/> android:layout_height="wrap_content" />
<Button <Button
style="@style/Widget.AppCompat.Button.Borderless.Colored" style="@style/Widget.AppCompat.Button.Borderless.Colored"

View File

@ -103,6 +103,17 @@
android:textColor="#FFBEBEBE" android:textColor="#FFBEBEBE"
android:textSize="12sp" /> android:textSize="12sp" />
<TextView
android:id="@+id/exo_live_badge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:textColor="#FFF"
android:textSize="12sp"
android:visibility="gone" />
<FrameLayout <FrameLayout
android:id="@+id/exo_fullscreen_button" android:id="@+id/exo_fullscreen_button"
android:layout_width="32dp" android:layout_width="32dp"

View File

@ -350,4 +350,7 @@
<string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string> <string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string>
<string name="set_video_language">Language filter</string> <string name="set_video_language">Language filter</string>
<string name="set_video_language_description">Filter videos with different languages</string> <string name="set_video_language_description">Filter videos with different languages</string>
<string name="live">Live</string>
<string name="live_not_started">This live has not started!</string>
<string name="remote_account">Account from another network!</string>
</resources> </resources>

View File

@ -346,4 +346,7 @@
<string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string> <string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string>
<string name="set_video_language">Sprachfilter</string> <string name="set_video_language">Sprachfilter</string>
<string name="set_video_language_description">Videos mit verschiedenen Sprachen filtern</string> <string name="set_video_language_description">Videos mit verschiedenen Sprachen filtern</string>
<string name="live">Live</string>
<string name="live_not_started">This live has not started!</string>
<string name="remote_account">Account from another network!</string>
</resources> </resources>

View File

@ -345,4 +345,7 @@
<string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string> <string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string>
<string name="set_video_language">Φίλτρο Γλώσσας</string> <string name="set_video_language">Φίλτρο Γλώσσας</string>
<string name="set_video_language_description">Φιλτράρετε βίντεο με διάφορες γλώσσες</string> <string name="set_video_language_description">Φιλτράρετε βίντεο με διάφορες γλώσσες</string>
<string name="live">Live</string>
<string name="live_not_started">This live has not started!</string>
<string name="remote_account">Account from another network!</string>
</resources> </resources>

View File

@ -346,4 +346,7 @@
<string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string> <string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string>
<string name="set_video_language">Filtro de idioma</string> <string name="set_video_language">Filtro de idioma</string>
<string name="set_video_language_description">Filtrar los videos con diferentes idiomas</string> <string name="set_video_language_description">Filtrar los videos con diferentes idiomas</string>
<string name="live">Live</string>
<string name="live_not_started">This live has not started!</string>
<string name="remote_account">Account from another network!</string>
</resources> </resources>

View File

@ -346,4 +346,7 @@
<string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string> <string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string>
<string name="set_video_language">Filtre de langue</string> <string name="set_video_language">Filtre de langue</string>
<string name="set_video_language_description">Filtrer les vidéos avec différentes langues</string> <string name="set_video_language_description">Filtrer les vidéos avec différentes langues</string>
<string name="live">Live</string>
<string name="live_not_started">This live has not started!</string>
<string name="remote_account">Account from another network!</string>
</resources> </resources>

View File

@ -346,4 +346,7 @@
<string name="set_video_minimize_description">Ridurre al minimo le dimensioni dei video quando l\'applicazione è in background (Android N+)</string> <string name="set_video_minimize_description">Ridurre al minimo le dimensioni dei video quando l\'applicazione è in background (Android N+)</string>
<string name="set_video_language">Filtro per le lingue</string> <string name="set_video_language">Filtro per le lingue</string>
<string name="set_video_language_description">Filtra video con lingue diverse</string> <string name="set_video_language_description">Filtra video con lingue diverse</string>
<string name="live">Live</string>
<string name="live_not_started">This live has not started!</string>
<string name="remote_account">Account from another network!</string>
</resources> </resources>

View File

@ -345,4 +345,7 @@
<string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string> <string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string>
<string name="set_video_language">Language filter</string> <string name="set_video_language">Language filter</string>
<string name="set_video_language_description">Filter videos with different languages</string> <string name="set_video_language_description">Filter videos with different languages</string>
<string name="live">Live</string>
<string name="live_not_started">This live has not started!</string>
<string name="remote_account">Account from another network!</string>
</resources> </resources>

View File

@ -345,4 +345,7 @@
<string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string> <string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string>
<string name="set_video_language">Language filter</string> <string name="set_video_language">Language filter</string>
<string name="set_video_language_description">Filter videos with different languages</string> <string name="set_video_language_description">Filter videos with different languages</string>
<string name="live">Live</string>
<string name="live_not_started">This live has not started!</string>
<string name="remote_account">Account from another network!</string>
</resources> </resources>

View File

@ -346,4 +346,7 @@
<string name="set_video_minimize_description">Minimaliseer de grootte van de video\'s als de app op de achtergrond staat (Android N+)</string> <string name="set_video_minimize_description">Minimaliseer de grootte van de video\'s als de app op de achtergrond staat (Android N+)</string>
<string name="set_video_language">Taalfilter</string> <string name="set_video_language">Taalfilter</string>
<string name="set_video_language_description">Filtervideo\'s met verschillende talen</string> <string name="set_video_language_description">Filtervideo\'s met verschillende talen</string>
<string name="live">Live</string>
<string name="live_not_started">This live has not started!</string>
<string name="remote_account">Account from another network!</string>
</resources> </resources>

View File

@ -348,4 +348,7 @@
<string name="set_video_minimize_description">Minimalizacja rozmiaru filmów, gdy aplikacja znajduje się w tle (Android N+)</string> <string name="set_video_minimize_description">Minimalizacja rozmiaru filmów, gdy aplikacja znajduje się w tle (Android N+)</string>
<string name="set_video_language">Filtr językowy</string> <string name="set_video_language">Filtr językowy</string>
<string name="set_video_language_description">Filtrowanie filmów w różnych językach</string> <string name="set_video_language_description">Filtrowanie filmów w różnych językach</string>
<string name="live">Live</string>
<string name="live_not_started">This live has not started!</string>
<string name="remote_account">Account from another network!</string>
</resources> </resources>

View File

@ -346,4 +346,7 @@
<string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string> <string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string>
<string name="set_video_language">Language filter</string> <string name="set_video_language">Language filter</string>
<string name="set_video_language_description">Filter videos with different languages</string> <string name="set_video_language_description">Filter videos with different languages</string>
<string name="live">Live</string>
<string name="live_not_started">This live has not started!</string>
<string name="remote_account">Account from another network!</string>
</resources> </resources>

View File

@ -347,4 +347,7 @@
<string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string> <string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string>
<string name="set_video_language">Language filter</string> <string name="set_video_language">Language filter</string>
<string name="set_video_language_description">Filter videos with different languages</string> <string name="set_video_language_description">Filter videos with different languages</string>
<string name="live">Live</string>
<string name="live_not_started">This live has not started!</string>
<string name="remote_account">Account from another network!</string>
</resources> </resources>

View File

@ -348,4 +348,7 @@
<string name="set_video_minimize_description">Уменьшить размер видео, когда приложение находится в фоновом режиме (Android N+)</string> <string name="set_video_minimize_description">Уменьшить размер видео, когда приложение находится в фоновом режиме (Android N+)</string>
<string name="set_video_language">Добавить языковой фильтр</string> <string name="set_video_language">Добавить языковой фильтр</string>
<string name="set_video_language_description">Фильтровать видео с разными языками</string> <string name="set_video_language_description">Фильтровать видео с разными языками</string>
<string name="live">Live</string>
<string name="live_not_started">This live has not started!</string>
<string name="remote_account">Account from another network!</string>
</resources> </resources>

View File

@ -346,4 +346,7 @@
<string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string> <string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string>
<string name="set_video_language">Language filter</string> <string name="set_video_language">Language filter</string>
<string name="set_video_language_description">Filter videos with different languages</string> <string name="set_video_language_description">Filter videos with different languages</string>
<string name="live">Live</string>
<string name="live_not_started">This live has not started!</string>
<string name="remote_account">Account from another network!</string>
</resources> </resources>

View File

@ -344,4 +344,7 @@
<string name="set_video_minimize_description">当处于后台播放时,最小化视频(仅适用于 Android N 以及之后的版本)</string> <string name="set_video_minimize_description">当处于后台播放时,最小化视频(仅适用于 Android N 以及之后的版本)</string>
<string name="set_video_language">语言筛选</string> <string name="set_video_language">语言筛选</string>
<string name="set_video_language_description">筛选其他语言的视频</string> <string name="set_video_language_description">筛选其他语言的视频</string>
<string name="live">Live</string>
<string name="live_not_started">This live has not started!</string>
<string name="remote_account">Account from another network!</string>
</resources> </resources>

View File

@ -345,4 +345,7 @@
<string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string> <string name="set_video_minimize_description">Minimize videos size when the app is in background (Android N+)</string>
<string name="set_video_language">Language filter</string> <string name="set_video_language">Language filter</string>
<string name="set_video_language_description">Filter videos with different languages</string> <string name="set_video_language_description">Filter videos with different languages</string>
<string name="live">Live</string>
<string name="live_not_started">This live has not started!</string>
<string name="remote_account">Account from another network!</string>
</resources> </resources>

View File

@ -443,4 +443,7 @@
<string name="set_video_language">Language filter</string> <string name="set_video_language">Language filter</string>
<string name="set_video_language_description">Filter videos with different languages</string> <string name="set_video_language_description">Filter videos with different languages</string>
<string name="live">Live</string>
<string name="live_not_started">This live has not started!</string>
<string name="remote_account">Account from another network!</string>
</resources> </resources>

View File

@ -6,15 +6,15 @@ files:
two_letters_code: two_letters_code:
zh-TW: zh-rTW zh-TW: zh-rTW
zh-CN: zh-rCN zh-CN: zh-rCN
- source: /app/src/fdroid_full/fastlane/metadata/android/en-US/full_description.txt - source: /src/fdroid_full/fastlane/metadata/android/en-US/full_description.txt
translation: /app/src/fdroid_full/fastlane/metadata/android/%two_letters_code%/%original_file_name% translation: /src/fdroid_full/fastlane/metadata/android/%two_letters_code%/%original_file_name%
#update_option: update_without_changes #update_option: update_without_changes
languages_mapping: languages_mapping:
two_letters_code: two_letters_code:
zh-TW: zh-rTW zh-TW: zh-rTW
zh-CN: zh-rCN zh-CN: zh-rCN
- source: /app/src/fdroid_full/fastlane/metadata/android/en-US/short_description.txt - source: /src/fdroid_full/fastlane/metadata/android/en-US/short_description.txt
translation: /app/src/fdroid_full/fastlane/metadata/android/%two_letters_code%/%original_file_name% translation: /src/fdroid_full/fastlane/metadata/android/%two_letters_code%/%original_file_name%
#update_option: update_without_changes #update_option: update_without_changes
languages_mapping: languages_mapping:
two_letters_code: two_letters_code:

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1,13 @@
Added:
- Live stream badge
- Increment view count when watching a video
Changed:
- Seek bar hidden with lives
- Add a message if the live has not yet started
Fixed:
- Do not list not honored when no accounts connected
- Comments with replies show overlap
- Mastodon accounts show errors
- Accounts not found issue

View File

@ -0,0 +1,13 @@
Added:
- Live stream badge
- Increment view count when watching a video
Changed:
- Seek bar hidden with lives
- Add a message if the live has not yet started
Fixed:
- Do not list not honored when no accounts connected
- Comments with replies show overlap
- Mastodon accounts show errors
- Accounts not found issue

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Some files were not shown because too many files have changed in this diff Show More