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

66 Commits
1.3.0 ... 1.5.0

Author SHA1 Message Date
017bd5a6a2 Release 1.5.0 2020-10-16 18:03:41 +02:00
967f11ddb4 Release 1.5.0 2020-10-16 17:53:30 +02:00
6b4abd019e typo 2020-10-16 17:43:18 +02:00
8b66c4030f Some fixes 2020-10-16 17:41:07 +02:00
34f058358e Merge branch 'l10n_develop' into 'develop'
New Crowdin updates

See merge request tom79/fedilab-tube!27
2020-10-16 17:26:37 +02:00
2bab907777 New Crowdin updates 2020-10-16 17:26:37 +02:00
52e64b6d85 Fix issue #9 2020-10-16 17:25:52 +02:00
9510678a9f Manage accounts 2020-10-16 17:03:07 +02:00
b4e7c3f8e2 New fixes 2020-10-16 11:37:40 +02:00
d800d2b10c Fix comment layout 2020-10-15 19:07:58 +02:00
785b4949e6 Fix a register issue 2020-10-15 19:02:12 +02:00
b79e17cb60 Merge branch 'l10n_develop' into 'develop'
New Crowdin updates

See merge request tom79/fedilab-tube!26
2020-10-15 18:59:22 +02:00
19fcbeb4b9 New Crowdin updates 2020-10-15 18:59:22 +02:00
ffb355d1a2 Add notifications for abuse reports 2020-10-15 18:59:08 +02:00
43fd2945cc Some improvements 2020-10-15 18:37:50 +02:00
d93c74a449 Reply to comments 2020-10-15 18:11:37 +02:00
7a197993c9 Support Emoji and replies 2020-10-15 15:16:41 +02:00
dc2a252dd5 Prepare the new layout. 2020-10-14 19:14:54 +02:00
2c33f7a7f8 Prepare the new layout. 2020-10-14 19:11:53 +02:00
24a8a0dc00 Some improvements 2020-10-14 16:39:27 +02:00
b78894b33c Merge remote-tracking branch 'origin/develop' into develop 2020-10-14 16:06:24 +02:00
2d33d7f970 Fix comment issue when posting 2020-10-14 16:06:17 +02:00
8823eb74ba Merge branch 'l10n_develop' into 'develop'
New Crowdin updates

See merge request tom79/fedilab-tube!25
2020-10-14 15:24:32 +02:00
7f77b86272 New Crowdin updates 2020-10-14 15:24:32 +02:00
2f773b2f0f Custom instances per country 2020-10-14 10:57:28 +02:00
ca69a6e86d Code cleaning 2020-10-14 10:31:02 +02:00
3e5cefbf24 Merge branch 'l10n_develop' into 'develop'
New Crowdin updates

See merge request tom79/fedilab-tube!24
2020-10-13 18:12:03 +02:00
245ef64ebe New Crowdin updates 2020-10-13 18:12:03 +02:00
a0ff454dd9 Some improvements 2020-10-13 18:11:53 +02:00
fa6b1560f8 Prepare release 1.4.2 2020-10-13 17:57:35 +02:00
518b5f617b Merge remote-tracking branch 'origin/develop' into develop 2020-10-13 17:50:57 +02:00
7c4ce7701c some fixes 2020-10-13 17:50:52 +02:00
0b6557f9c5 Merge branch 'l10n_develop' into 'develop'
New Crowdin updates

See merge request tom79/fedilab-tube!23
2020-10-13 16:36:10 +02:00
a8e00d137a New Crowdin updates 2020-10-13 16:36:10 +02:00
75d3f74e48 Merge remote-tracking branch 'origin/develop' into develop 2020-10-13 16:35:56 +02:00
3866317597 some fixes 2020-10-13 16:35:51 +02:00
10e904fe4a Merge branch 'l10n_develop' into 'develop'
New Crowdin updates

See merge request tom79/fedilab-tube!22
2020-10-13 14:32:42 +02:00
be655f6c2b New Crowdin updates 2020-10-13 14:32:42 +02:00
676e540059 Dark/Light/Automatic theme 2020-10-13 14:30:08 +02:00
87763a050c Merge remote-tracking branch 'origin/develop' into develop 2020-10-13 11:06:58 +02:00
ab45c1f80c Fix some issues + check if video is federated for Sepia search 2020-10-13 11:04:35 +02:00
ec5f2c7c45 Merge branch 'l10n_develop' into 'develop'
New Crowdin updates

See merge request tom79/fedilab-tube!21
2020-10-12 07:35:45 +02:00
c4448f22b9 New Crowdin updates 2020-10-12 07:35:44 +02:00
62af5c54aa Release 1.4.1 2020-10-11 17:21:45 +02:00
5872f5c99f Merge branch 'l10n_develop' into 'develop'
New Crowdin updates

See merge request tom79/fedilab-tube!20
2020-10-11 17:18:41 +02:00
2b1a63e08b New Crowdin updates 2020-10-11 17:18:41 +02:00
7b96cf32b3 App rater for Google Full version 2020-10-10 15:40:16 +02:00
6108bd143c App rater for Google Full version 2020-10-10 15:33:25 +02:00
0127b9bffa Censor videos having youtube + download in their title (Google Play release only). 2020-10-10 15:21:46 +02:00
8dddfc5497 Last fixes 2020-10-10 15:05:39 +02:00
bf119a5808 Fix strings 2020-10-10 11:52:57 +02:00
89ade69c5f Merge branch 'l10n_develop' into 'develop'
New Crowdin updates

See merge request tom79/fedilab-tube!19
2020-10-10 11:49:50 +02:00
93eaec8544 Fix some elements 2020-10-10 11:49:18 +02:00
ce984de339 New translations strings.xml (French) 2020-10-10 10:32:08 +02:00
b089ae93e1 Refresh subscription 2020-10-10 10:28:45 +02:00
fc95708a84 Merge remote-tracking branch 'origin/develop' into develop 2020-10-10 09:43:40 +02:00
7262690999 Fix translations 2020-10-10 09:43:35 +02:00
f818c74943 Merge branch 'l10n_develop' into 'develop'
New Crowdin updates

See merge request tom79/fedilab-tube!18
2020-10-10 09:38:05 +02:00
d7c5a04965 New Crowdin updates 2020-10-10 09:38:05 +02:00
257a00fa1e Some fixes 2020-10-10 09:37:44 +02:00
23875a2ceb Fix channel filter for subscriptions 2020-10-10 09:25:00 +02:00
3f1883fbbc Fix an issue with overlapping views 2020-10-09 19:14:20 +02:00
c5269a3129 comment #5 - Some improvements 2020-10-09 18:37:54 +02:00
056092ac71 comment #5 - Add searches 2020-10-09 18:22:05 +02:00
fd7632f001 comment #5 - searches 2020-10-09 14:54:01 +02:00
fb83a1927d comment #5 - prepare layouts 2020-10-09 10:19:46 +02:00
101 changed files with 7789 additions and 1540 deletions

View File

@ -6,12 +6,13 @@ android {
compileSdkVersion 30 compileSdkVersion 30
buildToolsVersion "30.0.2" buildToolsVersion "30.0.2"
defaultConfig { defaultConfig {
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 30 targetSdkVersion 30
versionCode 14 versionCode 19
versionName "1.3.0" versionName "1.5.0"
multiDexEnabled true multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
@ -30,6 +31,10 @@ android {
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
} }
buildFeatures {
viewBinding = true
}
lintOptions { lintOptions {
disable 'MissingTranslation' disable 'MissingTranslation'
checkReleaseBuilds false checkReleaseBuilds false
@ -92,7 +97,7 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.preference:preference:1.1.1' implementation 'androidx.preference:preference:1.1.1'
implementation 'com.google.android.material:material:1.2.1' implementation 'com.google.android.material:material:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1' implementation 'androidx.constraintlayout:constraintlayout:2.0.2'
implementation 'androidx.vectordrawable:vectordrawable:1.1.0' implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
implementation 'androidx.navigation:navigation-fragment:2.3.0' implementation 'androidx.navigation:navigation-fragment:2.3.0'
implementation "androidx.fragment:fragment:1.2.5" implementation "androidx.fragment:fragment:1.2.5"
@ -119,5 +124,9 @@ dependencies {
implementation 'com.github.ybq:Android-SpinKit:1.4.0' implementation 'com.github.ybq:Android-SpinKit:1.4.0'
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.github.mancj:MaterialSearchBar:0.8.5'
implementation "io.github.kobakei:ratethisapp:1.2.0"
implementation 'com.github.HITGIF:TextFieldBoxes:1.4.5'
} }

View File

@ -4,10 +4,6 @@
<color name="colorPrimaryDark">#4527A0</color> <color name="colorPrimaryDark">#4527A0</color>
<color name="colorAccent">#9C27B0</color> <color name="colorAccent">#9C27B0</color>
<color name="colorPrimary_full">#212529</color>
<color name="colorPrimaryDark_full">#000000</color>
<color name="colorAccent_full">#F2690D</color>
<color name="tag_color">#bbF2690D</color> <color name="tag_color">#bbF2690D</color>
<color name="tag_color_text">#FAFAFA</color> <color name="tag_color_text">#FAFAFA</color>
<color name="positive_thumbs">#2b90d9</color> <color name="positive_thumbs">#2b90d9</color>

View File

@ -1,21 +1,54 @@
<resources> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name" translatable="false">TubeAcad</string> <string name="app_name" translatable="false">TubeAcad</string>
<string name="set_video_mode_choice" translatable="false">set_video_mode_choice</string>
<string name="set_video_minimize_choice" translatable="false">set_video_minimize_choice</string>
<string name="set_video_language_choice" translatable="false">set_video_language_choice</string>
<string name="set_video_quality_choice" translatable="false">set_video_quality_choice</string>
<string name="set_video_cache_choice" translatable="false">set_video_cache_choice</string>
<string name="set_theme_choice" translatable="false">set_theme_choice</string>
<string name="delete_account_comment">Supprimer tous les commentaires</string>
<string name="delete_account_comment_confirm">Etes-vous sûr de vouloir supprimer tous les commentaires de ce compte pour vos vidéos ?</string>
<string-array name="settings_theme">
<item>Clair</item>
<item>Sombre</item>
<item>Automatique</item>
</string-array>
<plurals name="number_of_replies">
<item quantity="zero">%d réponse</item>
<item quantity="one">%d réponse</item>
<item quantity="other">%d réponses</item>
</plurals>
<string name="set_theme">Thème</string>
<string name="set_theme_description">Permet de changer le thème de l\'application</string>
<string name="federation_issue">La vidéo ne peut pas être fédérée !</string>
<string name="title_home">Locale</string> <string name="title_home">Locale</string>
<string name="title_local">Locale</string> <string name="title_local">Locale</string>
<string name="title_discover">Découvrir</string> <string name="title_discover">Découvrir</string>
<string name="title_notifications">Notifications</string> <string name="title_notifications">Notifications</string>
<string name="title_instances">Instances</string>
<string name="title_recently_added">Nouveautés</string> <string name="title_recently_added">Nouveautés</string>
<string name="title_trending">Tendances</string> <string name="title_trending">Tendances</string>
<string name="title_account">Compte</string>
<string name="title_most_liked">Plus aimées</string> <string name="title_most_liked">Plus aimées</string>
<string name="toast_error">Une erreur s\'est produite !</string> <string name="toast_error">Une erreur s\'est produite !</string>
<string name="title_muted">Sourdine</string>
<string name="title_channel">Chaînes</string>
<string name="do_not_list">Ne pas lister</string>
<string name="blur">Estomper</string>
<string name="display">Afficher</string>
<string name="no_opinion">Pas d\'opinion</string>
<string name="instance_choice">Choisissez une instance</string>
<string name="not_valide_instance">Cette instance ne semble pas être valide !</string>
<string name="no_videos">Aucune vidéo !</string> <string name="no_videos">Aucune vidéo !</string>
<string name="no_notifications">Aucune notification !</string>
<string name="favicon">Favicon</string> <string name="favicon">Favicon</string>
<string name="open_with">Ouvrir avec</string> <string name="open_with">Ouvrir avec</string>
<string name="action_playlist_edit">Modifier une liste de lecture</string>
<string name="close">Fermer</string> <string name="close">Fermer</string>
<string name="upload_video">Téléverser</string> <string name="upload_video">Téléverser</string>
<string name="bookmark_peertube_empty">Il ny a aucune vidéo Peertube dans vos favoris !</string>
<string name="image_preview">Aperçu de l\'image</string> <string name="image_preview">Aperçu de l\'image</string>
<string name="file_to_upload">Sélectionnez un fichier à transférer</string> <string name="file_to_upload">Sélectionnez un fichier à transférer</string>
<string name="channel">Chaîne</string> <string name="channel">Chaîne</string>
@ -26,144 +59,120 @@
<string name="cancel">Annuler</string> <string name="cancel">Annuler</string>
<string name="download">Télécharger</string> <string name="download">Télécharger</string>
<string name="profile_picture">Photo du profil</string> <string name="profile_picture">Photo du profil</string>
<string name="update_video">Mettre à jour la vidéo</string> <string name="update_video">Mettre à jour la vidéo</string>
<!-- Date --> <string name="remove_from_playlist">Supprimer de la liste de lecture</string>
<string name="date_seconds">%d s</string> <string name="date_seconds">%d s</string>
<string name="date_minutes">%d min</string> <string name="date_minutes">%d min</string>
<string name="date_hours">%d h</string> <string name="date_hours">%d h</string>
<string name="date_day">%d j</string> <string name="date_day">%d j</string>
<string name="number_view_video">%s vues</string> <string name="number_view_video">%s vues</string>
<string name="duration_video">Durée : %s</string> <string name="title_instance_login">Domaine de l\'instance</string>
<string name="toot_select_image_error">Une erreur sest produite lors de la sélection du média!</string>
<string name="uploading">Transfert en cours, veuillez patienter …</string> <string name="uploading">Transfert en cours, veuillez patienter …</string>
<string name="upload_video_success">La vidéo a été transférée !</string> <string name="upload_video_success">La vidéo a été transférée !</string>
<string name="toast_cancelled">Transfert annulé !</string> <string name="toast_cancelled">Transfert annulé !</string>
<string name="video_uploaded_action">Cliquez ici pour éditer les données de la vidéo.</string> <string name="video_uploaded_action">Cliquez ici pour éditer les données de la vidéo.</string>
<string name="toot_select_image">Sélectionnez un média</string> <string name="toot_select_image_error">Une erreur sest produite lors de la sélection du média!</string>
<string name="download_file">Télécharger %1$s</string> <string name="download_file">Télécharger %1$s</string>
<string name="action_privacy">Confidentialité</string>
<string name="action_logout">Déconnexion</string>
<string name="delete_video_confirmation">Êtes-vous sûr de vouloir supprimer cette vidéo ?</string> <string name="login">Connexion</string>
<string name="toast_peertube_video_updated">La vidéo a été mise à jour !</string> <string name="password">Mot de passe</string>
<string name="email">Courriel</string>
<string name="tags">Étiquettes</string>
<string name="validate">Valider</string>
<string name="share_with">Partager avec</string>
<string name="shared_via">Partagé via TubeLab</string>
<string name="username">Nom dutilisateur</string>
<string name="settings">Paramètres</string>
<string name="logout_account_confirmation">Voulez-vous vraiment déconnecter le compte @%1$s@%2$s ?</string>
<string name="following">Suit</string>
<string name="followers">Abonné·e·s</string>
<string name="client_error">Impossible dobtenir lid du client!</string>
<string name="toast_error_loading_account">Une erreur sest produite pendant le chargement du compte!</string>
<string name="toast_error_search">Une erreur sest produite lors de la recherche!</string>
<string name="nothing_to_do">Aucune action ne peut être réalisée</string>
<string name="action_follow">S\'abonner</string>
<string name="action_mute">Mettre en sourdine</string>
<string name="search">Chercher</string>
<string name="delete">Supprimer</string>
<string name="action_lists_confirm_delete">Êtes-vous sûr de vouloir supprimer définitivement cette liste de lecture ?</string>
<string name="action_lists_delete">Supprimer la liste de lecture</string>
<string name="no_comments">Soyez le·a premier·ère à laisser un commentaire sur cette vidéo en utilisant le bouton supérieur droit !</string>
<string name="comment_no_allowed_peertube">Les commentaires sur cette vidéos ont été désactivés !</string> <string name="comment_no_allowed_peertube">Les commentaires sur cette vidéos ont été désactivés !</string>
<string name="pickup_resolution">Choisissez une résolution</string>
<string name="bookmark_add_peertube">La vidéo est rajoutée aux favoris !</string> <string name="bookmark_add_peertube">La vidéo est rajoutée aux favoris !</string>
<string name="bookmark_remove_peertube">La vidéo a été retirée de vos favoris !</string> <string name="bookmark_remove_peertube">La vidéo a été retirée de vos favoris !</string>
<string name="information" tools:ignore="UnusedResources">Information</string>
<string name="shared_via">Partagé via TubeLab</string> <string name="app_logo">Logo de lapplication</string>
<string name="share_with">Partager avec</string> <!-- languages not translated -->
<string name="subscriptions">Abonnements</string>
<string name="pickup_resolution">Choisissez une résolution</string>
<string name="fullscreen">Vidéo plein écran</string>
<string name="remove_from_playlist">Supprimer de la liste de lecture</string>
<string name="comment">Commenter</string>
<string name="validate">Valider</string>
<string name="delete_comment">Supprimer le commentaire</string> <string name="delete_comment">Supprimer le commentaire</string>
<string name="delete_comment_confirm">Etes-vous sûr de vouloir supprimer ce commentaire ?</string> <string name="delete_comment_confirm">Etes-vous sûr de vouloir supprimer ce commentaire ?</string>
<string name="set_video_mode">Mode pour les vidéos</string>
<string name="filter">Filtrer</string>
<string name="toot_sent">Le message a été envoyé !</string> <string name="sepia_search">Recherche sépia</string>
<string name="reply">Répondre</string> <string name="sepia_element_nsfw">Afficher le contenu sensible</string>
<string name="delete">Supprimer</string> <string name="sepia_element_published_date">Date de publication</string>
<string name="no_video_to_display">Aucune vidéo nest disponible !</string> <string name="any">Toutes</string>
<string name="today">Aujourd\'hui</string>
<string name="last_7_days">Les 7 derniers jours</string>
<string name="last_30_days">Les 30 derniers jours</string>
<string name="last_365_days">Les 365 derniers jours</string>
<string name="sepia_element_duration">Durée</string>
<string name="duration_short"><![CDATA[Courte (<4 min)]]></string>
<string name="duration_medium"><![CDATA[Moyenne (4-10 min)]]></string>
<string name="duration_long"><![CDATA[Longue (> 10 min)]]></string>
<string name="display_all_categories">Afficher toutes les catégories</string>
<string name="display_all_licenses">Afficher toutes les licences</string>
<string name="display_all_languages">Afficher toutes les langues</string>
<string name="all_of_these_tags">Tous ces labels</string>
<string name="one_of_these_tags">Un de ces labels</string>
<string name="apply_filter">Appliquer le filtre</string>
<string-array name="sort_by_array">
<item>Meilleurs résultats</item>
<item>Les plus récentes</item>
<item>Les moins récentes</item>
</string-array>
<string name="sort_by">Trier par</string>
<string name="sepia_search_hint">Mot-clé, chaîne, vidéo, etc.</string>
<string name="sepia_indication">La recherche Sepia affiche les vidéos et les chaînes qui correspondent à votre recherche mais qui n\'est pas l\'éditeur, ni le propriétaire. Si vous remarquez des problèmes avec une vidéo, signalez-la aux administrateurs sur le site Web de PeerTube où la vidéo est publiée.</string>
<string name="my_videos">Mes vidéos</string> <string name="my_videos">Mes vidéos</string>
<string name="title">Titre</string> <string name="title">Titre</string>
<string name="license">Licence</string> <string name="license">Licence</string>
<string name="category">Catégorie</string> <string name="category">Catégorie</string>
<string name="language">Langue</string> <string name="language">Langue</string>
<string name="description">Description</string>
<string name="tags">Étiquettes</string>
<string name="action_privacy">Confidentialité</string>
<string name="peertube_nsfw">Cette vidéo contient du contenu pour adultes</string> <string name="peertube_nsfw">Cette vidéo contient du contenu pour adultes</string>
<string name="delete_video">Supprimer la vidéo</string>
<string name="peertube_enable_comments">Activer les commentaires</string> <string name="peertube_enable_comments">Activer les commentaires</string>
<string name="send_comment">Envoyer un commentaire</string> <string name="description">Libellé</string>
<string name="add_public_comment">Ajouter un commentaire public</string> <string name="toast_peertube_video_updated">La vidéo a été mise à jour !</string>
<string name="share">Partager</string> <string name="register_account">Créer un compte</string>
<string name="no_comments">Soyez le·a premier·ère à laisser un commentaire sur cette vidéo en utilisant le bouton supérieur droit !</string>
<string name="title_video_peertube">Titre de la vidéo</string>
<string name="set_video_mode">Mode pour les vidéos</string>
<string name="display_nsfw_videos">Afficher les vidéos sensibles</string>
<string name="action_playlist_add">Vous n\'avez aucune liste de lecture. Cliquez sur l\'icône « + » pour en ajouter une</string>
<string name="not_logged_in">Vous devez être connecté.e pour effectuer cette action !</string>
<string name="change_instance">Changer d\'instance</string>
<string name="account">Compte</string>
<string name="instance_choice">Choisissez une instance</string>
<string name="toast_error_loading_account">Une erreur sest produite pendant le chargement du compte!</string>
<string name="profile_banner">Bannière du profil</string>
<string name="make_an_action">Faire une action</string>
<string name="go_back">Retour</string>
<string name="open_menu">Ouvrir le menu</string>
<string name="display_more">Afficher plus</string>
<string name="edit_profile">Éditer le profil</string>
<string name="followed_by">Vous suit</string>
<string name="no_channels">Aucune chaîne !</string>
<string name="following">Suit</string>
<string name="followers">Abonné·e·s</string>
<string name="title_instance_login">Domaine de l\'instance</string>
<string name="followers_count">%1$s Abonné·e·s</string>
<string name="nothing_to_do">Aucune action ne peut être réalisée</string>
<string name="unfollow_confirm">Voulez-vous vous désabonner de ce compte ?</string>
<string name="action_unfollow">Se désabonner</string>
<string name="action_follow">S\'abonner</string>
<string name="search">Chercher</string>
<string name="toast_error_search">Une erreur sest produite lors de la recherche!</string>
<string name="no_result">Aucun résultat !</string>
<string name="app_logo">Logo de lapplication</string>
<string name="join_peertube">Rejoignez Peertube</string>
<string name="username">Nom dutilisateur</string>
<string name="email_address">Adresse mèl</string> <string name="email_address">Adresse mèl</string>
<string name="password">Mot de passe</string> <string name="preview">Aperçu</string>
<string name="add_account">Ajouter un compte</string> <string name="change_preview">Modifier l\'aperçu</string>
<string name="login">Connexion</string> <string name="name">Nom</string>
<string name="client_error">Impossible dobtenir lid du client!</string> <string name="display_more">Afficher plus</string>
<string name="email">Email</string> <string name="no_channels">Aucune chaîne !</string>
<string name="email_indicator">Vous recevrez un e-mail de confirmation</string> <string name="report_helper">Quelques explications concernant votre signalement…</string>
<string name="password_indicator">Utilisez au moins 8 caractères</string> <string name="report_video">Signaler la vidéo</string>
<string name="password_confirm">Confirmer le mot de passe</string> <string name="report">Signaler</string>
<string name="agreement_check_peertube">J\'ai au moins 16 ans et je suis d\'accord avec les %1$s de cette instance</string> <string name="change_instance">Changer d\'instance</string>
<string name="sign_up">Sinscrire</string> <string name="my_history">Historique</string>
<string name="account_created">Compte créé !</string> <string name="edit">Modifier</string>
<string name="account_created_message">Votre compte est créé !\n\nVous allez recevoir un email de confirmation à l\'adresse <b>%1$s</b>.\n\nCliquez sur le lien présent dans le mail pour valider votre compte.</string> <string name="video_settings">Réglages des vidéos</string>
<string name="all_field_filled">Veuillez remplir tous les champs !</string> <string name="app_interface">Interface</string>
<string name="password_length_error">Le mot de passe doit contenir 6 caractères !</string> <string name="set_cache_mode">Cache</string>
<string name="password_error">Les mots de passe ne sont pas identiques !</string> <string name="set_video_cache_description">Définir le cache pour les vidéos (par défaut 100Mo)</string>
<string name="email_error">L\'e-mail ne semble pas être valide !</string> <string name="set_video_quality_description">Définir une qualité par défaut pour les vidéos</string>
<string name="password_too_short">Le mot de passe doit contenir au moins 8 caractères</string> <string name="set_quality_mode">Résolution pour les vidéos</string>
<string name="username_error">Le nom d\'utilisateur·rice doit être en minuscule, contenir uniquement des lettres, des chiffres, des points et des caractères de soulignement</string> <string name="video_cache_value">Cache vidéo : %d Mo</string>
<string name="tos">conditions de service</string> <string name="captions">Légendes</string>
<string name="server_rules">règles du serveur</string> <string name="pickup_captions">Options d\'envoi</string>
<string name="agreement_check">J\'accepte les %1$s et les %2$s</string> <string name="none">Aucune</string>
<string name="email_error_domain">Les adresses mails %1$s ne sont pas autorisées !</string> <string name="set_video_mode_description">Permet de changer le mode de lecture pour les vidéos (normal, streaming ou via un navigateur).</string>
<string name="create_an_account">Créer un compte</string> <string name="delete_video">Supprimer la vidéo</string>
<string name="action_logout">Déconnexion</string> <string name="delete_video_confirmation">Êtes-vous sûr de vouloir supprimer cette vidéo ?</string>
<string name="logout_account_confirmation">Voulez-vous vraiment déconnecter le compte @%1$s@%2$s ?</string> <string name="no_video_to_display">Aucune vidéo nest disponible !</string>
<string name="share">Partager</string>
<string name="action_lists_delete">Supprimer la liste de lecture</string>
<string name="action_lists_confirm_delete">Êtes-vous sûr de vouloir supprimer définitivement cette liste de lecture ?</string>
<string name="action_channel_confirm_delete">Êtes-vous sûr de vouloir supprimer définitivement cette chaîne ?</string>
<string name="action_playlist_create">Créer une liste de lecture</string>
<string name="action_playlist_edit">Modifier une liste de lecture</string>
<string name="display_name">Nom d\'affichage</string>
<string name="error_channel_mandatory">Une chaîne est requise lorsque la liste de lecture est publique.</string>
<string name="error_display_name">Vous devez fournir un nom d\'affichage !</string>
<string name="error_display_name_channel">Vous devez fournir un nom d\'affichage et un nom pour la chaîne!</string>
<string name="action_playlist_empty_content">Cette liste de lecture est vide.</string>
<string name="playlists">Listes de lecture</string>
<string name="peertube_comment_on_video"><![CDATA[<b>%1$s</b> a commenté votre vidéo <b>%2$s</b>]]></string> <string name="peertube_comment_on_video"><![CDATA[<b>%1$s</b> a commenté votre vidéo <b>%2$s</b>]]></string>
<string name="peertube_follow_channel"><![CDATA[<b>%1$s</b> suit votre chaîne <b>%2$s</b>]]></string> <string name="peertube_follow_channel"><![CDATA[<b>%1$s</b> suit votre chaîne <b>%2$s</b>]]></string>
<string name="peertube_follow_account"><![CDATA[<b>%1$s</b> suit votre compte]]></string> <string name="peertube_follow_account"><![CDATA[<b>%1$s</b> suit votre compte]]></string>
@ -173,113 +182,101 @@
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> a publié une nouvelle vidéo : <b>%2$s</b>]]></string> <string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> a publié une nouvelle vidéo : <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[Votre vidéo <b>%1$s</b> a été blacklisté]]></string> <string name="peertube_video_blacklist"><![CDATA[Votre vidéo <b>%1$s</b> a été blacklisté]]></string>
<string name="peertube_video_unblacklist"><![CDATA[Votre vidéo <b>%1$s</b> nest plus blacklisté]]></string> <string name="peertube_video_unblacklist"><![CDATA[Votre vidéo <b>%1$s</b> nest plus blacklisté]]></string>
<string name="peertube_video_abuse"><![CDATA[Nouvelle modération sur la vidéo : <b>%1$s</b>]]></string> <string name="peertube_video_abuse"><![CDATA[Nouveau signalement pour la vidéo : <b>%1$s</b>]]></string>
<string name="toast_code_error">Une erreur sest produite! Linstance na retourné aucun code d\autorisation!</string> <string name="add_public_comment">Ajouter un commentaire public</string>
<string name="subscriptions">Abonnements</string> <string name="add_public_reply">Répondre publiquement</string>
<string name="report">Signaler</string> <string name="send_comment">Envoyer un commentaire</string>
<string name="report_video">Signaler la vidéo</string> <string name="all">Tout</string>
<string name="peertube_video_report_success"><![CDATA[ Votre signalement <b>%1$s</b> a été accepté]]></string>
<string name="reply">Répondre</string>
<!-- end languages -->
<string name="playlists">Listes de lecture</string>
<string name="display_name">Nom d\'affichage</string>
<string name="action_playlist_add">Vous n\'avez aucune liste de lecture. Cliquez sur l\'icône « + » pour en ajouter une</string>
<string name="error_display_name">Vous devez fournir un nom d\'affichage !</string>
<string name="error_channel_mandatory">Une chaîne est requise lorsque la liste de lecture est publique.</string>
<string name="action_playlist_create">Créer une liste de lecture</string>
<string name="action_playlist_empty_content">Cette liste de lecture est vide.</string>
<string name="password_confirm">Confirmer le mot de passe</string>
<string name="agreement_check">J\'accepte les %1$s et les %2$s</string>
<string name="server_rules">règles du serveur</string>
<string name="tos">conditions de service</string>
<string name="sign_up">Sinscrire</string>
<string name="all_field_filled">Veuillez remplir tous les champs !</string>
<string name="password_error">Les mots de passe ne sont pas identiques !</string>
<string name="email_error">L\'e-mail ne semble pas être valide !</string>
<string name="email_indicator">Vous recevrez un e-mail de confirmation</string>
<string name="password_indicator">Utilisez au moins 8 caractères</string>
<string name="password_too_short">Le mot de passe doit contenir au moins 8 caractères</string>
<string name="username_error">Le nom d\'utilisateur·rice doit être en minuscule, contenir uniquement des lettres, des chiffres, des points et des caractères de soulignement</string>
<string name="account_created">Compte créé !</string>
<string name="account_created_message">Votre compte est créé !\n\nVous allez recevoir un email de confirmation à l\'adresse <b>%1$s</b>.\n\nCliquez sur le lien présent dans le mail pour valider votre compte.</string>
<string name="account">Compte</string>
<string name="report_account">Signaler le compte</string> <string name="report_account">Signaler le compte</string>
<string name="report_helper">Quelques explications concernant votre signalement…</string> <string-array name="settings_video_mode">
<item>Normal</item>
<item>Streaming</item>
<item>Flux direct</item>
</string-array>
<string-array name="settings_video_quality">
<item>Élevée</item>
<item>Moyenne</item>
<item>Faible</item>
</string-array>
<string name="unfollow_confirm">Voulez-vous vous désabonner de ce compte ?</string>
<string name="title_video_peertube">Titre de la vidéo</string>
<string name="join_peertube">Rejoignez Peertube</string>
<string name="agreement_check_peertube">J\'ai au moins 16 ans et je suis d\'accord avec les %1$s de cette instance</string>
<string name="edit_profile">Éditer le profil</string>
<string name="make_an_action">Faire une action</string>
<string name="action_unfollow">Se désabonner</string>
<string name="display_nsfw_videos">Afficher les vidéos sensibles</string>
<string name="fullscreen">Vidéo plein écran</string>
<string name="bookmark_peertube_empty">Il ny a aucune vidéo Peertube dans vos favoris !</string>
<string name="delete_channel">Supprimer la chaîne</string>
<string name="action_channel_confirm_delete">Êtes-vous sûr de vouloir supprimer définitivement cette chaîne ?</string>
<string name="modify_playlists">Vidéo dans les listes de lecture</string>
<string name="no_muted">Aucun compte en sourdine !</string>
<string name="error_display_name_channel">Vous devez fournir un nom d\'affichage et un nom pour la chaîne!</string>
<string name="action_channel_create">Créer une chaîne</string>
<string name="action_channel_edit">Modifier une chaîne</string>
<string name="email_error_domain">Les adresses mails %1$s ne sont pas autorisées !</string>
<string name="report_comment_size">Veuillez préciser les raisons.</string>
<string name="not_logged_in">Vous devez être connecté.e pour effectuer cette action !</string>
<string name="successful_report">Le compte a été signalé !</string> <string name="successful_report">Le compte a été signalé !</string>
<string name="successful_report_comment">Le commentaire a été signalé !</string> <string name="successful_report_comment">Le commentaire a été signalé !</string>
<string name="successful_video_report">La vidéo a été signalée !</string> <string name="successful_video_report">La vidéo a été signalée !</string>
<string name="report_comment_size">Veuillez préciser les raisons.</string> <string name="password_length_error">Le mot de passe doit contenir 6 caractères !</string>
<string name="all">Tout</string>
<string name="my_history">Historique</string>
<string name="edit_video">Modifier une vidéo</string>
<string name="settings">Paramètres</string>
<string name="video_settings">Paramètres des vidéos</string>
<string name="app_interface">Interface</string>
<string name="modify_playlists">Vidéo dans les listes de lecture</string>
<string-array name="settings_video_mode">
<item>Normal</item>
<item>Navigateur</item>
<item>Streaming</item>
</string-array>
<string name="set_cache_mode">Cache</string>
<string name="set_video_cache_description">Définir le cache pour les vidéos (défaut 100Mo)</string>
<string name="video_cache_value">Cache pour les vidéos: %d Mo</string>
<string name="set_video_mode_choice" translatable="false">set_video_mode_choice</string>
<string name="set_video_minimize_choice" translatable="false">set_video_minimize_choice</string>
<string name="set_video_language_choice" translatable="false">set_video_language_choice</string>
<string name="set_video_quality_choice" translatable="false">set_video_quality_choice</string>
<string name="set_video_cache_choice" translatable="false">set_video_cache_choice</string>
<string-array name="settings_video_quality">
<item>Elevé</item>
<item>Moyen</item>
<item>Faible</item>
</string-array>
<string name="set_video_quality_description">Permet de définir la qualité de la vidéo par défaut</string>
<string name="set_quality_mode">Résolution pour les vidéos</string>
<string name="set_video_mode_description">Permet de changer le mode de lecture pour les vidéos (normal, streaming ou via un navigateur).</string>
<string name="register_account">Créer un compte</string>
<string name="preview">Aperçu</string>
<string name="change_preview">Modifier l\'aperçu</string>
<string name="title_muted">Sourdine</string>
<string name="title_blocked">Bloqués</string>
<string name="no_muted">Aucun compte en sourdine !</string>
<string name="no_notifications">Aucune notification !</string>
<string name="action_mute">Mettre en sourdine</string>
<string name="action_unmute">Réactiver le compte</string>
<string name="muted_done">Le compte a été mis en sourdine !</string> <string name="muted_done">Le compte a été mis en sourdine !</string>
<string name="title_channel">Chaînes</string> <string name="edit_video">Modifier une vidéo</string>
<string name="captions">Sous-titres</string> <string name="create_an_account">Créer un compte</string>
<string name="none">Aucun</string> <string name="followers_count">%1$s Abonné·e·s</string>
<string name="pickup_captions">Sélectionner des sous-titres</string>
<string name="name">Nom</string>
<string name="action_channel_create">Créer une chaîne</string>
<string name="action_channel_edit">Modifier une chaîne</string>
<string name="delete_channel">Supprimer la chaîne</string>
<string name="display_list">Afficher la liste</string>
<string name="delete_list">Supprimer la liste de lecture</string>
<string name="edit">Modifier</string>
<string name="not_valide_instance">Cette instance ne semble pas être valide !</string>
<string name="developer">Développeur</string> <string name="developer">Développeur</string>
<string name="about_vesrion">Version %1$s</string> <string name="about_vesrion">Version %1$s</string>
<string name="about_the_app">À propos de lapplication</string> <string name="about_the_app">À propos de lapplication</string>
<string name="Donate">Faire un don</string> <string name="Donate">Faire un don</string>
<string name="source_code">Code source</string> <string name="source_code">Code source</string>
<string name="issue_tracker">Suivi des tickets</string> <string name="issue_tracker">Suivi des tickets</string>
<string name="action_instance_empty_content">Aucune instance ne correspond à ces critères</string>
<string name="action_instance_empty_content">No instances match these criteria</string> <string name="instances_picker">Sélecteur d\'instances</string>
<string name="instances_picker">Instances picker</string> <string name="pickup_instance">Choisissez une instance</string>
<string name="pickup_instance">Pickup this instance</string> <string name="sensitive_video"> Vidéos sensibles</string>
<string name="sensitive_content">Sensitive content: %1$s</string> <string name="sensitive_content">Contenu sensible : %1$s</string>
<string name="followers_instance">%1$s instance followers</string> <string name="followers_instance">%1$s instances suiveuses</string>
<string name="help">Help</string> <string name="help">Aide</string>
<string name="sensitive_video"> Sensitive videos</string> <string name="pickup_categories">Sélection des catégories</string>
<string name="pickup_categories">Pickup categories</string> <string name="pickup_languages">Sélection des langues</string>
<string name="do_not_list">Do not list</string>
<string name="blur">Blur</string>
<string name="display">Display</string>
<string name="no_opinion">No opinion</string>
<string name="pickup_languages">Pickup languages</string>
<string name="notification_channel_name">Mise à jour des informations</string> <string name="notification_channel_name">Mise à jour des informations</string>
<string name="add_account">Ajouter un compte</string>
<string name="list_of_accounts">Liste des comptes</string> <string name="list_of_accounts">Liste des comptes</string>
<string name="pause">Pause</string> <string name="pause">Pause</string>
<string name="play">Lecture</string> <string name="play">Jouer</string>
<string name="minimize">Réduire</string> <string name="minimize">Minimiser</string>
<string name="fast_rewind">Retour rapide</string> <string name="fast_rewind">Rembobinage rapide</string>
<string name="fast_forward">Avance rapide</string> <string name="fast_forward">Avance rapide</string>
<string name="set_video_minimize">Minimiser la taille des vidéos</string>
<string name="set_video_minimize">Réduire la taille des vidéos</string> <string name="set_video_minimize_description">Minimiser la taille des vidéos lorsque l\'application est en arrière-plan (Android N+)</string>
<string name="set_video_minimize_description">Réduit la taille des vidéos quand l\'application est en arrière plan (Android N+)</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">Filtrer les langues</string>
<string name="set_video_language_description">Filtrer les vidéos en fonction de la langue</string>
</resources> </resources>

View File

@ -1,5 +1,3 @@
- Support for m3u8 videos - Theme: Clair, Sombre et automatique
- Improve loading time - Supprimer tous les commentaires d'un compte sur vos vidéos
- Quick menu access for videos (edit/playlist/follow/report) - Mettre en sourdine un compte depuis les commentaires.
- Improve menu for adding videos in playlists
- Fix an issue with pagination

View File

@ -1 +1 @@
App for all Peertube instances App per tutti i casi Peertube

View File

@ -1,22 +1,22 @@
*Nie ma trybu uwierzytelnionego* *Tryb bez uwierzytelniania*
Jest to tryb ograniczony, w którym można wykonywać pewne czynności: Jest to tryb ograniczony, w którym można wykonywać niektóre czynności:
- Przełącznik, - Przełączać sesje,
- Podziel się filmami, - Udostępniać filmy,
- Pobierz filmy. - Pobier filmy.
*Tryb uwierzytelniony* *Tryb uwierzytelniony*
W tym trybie dostępnych jest wiele funkcji: W tym trybie dostępnych jest wiele funkcji:
- Napisać/usunąć komentarz - Pisanie/Usuwanie komentarzy
- Przesyłanie/usuwanie/edycja filmów - Przesyłanie/Usuwanie/Edytowanie filmów
- Zarządzanie (tworzenie/edycja/usuwanie) kanałami i listami odtwarzania - Zarządzanie (tworzenie/edytowanie/usuwanie) kanałami i listami odtwarzania
- Kanały podążające/niepodążające - Obserwowanie kanałów
- Kciuki w górę/w dół - Kciuki w górę/w dół
- Powiadomienia o kontroli - Sprawdzanie powiadomień
- Kanały wyciszone/niewyciszone - Wyciszanie kanałów
- Raporty wideo/rachunki - Zgłaszanie filmów/kont
- Sprawdź swoją historię - Sprawdzanie swojej historii

View File

@ -1 +1 @@
App for all Peertube instances Aplikacja dla wszystkich instancji PeerTube

View File

@ -15,7 +15,7 @@
- Загружать/удалять/редактировать видео - Загружать/удалять/редактировать видео
- Управлять (создание/редактирование/удаление) каналами и плейлистами - Управлять (создание/редактирование/удаление) каналами и плейлистами
- Подписаться/отписаться от каналов - Подписаться/отписаться от каналов
- Палец вверх/вниз - Нравится/не нравится
- Проверить уведомления - Проверить уведомления
- Отключить/включить каналы - Отключить/включить каналы
- Пожаловаться на видео/аккаунты - Пожаловаться на видео/аккаунты

View File

@ -1 +1 @@
App for all Peertube instances Приложение для всех серверов Peertube

View File

@ -1,5 +1,7 @@
- Support for m3u8 videos - Custom default instance depending of the country
- Improve loading time - See replies to comments
- Quick menu access for videos (edit/playlist/follow/report) - Reply to comments
- Improve menu for adding videos in playlists - Reply to replies
- Fix an issue with pagination - See accounts (displays their channels & videos)
- Fix some issues when posting
- Fix videos not paused after screen lock

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/colorAccent_full" android:state_checked="true" /> <item android:color="@color/colorAccent" android:state_checked="true" />
<item android:color="@android:color/tab_indicator_text" /> <item android:color="@android:color/tab_indicator_text" />
</selector> </selector>

View File

@ -1,5 +1,18 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="add_public_reply">Add a public reply</string>
<plurals name="number_of_replies">
<item quantity="zero">%d replies</item>
<item quantity="one">%d reply</item>
<item quantity="two">%d replies</item>
<item quantity="few">%d replies</item>
<item quantity="many">%d replies</item>
<item quantity="other">%d replies</item>
</plurals>
<string name="reply">Reply</string>
<string name="set_theme">Theme</string>
<string name="set_theme_description">Allow to change app theme</string>
<string name="federation_issue">The video cannot be federated!</string>
<string name="title_home">Home</string> <string name="title_home">Home</string>
<string name="title_local">Local</string> <string name="title_local">Local</string>
<string name="title_discover">Discover</string> <string name="title_discover">Discover</string>
@ -83,6 +96,33 @@
<string name="delete_comment">Delete a comment</string> <string name="delete_comment">Delete a comment</string>
<string name="delete_comment_confirm">Are you sure to delete this comment?</string> <string name="delete_comment_confirm">Are you sure to delete this comment?</string>
<string name="set_video_mode">Mode for videos</string> <string name="set_video_mode">Mode for videos</string>
<string name="filter">Filter</string>
<string name="sepia_search">Sepia search</string>
<string name="sepia_element_nsfw">Display sensitive content</string>
<string name="sepia_element_published_date">Published date</string>
<string name="any">Any</string>
<string name="today">Today</string>
<string name="last_7_days">Last 7 days</string>
<string name="last_30_days">Last 30 days</string>
<string name="last_365_days">Last 365 days</string>
<string name="sepia_element_duration">Duration</string>
<string name="duration_short"><![CDATA[Short (<4 min)]]></string>
<string name="duration_medium"><![CDATA[Medium (410 min)]]></string>
<string name="duration_long"><![CDATA[Long (> 10 min)]]></string>
<string name="display_all_categories">Display all categories</string>
<string name="display_all_licenses">Display all licenses</string>
<string name="display_all_languages">Display all languages</string>
<string name="all_of_these_tags">All of these tags</string>
<string name="one_of_these_tags">One of these tags</string>
<string name="apply_filter">Apply filter</string>
<string-array name="sort_by_array">
<item>Best match</item>
<item>Most recent</item>
<item>Least recent</item>
</string-array>
<string name="sort_by">Sort by</string>
<string name="sepia_search_hint">Keyword, channel, video, etc.</string>
<string name="sepia_indication">Sepia Search displays videos and channels that match your search but is not the publisher, nor the owner. If you notice any problems with a video, report it to the administrators on the PeerTube website where the video is published.</string>
<string name="my_videos">My videos</string> <string name="my_videos">My videos</string>
<string name="title">Title</string> <string name="title">Title</string>
<string name="license">License</string> <string name="license">License</string>
@ -116,6 +156,8 @@
<string name="pickup_captions">Pick captions</string> <string name="pickup_captions">Pick captions</string>
<string name="none">None</string> <string name="none">None</string>
<string name="set_video_mode_description">Allows to change mode for playing videos (default, streaming or via a browser).</string> <string name="set_video_mode_description">Allows to change mode for playing videos (default, streaming or via a browser).</string>
<string name="delete_account_comment">Delete account comments</string>
<string name="delete_account_comment_confirm">Are you sure you want to remove all the comments of this account?</string>
<string name="delete_video">Delete video</string> <string name="delete_video">Delete video</string>
<string name="delete_video_confirmation">Are you sure to delete this video?</string> <string name="delete_video_confirmation">Are you sure to delete this video?</string>
<string name="no_video_to_display">No videos to display!</string> <string name="no_video_to_display">No videos to display!</string>
@ -129,6 +171,7 @@
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> published a new video: <b>%2$s</b>]]></string> <string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> published a new video: <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[Your video <b>%1$s</b> has been blacklisted]]></string> <string name="peertube_video_blacklist"><![CDATA[Your video <b>%1$s</b> has been blacklisted]]></string>
<string name="peertube_video_unblacklist"><![CDATA[Your video <b>%1$s</b> has been unblacklisted]]></string> <string name="peertube_video_unblacklist"><![CDATA[Your video <b>%1$s</b> has been unblacklisted]]></string>
<string name="peertube_video_report_success"><![CDATA[ Your abuse <b>%1$s</b> has been accepted]]></string>
<string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string> <string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string>
<string name="add_public_comment">Add a public comment</string> <string name="add_public_comment">Add a public comment</string>
<string name="send_comment">Send comment</string> <string name="send_comment">Send comment</string>
@ -166,6 +209,11 @@
<item>Webview</item> <item>Webview</item>
<item>Direct stream</item> <item>Direct stream</item>
</string-array> </string-array>
<string-array name="settings_theme">
<item>Light</item>
<item>Dark</item>
<item>Automatic</item>
</string-array>
<string-array name="settings_video_quality"> <string-array name="settings_video_quality">
<item>High</item> <item>High</item>
<item>Medium</item> <item>Medium</item>

View File

@ -1,5 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="add_public_reply">Add a public reply</string>
<plurals name="number_of_replies">
<item quantity="one">%d reply</item>
<item quantity="other">%d replies</item>
</plurals>
<string name="reply">Reply</string>
<string name="set_theme">Theme</string>
<string name="set_theme_description">Allow to change app theme</string>
<string name="federation_issue">The video cannot be federated!</string>
<string name="title_home">Startseite</string> <string name="title_home">Startseite</string>
<string name="title_local">Local</string> <string name="title_local">Local</string>
<string name="title_discover">Mehr erfahren</string> <string name="title_discover">Mehr erfahren</string>
@ -83,6 +92,33 @@
<string name="delete_comment">Kommentar löschen</string> <string name="delete_comment">Kommentar löschen</string>
<string name="delete_comment_confirm">Möchtest du diesen Kommentar wirklich löschen?</string> <string name="delete_comment_confirm">Möchtest du diesen Kommentar wirklich löschen?</string>
<string name="set_video_mode">Videomodus</string> <string name="set_video_mode">Videomodus</string>
<string name="filter">Filter</string>
<string name="sepia_search">Sepia search</string>
<string name="sepia_element_nsfw">Display sensitive content</string>
<string name="sepia_element_published_date">Published date</string>
<string name="any">Any</string>
<string name="today">Today</string>
<string name="last_7_days">Last 7 days</string>
<string name="last_30_days">Last 30 days</string>
<string name="last_365_days">Last 365 days</string>
<string name="sepia_element_duration">Duration</string>
<string name="duration_short"><![CDATA[Short (<4 min)]]></string>
<string name="duration_medium"><![CDATA[Medium (410 min)]]></string>
<string name="duration_long"><![CDATA[Long (> 10 min)]]></string>
<string name="display_all_categories">Display all categories</string>
<string name="display_all_licenses">Display all licenses</string>
<string name="display_all_languages">Display all languages</string>
<string name="all_of_these_tags">All of these tags</string>
<string name="one_of_these_tags">One of these tags</string>
<string name="apply_filter">Apply filter</string>
<string-array name="sort_by_array">
<item>Best match</item>
<item>Most recent</item>
<item>Least recent</item>
</string-array>
<string name="sort_by">Sort by</string>
<string name="sepia_search_hint">Keyword, channel, video, etc.</string>
<string name="sepia_indication">Sepia Search displays videos and channels that match your search but is not the publisher, nor the owner. If you notice any problems with a video, report it to the administrators on the PeerTube website where the video is published.</string>
<string name="my_videos">Eigene Videos</string> <string name="my_videos">Eigene Videos</string>
<string name="title">Titel</string> <string name="title">Titel</string>
<string name="license">Lizenz</string> <string name="license">Lizenz</string>
@ -116,6 +152,8 @@
<string name="pickup_captions">Untertitel abholen</string> <string name="pickup_captions">Untertitel abholen</string>
<string name="none">Keine</string> <string name="none">Keine</string>
<string name="set_video_mode_description">Erlaubt es, den Modus für das Abspielen von Videos zu ändern (Standard, Streaming oder über einen Browser).</string> <string name="set_video_mode_description">Erlaubt es, den Modus für das Abspielen von Videos zu ändern (Standard, Streaming oder über einen Browser).</string>
<string name="delete_account_comment">Delete account comments</string>
<string name="delete_account_comment_confirm">Are you sure you want to remove all the comments of this account?</string>
<string name="delete_video">Video löschen</string> <string name="delete_video">Video löschen</string>
<string name="delete_video_confirmation">Möchtest du dieses Video wirklich löschen?</string> <string name="delete_video_confirmation">Möchtest du dieses Video wirklich löschen?</string>
<string name="no_video_to_display">Keine Videos zum Anzeigen!</string> <string name="no_video_to_display">Keine Videos zum Anzeigen!</string>
@ -129,6 +167,7 @@
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> hat ein neues Video veröffentlicht: <b>%2$s</b>]]></string> <string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> hat ein neues Video veröffentlicht: <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[Dein Video <b>%1$s</b> wurde gesperrt]]></string> <string name="peertube_video_blacklist"><![CDATA[Dein Video <b>%1$s</b> wurde gesperrt]]></string>
<string name="peertube_video_unblacklist"><![CDATA[Die Sperre für dein Video <b>%1$s</b> wurde aufgehoben]]></string> <string name="peertube_video_unblacklist"><![CDATA[Die Sperre für dein Video <b>%1$s</b> wurde aufgehoben]]></string>
<string name="peertube_video_report_success"><![CDATA[ Your abuse <b>%1$s</b> has been accepted]]></string>
<string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string> <string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string>
<string name="add_public_comment">Öffentlichen Kommentar hinzufügen</string> <string name="add_public_comment">Öffentlichen Kommentar hinzufügen</string>
<string name="send_comment">Kommentar absenden</string> <string name="send_comment">Kommentar absenden</string>
@ -166,6 +205,11 @@
<item>Direkter Datenstrom</item> <item>Direkter Datenstrom</item>
<item>Direct stream</item> <item>Direct stream</item>
</string-array> </string-array>
<string-array name="settings_theme">
<item>Light</item>
<item>Dark</item>
<item>Automatic</item>
</string-array>
<string-array name="settings_video_quality"> <string-array name="settings_video_quality">
<item>High</item> <item>High</item>
<item>Medium</item> <item>Medium</item>

View File

@ -1,5 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="add_public_reply">Add a public reply</string>
<plurals name="number_of_replies">
<item quantity="one">%d reply</item>
<item quantity="other">%d replies</item>
</plurals>
<string name="reply">Reply</string>
<string name="set_theme">Theme</string>
<string name="set_theme_description">Allow to change app theme</string>
<string name="federation_issue">The video cannot be federated!</string>
<string name="title_home">Αρχική</string> <string name="title_home">Αρχική</string>
<string name="title_local">Local</string> <string name="title_local">Local</string>
<string name="title_discover">Ανακαλύψτε</string> <string name="title_discover">Ανακαλύψτε</string>
@ -83,6 +92,33 @@
<string name="delete_comment">Διαγραφή ενός σχόλιου</string> <string name="delete_comment">Διαγραφή ενός σχόλιου</string>
<string name="delete_comment_confirm">Θέλετε να διαγράψετε αυτό το σχόλιο, στα σίγουρα;</string> <string name="delete_comment_confirm">Θέλετε να διαγράψετε αυτό το σχόλιο, στα σίγουρα;</string>
<string name="set_video_mode">Κατάσταση λειτουργίας για τα βίντεο</string> <string name="set_video_mode">Κατάσταση λειτουργίας για τα βίντεο</string>
<string name="filter">Filter</string>
<string name="sepia_search">Sepia search</string>
<string name="sepia_element_nsfw">Display sensitive content</string>
<string name="sepia_element_published_date">Published date</string>
<string name="any">Any</string>
<string name="today">Today</string>
<string name="last_7_days">Last 7 days</string>
<string name="last_30_days">Last 30 days</string>
<string name="last_365_days">Last 365 days</string>
<string name="sepia_element_duration">Duration</string>
<string name="duration_short"><![CDATA[Short (<4 min)]]></string>
<string name="duration_medium"><![CDATA[Medium (410 min)]]></string>
<string name="duration_long"><![CDATA[Long (> 10 min)]]></string>
<string name="display_all_categories">Display all categories</string>
<string name="display_all_licenses">Display all licenses</string>
<string name="display_all_languages">Display all languages</string>
<string name="all_of_these_tags">All of these tags</string>
<string name="one_of_these_tags">One of these tags</string>
<string name="apply_filter">Apply filter</string>
<string-array name="sort_by_array">
<item>Best match</item>
<item>Most recent</item>
<item>Least recent</item>
</string-array>
<string name="sort_by">Sort by</string>
<string name="sepia_search_hint">Keyword, channel, video, etc.</string>
<string name="sepia_indication">Sepia Search displays videos and channels that match your search but is not the publisher, nor the owner. If you notice any problems with a video, report it to the administrators on the PeerTube website where the video is published.</string>
<string name="my_videos">Τα βίντεο μου</string> <string name="my_videos">Τα βίντεο μου</string>
<string name="title">Τίτλος</string> <string name="title">Τίτλος</string>
<string name="license">Άδεια</string> <string name="license">Άδεια</string>
@ -116,6 +152,8 @@
<string name="pickup_captions">Επιλογή υποτίτλων</string> <string name="pickup_captions">Επιλογή υποτίτλων</string>
<string name="none">Κανένας</string> <string name="none">Κανένας</string>
<string name="set_video_mode_description">Επιτρέπει την εναλλαγή κατάστασης λειτουργίας για την αναπαραγωγή βίντεο (προεπιλεγμένη, ροή ή μέσω περιηγητή ιστού).</string> <string name="set_video_mode_description">Επιτρέπει την εναλλαγή κατάστασης λειτουργίας για την αναπαραγωγή βίντεο (προεπιλεγμένη, ροή ή μέσω περιηγητή ιστού).</string>
<string name="delete_account_comment">Delete account comments</string>
<string name="delete_account_comment_confirm">Are you sure you want to remove all the comments of this account?</string>
<string name="delete_video">Διαγραφή βίντεο</string> <string name="delete_video">Διαγραφή βίντεο</string>
<string name="delete_video_confirmation">Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτό το βίντεο;</string> <string name="delete_video_confirmation">Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτό το βίντεο;</string>
<string name="no_video_to_display">Δεν υπάρχουν βίντεο για προβολή!</string> <string name="no_video_to_display">Δεν υπάρχουν βίντεο για προβολή!</string>
@ -129,6 +167,7 @@
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> Δημοσίευσε ένα νέο βίντεο: <b>%2$s</b>]]></string> <string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> Δημοσίευσε ένα νέο βίντεο: <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[Το βίντεό σου <b>%1$s</b> έχει μπει στη μαύρη λίστα]]></string> <string name="peertube_video_blacklist"><![CDATA[Το βίντεό σου <b>%1$s</b> έχει μπει στη μαύρη λίστα]]></string>
<string name="peertube_video_unblacklist"><![CDATA[Το βίντεό σου <b>%1$s</b> έχει βγει από τη μαύρη λίστα]]></string> <string name="peertube_video_unblacklist"><![CDATA[Το βίντεό σου <b>%1$s</b> έχει βγει από τη μαύρη λίστα]]></string>
<string name="peertube_video_report_success"><![CDATA[ Your abuse <b>%1$s</b> has been accepted]]></string>
<string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string> <string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string>
<string name="add_public_comment">Προσθήκη ενός δημόσιου σχόλιου</string> <string name="add_public_comment">Προσθήκη ενός δημόσιου σχόλιου</string>
<string name="send_comment">Αποστολή σχόλιου</string> <string name="send_comment">Αποστολή σχόλιου</string>
@ -165,6 +204,11 @@
<item>Άμεση ροή</item> <item>Άμεση ροή</item>
<item>Direct stream</item> <item>Direct stream</item>
</string-array> </string-array>
<string-array name="settings_theme">
<item>Light</item>
<item>Dark</item>
<item>Automatic</item>
</string-array>
<string-array name="settings_video_quality"> <string-array name="settings_video_quality">
<item>High</item> <item>High</item>
<item>Medium</item> <item>Medium</item>

View File

@ -1,5 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="add_public_reply">Add a public reply</string>
<plurals name="number_of_replies">
<item quantity="one">%d reply</item>
<item quantity="other">%d replies</item>
</plurals>
<string name="reply">Reply</string>
<string name="set_theme">Theme</string>
<string name="set_theme_description">Allow to change app theme</string>
<string name="federation_issue">The video cannot be federated!</string>
<string name="title_home">Inicio</string> <string name="title_home">Inicio</string>
<string name="title_local">Local</string> <string name="title_local">Local</string>
<string name="title_discover">Descubre</string> <string name="title_discover">Descubre</string>
@ -83,6 +92,33 @@
<string name="delete_comment">Eliminar un comentario</string> <string name="delete_comment">Eliminar un comentario</string>
<string name="delete_comment_confirm">¿Realmente deseas eliminar este comentario?</string> <string name="delete_comment_confirm">¿Realmente deseas eliminar este comentario?</string>
<string name="set_video_mode">Aplicar el modo de video</string> <string name="set_video_mode">Aplicar el modo de video</string>
<string name="filter">Filter</string>
<string name="sepia_search">Sepia search</string>
<string name="sepia_element_nsfw">Display sensitive content</string>
<string name="sepia_element_published_date">Published date</string>
<string name="any">Any</string>
<string name="today">Today</string>
<string name="last_7_days">Last 7 days</string>
<string name="last_30_days">Last 30 days</string>
<string name="last_365_days">Last 365 days</string>
<string name="sepia_element_duration">Duration</string>
<string name="duration_short"><![CDATA[Short (<4 min)]]></string>
<string name="duration_medium"><![CDATA[Medium (410 min)]]></string>
<string name="duration_long"><![CDATA[Long (> 10 min)]]></string>
<string name="display_all_categories">Display all categories</string>
<string name="display_all_licenses">Display all licenses</string>
<string name="display_all_languages">Display all languages</string>
<string name="all_of_these_tags">All of these tags</string>
<string name="one_of_these_tags">One of these tags</string>
<string name="apply_filter">Apply filter</string>
<string-array name="sort_by_array">
<item>Best match</item>
<item>Most recent</item>
<item>Least recent</item>
</string-array>
<string name="sort_by">Sort by</string>
<string name="sepia_search_hint">Keyword, channel, video, etc.</string>
<string name="sepia_indication">Sepia Search displays videos and channels that match your search but is not the publisher, nor the owner. If you notice any problems with a video, report it to the administrators on the PeerTube website where the video is published.</string>
<string name="my_videos">Mis videos</string> <string name="my_videos">Mis videos</string>
<string name="title">Título</string> <string name="title">Título</string>
<string name="license">Licencia</string> <string name="license">Licencia</string>
@ -116,6 +152,8 @@
<string name="pickup_captions">Pies de foto de la camioneta</string> <string name="pickup_captions">Pies de foto de la camioneta</string>
<string name="none">Ninguno</string> <string name="none">Ninguno</string>
<string name="set_video_mode_description">Permite cambiar el modo de reproducción de los vídeos (predeterminado, streaming o a través de un navegador).</string> <string name="set_video_mode_description">Permite cambiar el modo de reproducción de los vídeos (predeterminado, streaming o a través de un navegador).</string>
<string name="delete_account_comment">Delete account comments</string>
<string name="delete_account_comment_confirm">Are you sure you want to remove all the comments of this account?</string>
<string name="delete_video">Eliminar vídeo</string> <string name="delete_video">Eliminar vídeo</string>
<string name="delete_video_confirmation">¿Estás seguro de eliminar este video?</string> <string name="delete_video_confirmation">¿Estás seguro de eliminar este video?</string>
<string name="no_video_to_display">¡No hay videos para ver!</string> <string name="no_video_to_display">¡No hay videos para ver!</string>
@ -129,6 +167,7 @@
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> publicó un nuevo video: <b>%2$s</b>]]></string> <string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> publicó un nuevo video: <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[Su video <b>%1$s</b> esta en lista negra]]></string> <string name="peertube_video_blacklist"><![CDATA[Su video <b>%1$s</b> esta en lista negra]]></string>
<string name="peertube_video_unblacklist"><![CDATA[Tu video <b>%1$s</b> non más esta en lista negra]]></string> <string name="peertube_video_unblacklist"><![CDATA[Tu video <b>%1$s</b> non más esta en lista negra]]></string>
<string name="peertube_video_report_success"><![CDATA[ Your abuse <b>%1$s</b> has been accepted]]></string>
<string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string> <string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string>
<string name="add_public_comment">Añade un comentario público</string> <string name="add_public_comment">Añade un comentario público</string>
<string name="send_comment">Enviar comentario</string> <string name="send_comment">Enviar comentario</string>
@ -166,6 +205,11 @@
<item>Corriente Directa</item> <item>Corriente Directa</item>
<item>Direct stream</item> <item>Direct stream</item>
</string-array> </string-array>
<string-array name="settings_theme">
<item>Light</item>
<item>Dark</item>
<item>Automatic</item>
</string-array>
<string-array name="settings_video_quality"> <string-array name="settings_video_quality">
<item>High</item> <item>High</item>
<item>Medium</item> <item>Medium</item>

View File

@ -1,7 +1,16 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="add_public_reply">Add a public reply</string>
<plurals name="number_of_replies">
<item quantity="one">%d reply</item>
<item quantity="other">%d replies</item>
</plurals>
<string name="reply">Reply</string>
<string name="set_theme">Theme</string>
<string name="set_theme_description">Allow to change app theme</string>
<string name="federation_issue">The video cannot be federated!</string>
<string name="title_home">Locale</string> <string name="title_home">Locale</string>
<string name="title_local">Local</string> <string name="title_local">Locale</string>
<string name="title_discover">Découvrir</string> <string name="title_discover">Découvrir</string>
<string name="title_notifications">Notifications</string> <string name="title_notifications">Notifications</string>
<string name="title_recently_added">Nouveautés</string> <string name="title_recently_added">Nouveautés</string>
@ -34,7 +43,7 @@
<string name="download">Télécharger</string> <string name="download">Télécharger</string>
<string name="profile_picture">Photo du profil</string> <string name="profile_picture">Photo du profil</string>
<string name="update_video">Mettre à jour la vidéo</string> <string name="update_video">Mettre à jour la vidéo</string>
<string name="remove_from_playlist">Remove from playlist</string> <string name="remove_from_playlist">Supprimer de la liste de lecture</string>
<string name="date_seconds">%d s</string> <string name="date_seconds">%d s</string>
<string name="date_minutes">%d min</string> <string name="date_minutes">%d min</string>
<string name="date_hours">%d h</string> <string name="date_hours">%d h</string>
@ -83,6 +92,33 @@
<string name="delete_comment">Supprimer le commentaire</string> <string name="delete_comment">Supprimer le commentaire</string>
<string name="delete_comment_confirm">Etes-vous sûr de vouloir supprimer ce commentaire ?</string> <string name="delete_comment_confirm">Etes-vous sûr de vouloir supprimer ce commentaire ?</string>
<string name="set_video_mode">Mode pour les vidéos</string> <string name="set_video_mode">Mode pour les vidéos</string>
<string name="filter">Filtrer</string>
<string name="sepia_search">Recherche sépia</string>
<string name="sepia_element_nsfw">Afficher le contenu sensible</string>
<string name="sepia_element_published_date">Date de publication</string>
<string name="any">Toutes</string>
<string name="today">Aujourd\'hui</string>
<string name="last_7_days">Les 7 derniers jours</string>
<string name="last_30_days">Les 30 derniers jours</string>
<string name="last_365_days">Les 365 derniers jours</string>
<string name="sepia_element_duration">Durée</string>
<string name="duration_short"><![CDATA[Courte (<4 min)]]></string>
<string name="duration_medium"><![CDATA[Moyenne (4-10 min)]]></string>
<string name="duration_long"><![CDATA[Longue (> 10 min)]]></string>
<string name="display_all_categories">Afficher toutes les catégories</string>
<string name="display_all_licenses">Afficher toutes les licences</string>
<string name="display_all_languages">Afficher toutes les langues</string>
<string name="all_of_these_tags">Tous ces labels</string>
<string name="one_of_these_tags">Un de ces labels</string>
<string name="apply_filter">Appliquer le filtre</string>
<string-array name="sort_by_array">
<item>Meilleurs résultats</item>
<item>Les plus récentes</item>
<item>Les moins récentes</item>
</string-array>
<string name="sort_by">Trier par</string>
<string name="sepia_search_hint">Mot-clé, chaîne, vidéo, etc.</string>
<string name="sepia_indication">La recherche Sepia affiche les vidéos et les chaînes qui correspondent à votre recherche mais qui n\'est pas l\'éditeur, ni le propriétaire. Si vous remarquez des problèmes avec une vidéo, signalez-la aux administrateurs sur le site Web de PeerTube où la vidéo est publiée.</string>
<string name="my_videos">Mes vidéos</string> <string name="my_videos">Mes vidéos</string>
<string name="title">Titre</string> <string name="title">Titre</string>
<string name="license">Licence</string> <string name="license">Licence</string>
@ -105,17 +141,19 @@
<string name="change_instance">Changer d\'instance</string> <string name="change_instance">Changer d\'instance</string>
<string name="my_history">Historique</string> <string name="my_history">Historique</string>
<string name="edit">Modifier</string> <string name="edit">Modifier</string>
<string name="video_settings">Video settings</string> <string name="video_settings">Réglages des vidéos</string>
<string name="app_interface">Interface</string> <string name="app_interface">Interface</string>
<string name="set_cache_mode">Cache</string> <string name="set_cache_mode">Cache</string>
<string name="set_video_cache_description">Set the cache for videos (default 100Mb)</string> <string name="set_video_cache_description">Définir le cache pour les vidéos (par défaut 100Mo)</string>
<string name="set_video_quality_description">Define a default quality for videos</string> <string name="set_video_quality_description">Définir une qualité par défaut pour les vidéos</string>
<string name="set_quality_mode">Resolution for videos</string> <string name="set_quality_mode">Résolution pour les vidéos</string>
<string name="video_cache_value">Video cache: %d Mb</string> <string name="video_cache_value">Cache vidéo : %d Mo</string>
<string name="captions">Légendes</string> <string name="captions">Légendes</string>
<string name="pickup_captions">Options d\'envoi</string> <string name="pickup_captions">Options d\'envoi</string>
<string name="none">Aucune</string> <string name="none">Aucune</string>
<string name="set_video_mode_description">Permet de changer le mode de lecture pour les vidéos (normal, streaming ou via un navigateur).</string> <string name="set_video_mode_description">Permet de changer le mode de lecture pour les vidéos (normal, streaming ou via un navigateur).</string>
<string name="delete_account_comment">Delete account comments</string>
<string name="delete_account_comment_confirm">Are you sure you want to remove all the comments of this account?</string>
<string name="delete_video">Supprimer la vidéo</string> <string name="delete_video">Supprimer la vidéo</string>
<string name="delete_video_confirmation">Êtes-vous sûr de vouloir supprimer cette vidéo ?</string> <string name="delete_video_confirmation">Êtes-vous sûr de vouloir supprimer cette vidéo ?</string>
<string name="no_video_to_display">Aucune vidéo nest disponible !</string> <string name="no_video_to_display">Aucune vidéo nest disponible !</string>
@ -129,7 +167,8 @@
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> a publié une nouvelle vidéo : <b>%2$s</b>]]></string> <string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> a publié une nouvelle vidéo : <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[Votre vidéo <b>%1$s</b> a été blacklisté]]></string> <string name="peertube_video_blacklist"><![CDATA[Votre vidéo <b>%1$s</b> a été blacklisté]]></string>
<string name="peertube_video_unblacklist"><![CDATA[Votre vidéo <b>%1$s</b> nest plus blacklisté]]></string> <string name="peertube_video_unblacklist"><![CDATA[Votre vidéo <b>%1$s</b> nest plus blacklisté]]></string>
<string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string> <string name="peertube_video_report_success"><![CDATA[ Your abuse <b>%1$s</b> has been accepted]]></string>
<string name="peertube_video_abuse"><![CDATA[Nouveau signalement pour la vidéo : <b>%1$s</b>]]></string>
<string name="add_public_comment">Ajouter un commentaire public</string> <string name="add_public_comment">Ajouter un commentaire public</string>
<string name="send_comment">Envoyer un commentaire</string> <string name="send_comment">Envoyer un commentaire</string>
<string name="all">Tout</string> <string name="all">Tout</string>
@ -160,12 +199,17 @@
<string-array name="settings_video_mode"> <string-array name="settings_video_mode">
<item>Normal</item> <item>Normal</item>
<item>Streaming</item> <item>Streaming</item>
<item>Direct stream</item> <item>Flux direct</item>
</string-array>
<string-array name="settings_theme">
<item>Light</item>
<item>Dark</item>
<item>Automatic</item>
</string-array> </string-array>
<string-array name="settings_video_quality"> <string-array name="settings_video_quality">
<item>High</item> <item>Élevée</item>
<item>Medium</item> <item>Moyenne</item>
<item>Low</item> <item>Faible</item>
</string-array> </string-array>
<string name="unfollow_confirm">Voulez-vous vous désabonner de ce compte ?</string> <string name="unfollow_confirm">Voulez-vous vous désabonner de ce compte ?</string>
<string name="title_video_peertube">Titre de la vidéo</string> <string name="title_video_peertube">Titre de la vidéo</string>
@ -179,7 +223,7 @@
<string name="bookmark_peertube_empty">Il ny a aucune vidéo Peertube dans vos favoris !</string> <string name="bookmark_peertube_empty">Il ny a aucune vidéo Peertube dans vos favoris !</string>
<string name="delete_channel">Supprimer la chaîne</string> <string name="delete_channel">Supprimer la chaîne</string>
<string name="action_channel_confirm_delete">Êtes-vous sûr de vouloir supprimer définitivement cette chaîne ?</string> <string name="action_channel_confirm_delete">Êtes-vous sûr de vouloir supprimer définitivement cette chaîne ?</string>
<string name="modify_playlists">Video in playlists</string> <string name="modify_playlists">Vidéo dans les listes de lecture</string>
<string name="no_muted">Aucun compte en sourdine !</string> <string name="no_muted">Aucun compte en sourdine !</string>
<string name="error_display_name_channel">Vous devez fournir un nom d\'affichage et un nom pour la chaîne!</string> <string name="error_display_name_channel">Vous devez fournir un nom d\'affichage et un nom pour la chaîne!</string>
<string name="action_channel_create">Créer une chaîne</string> <string name="action_channel_create">Créer une chaîne</string>
@ -188,7 +232,7 @@
<string name="report_comment_size">Veuillez préciser les raisons.</string> <string name="report_comment_size">Veuillez préciser les raisons.</string>
<string name="not_logged_in">Vous devez être connecté.e pour effectuer cette action !</string> <string name="not_logged_in">Vous devez être connecté.e pour effectuer cette action !</string>
<string name="successful_report">Le compte a été signalé !</string> <string name="successful_report">Le compte a été signalé !</string>
<string name="successful_report_comment">The comment has been reported!</string> <string name="successful_report_comment">Le commentaire a été signalé !</string>
<string name="successful_video_report">La vidéo a été signalée !</string> <string name="successful_video_report">La vidéo a été signalée !</string>
<string name="password_length_error">Le mot de passe doit contenir 6 caractères !</string> <string name="password_length_error">Le mot de passe doit contenir 6 caractères !</string>
<string name="muted_done">Le compte a été mis en sourdine !</string> <string name="muted_done">Le compte a été mis en sourdine !</string>

View File

@ -1,7 +1,16 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="add_public_reply">Add a public reply</string>
<plurals name="number_of_replies">
<item quantity="one">%d reply</item>
<item quantity="other">%d replies</item>
</plurals>
<string name="reply">Reply</string>
<string name="set_theme">Theme</string>
<string name="set_theme_description">Allow to change app theme</string>
<string name="federation_issue">The video cannot be federated!</string>
<string name="title_home">Inizio</string> <string name="title_home">Inizio</string>
<string name="title_local">Local</string> <string name="title_local">Locale</string>
<string name="title_discover">Esplora</string> <string name="title_discover">Esplora</string>
<string name="title_notifications">Notifiche</string> <string name="title_notifications">Notifiche</string>
<string name="title_recently_added">Aggiunti di recente</string> <string name="title_recently_added">Aggiunti di recente</string>
@ -17,7 +26,7 @@
<string name="instance_choice">Trova un\'istanza</string> <string name="instance_choice">Trova un\'istanza</string>
<string name="not_valide_instance">Questa istanza non sembra essere valida!</string> <string name="not_valide_instance">Questa istanza non sembra essere valida!</string>
<string name="no_videos">Nessun video!</string> <string name="no_videos">Nessun video!</string>
<string name="no_notifications">No notifications!</string> <string name="no_notifications">Nessuna notifica!</string>
<string name="favicon">Favicon</string> <string name="favicon">Favicon</string>
<string name="open_with">Apri con</string> <string name="open_with">Apri con</string>
<string name="action_playlist_edit">Modifica playlist</string> <string name="action_playlist_edit">Modifica playlist</string>
@ -34,7 +43,7 @@
<string name="download">Scarica</string> <string name="download">Scarica</string>
<string name="profile_picture">Immagine di profilo</string> <string name="profile_picture">Immagine di profilo</string>
<string name="update_video">Aggiorna video</string> <string name="update_video">Aggiorna video</string>
<string name="remove_from_playlist">Remove from playlist</string> <string name="remove_from_playlist">Rimuovere dalla playlist</string>
<string name="date_seconds">%d s</string> <string name="date_seconds">%d s</string>
<string name="date_minutes">%d m</string> <string name="date_minutes">%d m</string>
<string name="date_hours">%d h</string> <string name="date_hours">%d h</string>
@ -83,6 +92,33 @@
<string name="delete_comment">Elimina il commento</string> <string name="delete_comment">Elimina il commento</string>
<string name="delete_comment_confirm">Sei sicuro di voler eliminare questo commento?</string> <string name="delete_comment_confirm">Sei sicuro di voler eliminare questo commento?</string>
<string name="set_video_mode">Modalità per i video</string> <string name="set_video_mode">Modalità per i video</string>
<string name="filter">Filtro</string>
<string name="sepia_search">Ricerca Seppia</string>
<string name="sepia_element_nsfw">Visualizzare il contenuto sensibile</string>
<string name="sepia_element_published_date">Data di pubblicazione</string>
<string name="any">Qualsiasi</string>
<string name="today">Oggi</string>
<string name="last_7_days">Ultimi 7 giorni</string>
<string name="last_30_days">Ultimi 30 giorni</string>
<string name="last_365_days">Ultimi 365 giorni</string>
<string name="sepia_element_duration">Durata</string>
<string name="duration_short"><![CDATA[Breve (<4 min)]]></string>
<string name="duration_medium"><![CDATA[Medio (4-10 min)]]></string>
<string name="duration_long"><![CDATA[Lungo (> 10 min)]]></string>
<string name="display_all_categories">Visualizza tutte le categorie</string>
<string name="display_all_licenses">Visualizzare tutte le licenze</string>
<string name="display_all_languages">Visualizza tutte le lingue</string>
<string name="all_of_these_tags">Tutti questi tag</string>
<string name="one_of_these_tags">Uno di questi tag</string>
<string name="apply_filter">Applicare il filtro</string>
<string-array name="sort_by_array">
<item>Migliore partita</item>
<item>I più recenti</item>
<item>Meno recente</item>
</string-array>
<string name="sort_by">Ordina per</string>
<string name="sepia_search_hint">Parola chiave, canale, video, ecc.</string>
<string name="sepia_indication">Sepia Search visualizza video e canali che corrispondono alla tua ricerca, ma non è l\'editore, né il proprietario. Se si notano problemi con un video, segnalarlo agli amministratori sul sito web di PeerTube dove viene pubblicato il video.</string>
<string name="my_videos">I miei video</string> <string name="my_videos">I miei video</string>
<string name="title">Titolo</string> <string name="title">Titolo</string>
<string name="license">Licenza</string> <string name="license">Licenza</string>
@ -105,17 +141,19 @@
<string name="change_instance">Prendi un\'altra istanza</string> <string name="change_instance">Prendi un\'altra istanza</string>
<string name="my_history">Cronologia</string> <string name="my_history">Cronologia</string>
<string name="edit">Modifica</string> <string name="edit">Modifica</string>
<string name="video_settings">Video settings</string> <string name="video_settings">Impostazioni video</string>
<string name="app_interface">Interface</string> <string name="app_interface">Interfaccia</string>
<string name="set_cache_mode">Cache</string> <string name="set_cache_mode">Cache</string>
<string name="set_video_cache_description">Set the cache for videos (default 100Mb)</string> <string name="set_video_cache_description">Impostare la cache per i video (default 100Mb)</string>
<string name="set_video_quality_description">Define a default quality for videos</string> <string name="set_video_quality_description">Definire una qualità predefinita per i video</string>
<string name="set_quality_mode">Resolution for videos</string> <string name="set_quality_mode">Risoluzione per i video</string>
<string name="video_cache_value">Video cache: %d Mb</string> <string name="video_cache_value">Memoria video: %d Mb</string>
<string name="captions">Didascalie</string> <string name="captions">Didascalie</string>
<string name="pickup_captions">Scegliere le didascalie</string> <string name="pickup_captions">Scegliere le didascalie</string>
<string name="none">Nessuno</string> <string name="none">Nessuno</string>
<string name="set_video_mode_description">Permette di cambiare la modalità di riproduzione dei video (di default, in streaming o tramite browser).</string> <string name="set_video_mode_description">Permette di cambiare la modalità di riproduzione dei video (di default, in streaming o tramite browser).</string>
<string name="delete_account_comment">Delete account comments</string>
<string name="delete_account_comment_confirm">Are you sure you want to remove all the comments of this account?</string>
<string name="delete_video">Elimina video</string> <string name="delete_video">Elimina video</string>
<string name="delete_video_confirmation">Sei sicuro di voler eliminare questo video?</string> <string name="delete_video_confirmation">Sei sicuro di voler eliminare questo video?</string>
<string name="no_video_to_display">Nessun video da mostrare!</string> <string name="no_video_to_display">Nessun video da mostrare!</string>
@ -129,7 +167,8 @@
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> ha pubblicato un nuovo video: <b>%2$s</b>]]></string> <string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> ha pubblicato un nuovo video: <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[Il tuo video <b>%1$s</b> è stato messo nella lista nera]]></string> <string name="peertube_video_blacklist"><![CDATA[Il tuo video <b>%1$s</b> è stato messo nella lista nera]]></string>
<string name="peertube_video_unblacklist"><![CDATA[Il tuo video <b>%1$s</b> è stato rimosso dalla lista nera]]></string> <string name="peertube_video_unblacklist"><![CDATA[Il tuo video <b>%1$s</b> è stato rimosso dalla lista nera]]></string>
<string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string> <string name="peertube_video_report_success"><![CDATA[ Your abuse <b>%1$s</b> has been accepted]]></string>
<string name="peertube_video_abuse"><![CDATA[Nuovo rapporto di abuso per il video: <b>%1$s</b>]]></string>
<string name="add_public_comment">Aggiungi un commento pubblico</string> <string name="add_public_comment">Aggiungi un commento pubblico</string>
<string name="send_comment">Invia commento</string> <string name="send_comment">Invia commento</string>
<string name="all">Tutto</string> <string name="all">Tutto</string>
@ -164,12 +203,17 @@
<string-array name="settings_video_mode"> <string-array name="settings_video_mode">
<item>Webview</item> <item>Webview</item>
<item>Stream diretto</item> <item>Stream diretto</item>
<item>Direct stream</item> <item>Flusso diretto</item>
</string-array>
<string-array name="settings_theme">
<item>Light</item>
<item>Dark</item>
<item>Automatic</item>
</string-array> </string-array>
<string-array name="settings_video_quality"> <string-array name="settings_video_quality">
<item>High</item> <item>Alto</item>
<item>Medium</item> <item>Medio</item>
<item>Low</item> <item>Basso</item>
</string-array> </string-array>
<string name="unfollow_confirm">Vuoi smettere di seguire questo account?</string> <string name="unfollow_confirm">Vuoi smettere di seguire questo account?</string>
<string name="title_video_peertube">Titolo per il video</string> <string name="title_video_peertube">Titolo per il video</string>
@ -183,7 +227,7 @@
<string name="bookmark_peertube_empty">Non c\'è nessun video nei tuoi favoriti!</string> <string name="bookmark_peertube_empty">Non c\'è nessun video nei tuoi favoriti!</string>
<string name="delete_channel">Rimuovi Canale</string> <string name="delete_channel">Rimuovi Canale</string>
<string name="action_channel_confirm_delete">Sei sicuro di voler eliminare definitivamente questo canale?</string> <string name="action_channel_confirm_delete">Sei sicuro di voler eliminare definitivamente questo canale?</string>
<string name="modify_playlists">Video in playlists</string> <string name="modify_playlists">Video in playlist</string>
<string name="no_muted">Nessun account silenziato!</string> <string name="no_muted">Nessun account silenziato!</string>
<string name="error_display_name_channel">Devi definire un nome e un nome visualizzato per questo canale!</string> <string name="error_display_name_channel">Devi definire un nome e un nome visualizzato per questo canale!</string>
<string name="action_channel_create">Creare un canale</string> <string name="action_channel_create">Creare un canale</string>
@ -192,7 +236,7 @@
<string name="report_comment_size">Per favore, specifica una motivazione</string> <string name="report_comment_size">Per favore, specifica una motivazione</string>
<string name="not_logged_in">Per eseguire questa operazione, è necessario autenticarsi!</string> <string name="not_logged_in">Per eseguire questa operazione, è necessario autenticarsi!</string>
<string name="successful_report">L\'account è stato segnalato!</string> <string name="successful_report">L\'account è stato segnalato!</string>
<string name="successful_report_comment">The comment has been reported!</string> <string name="successful_report_comment">Il commento è stato riportato!</string>
<string name="successful_video_report">Il video è stato segnalato!</string> <string name="successful_video_report">Il video è stato segnalato!</string>
<string name="password_length_error">La password deve contenere almeno 6 caratteri!</string> <string name="password_length_error">La password deve contenere almeno 6 caratteri!</string>
<string name="muted_done">L\'account è stato silenziato!</string> <string name="muted_done">L\'account è stato silenziato!</string>

View File

@ -1,5 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="add_public_reply">Add a public reply</string>
<plurals name="number_of_replies">
<item quantity="other">%d replies</item>
</plurals>
<string name="reply">Reply</string>
<string name="set_theme">Theme</string>
<string name="set_theme_description">Allow to change app theme</string>
<string name="federation_issue">The video cannot be federated!</string>
<string name="title_home">ホーム</string> <string name="title_home">ホーム</string>
<string name="title_local">Local</string> <string name="title_local">Local</string>
<string name="title_discover">発見</string> <string name="title_discover">発見</string>
@ -83,6 +91,33 @@
<string name="delete_comment">Delete a comment</string> <string name="delete_comment">Delete a comment</string>
<string name="delete_comment_confirm">Are you sure to delete this comment?</string> <string name="delete_comment_confirm">Are you sure to delete this comment?</string>
<string name="set_video_mode">Mode for videos</string> <string name="set_video_mode">Mode for videos</string>
<string name="filter">Filter</string>
<string name="sepia_search">Sepia search</string>
<string name="sepia_element_nsfw">Display sensitive content</string>
<string name="sepia_element_published_date">Published date</string>
<string name="any">Any</string>
<string name="today">Today</string>
<string name="last_7_days">Last 7 days</string>
<string name="last_30_days">Last 30 days</string>
<string name="last_365_days">Last 365 days</string>
<string name="sepia_element_duration">Duration</string>
<string name="duration_short"><![CDATA[Short (<4 min)]]></string>
<string name="duration_medium"><![CDATA[Medium (410 min)]]></string>
<string name="duration_long"><![CDATA[Long (> 10 min)]]></string>
<string name="display_all_categories">Display all categories</string>
<string name="display_all_licenses">Display all licenses</string>
<string name="display_all_languages">Display all languages</string>
<string name="all_of_these_tags">All of these tags</string>
<string name="one_of_these_tags">One of these tags</string>
<string name="apply_filter">Apply filter</string>
<string-array name="sort_by_array">
<item>Best match</item>
<item>Most recent</item>
<item>Least recent</item>
</string-array>
<string name="sort_by">Sort by</string>
<string name="sepia_search_hint">Keyword, channel, video, etc.</string>
<string name="sepia_indication">Sepia Search displays videos and channels that match your search but is not the publisher, nor the owner. If you notice any problems with a video, report it to the administrators on the PeerTube website where the video is published.</string>
<string name="my_videos">My videos</string> <string name="my_videos">My videos</string>
<string name="title">Title</string> <string name="title">Title</string>
<string name="license">License</string> <string name="license">License</string>
@ -116,6 +151,8 @@
<string name="pickup_captions">字幕を選択</string> <string name="pickup_captions">字幕を選択</string>
<string name="none">なし</string> <string name="none">なし</string>
<string name="set_video_mode_description">動画再生モードの変更を許可する(デフォルト、ストリーミングまたはブラウザ経由)。</string> <string name="set_video_mode_description">動画再生モードの変更を許可する(デフォルト、ストリーミングまたはブラウザ経由)。</string>
<string name="delete_account_comment">Delete account comments</string>
<string name="delete_account_comment_confirm">Are you sure you want to remove all the comments of this account?</string>
<string name="delete_video">動画を削除</string> <string name="delete_video">動画を削除</string>
<string name="delete_video_confirmation">この動画を本当に削除しますか?</string> <string name="delete_video_confirmation">この動画を本当に削除しますか?</string>
<string name="no_video_to_display">動画がありません!</string> <string name="no_video_to_display">動画がありません!</string>
@ -129,6 +166,7 @@
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b>が新しい動画を投稿しました: <b>%2$s</b>]]></string> <string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b>が新しい動画を投稿しました: <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[<b>%1$s</b>がブラックリストに追加されました]]></string> <string name="peertube_video_blacklist"><![CDATA[<b>%1$s</b>がブラックリストに追加されました]]></string>
<string name="peertube_video_unblacklist"><![CDATA[<b>%1$s</b>がブラックリストから外されました]]></string> <string name="peertube_video_unblacklist"><![CDATA[<b>%1$s</b>がブラックリストから外されました]]></string>
<string name="peertube_video_report_success"><![CDATA[ Your abuse <b>%1$s</b> has been accepted]]></string>
<string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string> <string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string>
<string name="add_public_comment">パブリックコメントを追加</string> <string name="add_public_comment">パブリックコメントを追加</string>
<string name="send_comment">コメントを送信</string> <string name="send_comment">コメントを送信</string>
@ -166,6 +204,11 @@
<item>Webview</item> <item>Webview</item>
<item>Direct stream</item> <item>Direct stream</item>
</string-array> </string-array>
<string-array name="settings_theme">
<item>Light</item>
<item>Dark</item>
<item>Automatic</item>
</string-array>
<string-array name="settings_video_quality"> <string-array name="settings_video_quality">
<item>High</item> <item>High</item>
<item>Medium</item> <item>Medium</item>

View File

@ -1,5 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="add_public_reply">Add a public reply</string>
<plurals name="number_of_replies">
<item quantity="other">%d replies</item>
</plurals>
<string name="reply">Reply</string>
<string name="set_theme">Theme</string>
<string name="set_theme_description">Allow to change app theme</string>
<string name="federation_issue">The video cannot be federated!</string>
<string name="title_home">Home</string> <string name="title_home">Home</string>
<string name="title_local">Local</string> <string name="title_local">Local</string>
<string name="title_discover">Discover</string> <string name="title_discover">Discover</string>
@ -83,6 +91,33 @@
<string name="delete_comment">Delete a comment</string> <string name="delete_comment">Delete a comment</string>
<string name="delete_comment_confirm">Are you sure to delete this comment?</string> <string name="delete_comment_confirm">Are you sure to delete this comment?</string>
<string name="set_video_mode">Mode for videos</string> <string name="set_video_mode">Mode for videos</string>
<string name="filter">Filter</string>
<string name="sepia_search">Sepia search</string>
<string name="sepia_element_nsfw">Display sensitive content</string>
<string name="sepia_element_published_date">Published date</string>
<string name="any">Any</string>
<string name="today">Today</string>
<string name="last_7_days">Last 7 days</string>
<string name="last_30_days">Last 30 days</string>
<string name="last_365_days">Last 365 days</string>
<string name="sepia_element_duration">Duration</string>
<string name="duration_short"><![CDATA[Short (<4 min)]]></string>
<string name="duration_medium"><![CDATA[Medium (410 min)]]></string>
<string name="duration_long"><![CDATA[Long (> 10 min)]]></string>
<string name="display_all_categories">Display all categories</string>
<string name="display_all_licenses">Display all licenses</string>
<string name="display_all_languages">Display all languages</string>
<string name="all_of_these_tags">All of these tags</string>
<string name="one_of_these_tags">One of these tags</string>
<string name="apply_filter">Apply filter</string>
<string-array name="sort_by_array">
<item>Best match</item>
<item>Most recent</item>
<item>Least recent</item>
</string-array>
<string name="sort_by">Sort by</string>
<string name="sepia_search_hint">Keyword, channel, video, etc.</string>
<string name="sepia_indication">Sepia Search displays videos and channels that match your search but is not the publisher, nor the owner. If you notice any problems with a video, report it to the administrators on the PeerTube website where the video is published.</string>
<string name="my_videos">My videos</string> <string name="my_videos">My videos</string>
<string name="title">Title</string> <string name="title">Title</string>
<string name="license">License</string> <string name="license">License</string>
@ -116,6 +151,8 @@
<string name="pickup_captions">Pick captions</string> <string name="pickup_captions">Pick captions</string>
<string name="none">None</string> <string name="none">None</string>
<string name="set_video_mode_description">Allows to change mode for playing videos (default, streaming or via a browser).</string> <string name="set_video_mode_description">Allows to change mode for playing videos (default, streaming or via a browser).</string>
<string name="delete_account_comment">Delete account comments</string>
<string name="delete_account_comment_confirm">Are you sure you want to remove all the comments of this account?</string>
<string name="delete_video">Delete video</string> <string name="delete_video">Delete video</string>
<string name="delete_video_confirmation">Are you sure to delete this video?</string> <string name="delete_video_confirmation">Are you sure to delete this video?</string>
<string name="no_video_to_display">No videos to display!</string> <string name="no_video_to_display">No videos to display!</string>
@ -129,6 +166,7 @@
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> published a new video: <b>%2$s</b>]]></string> <string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> published a new video: <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[Your video <b>%1$s</b> has been blacklisted]]></string> <string name="peertube_video_blacklist"><![CDATA[Your video <b>%1$s</b> has been blacklisted]]></string>
<string name="peertube_video_unblacklist"><![CDATA[Your video <b>%1$s</b> has been unblacklisted]]></string> <string name="peertube_video_unblacklist"><![CDATA[Your video <b>%1$s</b> has been unblacklisted]]></string>
<string name="peertube_video_report_success"><![CDATA[ Your abuse <b>%1$s</b> has been accepted]]></string>
<string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string> <string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string>
<string name="add_public_comment">Add a public comment</string> <string name="add_public_comment">Add a public comment</string>
<string name="send_comment">Send comment</string> <string name="send_comment">Send comment</string>
@ -166,6 +204,11 @@
<item>Webview</item> <item>Webview</item>
<item>Direct stream</item> <item>Direct stream</item>
</string-array> </string-array>
<string-array name="settings_theme">
<item>Light</item>
<item>Dark</item>
<item>Automatic</item>
</string-array>
<string-array name="settings_video_quality"> <string-array name="settings_video_quality">
<item>High</item> <item>High</item>
<item>Medium</item> <item>Medium</item>

View File

@ -1,5 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="add_public_reply">Add a public reply</string>
<plurals name="number_of_replies">
<item quantity="one">%d reply</item>
<item quantity="other">%d replies</item>
</plurals>
<string name="reply">Reply</string>
<string name="set_theme">Theme</string>
<string name="set_theme_description">Allow to change app theme</string>
<string name="federation_issue">The video cannot be federated!</string>
<string name="title_home">Home</string> <string name="title_home">Home</string>
<string name="title_local">Local</string> <string name="title_local">Local</string>
<string name="title_discover">Ontdek</string> <string name="title_discover">Ontdek</string>
@ -83,6 +92,33 @@
<string name="delete_comment">Een opmerking verwijderen</string> <string name="delete_comment">Een opmerking verwijderen</string>
<string name="delete_comment_confirm">Weet u zeker dat u deze opmerking wilt verwijderen?</string> <string name="delete_comment_confirm">Weet u zeker dat u deze opmerking wilt verwijderen?</string>
<string name="set_video_mode">Modus voor video\'s</string> <string name="set_video_mode">Modus voor video\'s</string>
<string name="filter">Filter</string>
<string name="sepia_search">Sepia search</string>
<string name="sepia_element_nsfw">Display sensitive content</string>
<string name="sepia_element_published_date">Published date</string>
<string name="any">Any</string>
<string name="today">Today</string>
<string name="last_7_days">Last 7 days</string>
<string name="last_30_days">Last 30 days</string>
<string name="last_365_days">Last 365 days</string>
<string name="sepia_element_duration">Duration</string>
<string name="duration_short"><![CDATA[Short (<4 min)]]></string>
<string name="duration_medium"><![CDATA[Medium (410 min)]]></string>
<string name="duration_long"><![CDATA[Long (> 10 min)]]></string>
<string name="display_all_categories">Display all categories</string>
<string name="display_all_licenses">Display all licenses</string>
<string name="display_all_languages">Display all languages</string>
<string name="all_of_these_tags">All of these tags</string>
<string name="one_of_these_tags">One of these tags</string>
<string name="apply_filter">Apply filter</string>
<string-array name="sort_by_array">
<item>Best match</item>
<item>Most recent</item>
<item>Least recent</item>
</string-array>
<string name="sort_by">Sort by</string>
<string name="sepia_search_hint">Keyword, channel, video, etc.</string>
<string name="sepia_indication">Sepia Search displays videos and channels that match your search but is not the publisher, nor the owner. If you notice any problems with a video, report it to the administrators on the PeerTube website where the video is published.</string>
<string name="my_videos">Mijn video\'s</string> <string name="my_videos">Mijn video\'s</string>
<string name="title">Titel</string> <string name="title">Titel</string>
<string name="license">Licentie</string> <string name="license">Licentie</string>
@ -116,6 +152,8 @@
<string name="pickup_captions">Pick captions</string> <string name="pickup_captions">Pick captions</string>
<string name="none">Geen</string> <string name="none">Geen</string>
<string name="set_video_mode_description">Maakt het mogelijk om van modus te veranderen voor het afspelen van video\'s (standaard, streaming of via een browser).</string> <string name="set_video_mode_description">Maakt het mogelijk om van modus te veranderen voor het afspelen van video\'s (standaard, streaming of via een browser).</string>
<string name="delete_account_comment">Delete account comments</string>
<string name="delete_account_comment_confirm">Are you sure you want to remove all the comments of this account?</string>
<string name="delete_video">Video verwijderen</string> <string name="delete_video">Video verwijderen</string>
<string name="delete_video_confirmation">Weet u zeker dat u deze video wilt verwijderen?</string> <string name="delete_video_confirmation">Weet u zeker dat u deze video wilt verwijderen?</string>
<string name="no_video_to_display">Geen video\'s te tonen!</string> <string name="no_video_to_display">Geen video\'s te tonen!</string>
@ -129,6 +167,7 @@
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> publiceerde een nieuwe video: <b>%2$s</b>]]></string> <string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> publiceerde een nieuwe video: <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[Uw video <b>%1$s</b> is op de zwarte lijst geplaatst]]></string> <string name="peertube_video_blacklist"><![CDATA[Uw video <b>%1$s</b> is op de zwarte lijst geplaatst]]></string>
<string name="peertube_video_unblacklist"><![CDATA[Uw video <b>%1$s</b> is niet op de zwarte lijst gezet]]></string> <string name="peertube_video_unblacklist"><![CDATA[Uw video <b>%1$s</b> is niet op de zwarte lijst gezet]]></string>
<string name="peertube_video_report_success"><![CDATA[ Your abuse <b>%1$s</b> has been accepted]]></string>
<string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string> <string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string>
<string name="add_public_comment">Voeg een publieke opmerking toe</string> <string name="add_public_comment">Voeg een publieke opmerking toe</string>
<string name="send_comment">Stuur commentaar</string> <string name="send_comment">Stuur commentaar</string>
@ -166,6 +205,11 @@
<item>Directe stroom</item> <item>Directe stroom</item>
<item>Direct stream</item> <item>Direct stream</item>
</string-array> </string-array>
<string-array name="settings_theme">
<item>Light</item>
<item>Dark</item>
<item>Automatic</item>
</string-array>
<string-array name="settings_video_quality"> <string-array name="settings_video_quality">
<item>High</item> <item>High</item>
<item>Medium</item> <item>Medium</item>

View File

@ -1,74 +1,85 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="title_home">Strona główna</string> <string name="add_public_reply">Dodaj publiczną odpowiedź</string>
<string name="title_local">Local</string> <plurals name="number_of_replies">
<string name="title_discover">Odkryj</string> <item quantity="one">%d odpowiedź</item>
<item quantity="few">%d odpowiedzi</item>
<item quantity="many">%d odpowiedzi</item>
<item quantity="other">%d odpowiedzi</item>
</plurals>
<string name="reply">Odpowiedz</string>
<string name="set_theme">Motyw</string>
<string name="set_theme_description">Zezwól na zmianę motywu aplikacji</string>
<string name="federation_issue">The video cannot be federated!</string>
<string name="title_home">Początek</string>
<string name="title_local">Lokalne</string>
<string name="title_discover">Odkrywaj</string>
<string name="title_notifications">Powiadomienia</string> <string name="title_notifications">Powiadomienia</string>
<string name="title_recently_added">Ostatnio dodany</string> <string name="title_recently_added">Ostatnio dodane</string>
<string name="title_trending">Trendowość</string> <string name="title_trending">Popularne</string>
<string name="title_most_liked">Najbardziej lubiany</string> <string name="title_most_liked">Najbardziej lubiane</string>
<string name="toast_error">Oops! Wystąpił błąd!</string> <string name="toast_error">Ups! Wystąpił błąd!</string>
<string name="title_muted">Wyciszony</string> <string name="title_muted">Wyciszone</string>
<string name="title_channel">Kanały</string> <string name="title_channel">Kanały</string>
<string name="do_not_list">Nie wymieniaj</string> <string name="do_not_list">Nie wymieniaj</string>
<string name="blur">Rozmycie</string> <string name="blur">Rozmycie</string>
<string name="display">Wyświetlacz</string> <string name="display">Wyświetl</string>
<string name="no_opinion">Brak opinii</string> <string name="no_opinion">Brak opinii</string>
<string name="instance_choice">Wybierz instancję</string> <string name="instance_choice">Wybierz instancję</string>
<string name="not_valide_instance">Ten przypadek wydaje się być nieważny!</string> <string name="not_valide_instance">Ta instancja nie wygląda na prawidłową!</string>
<string name="no_videos">Nie ma wideo!</string> <string name="no_videos">Brak filmów!</string>
<string name="no_notifications">No notifications!</string> <string name="no_notifications">Brak powiadomień!</string>
<string name="favicon">Favicon</string> <string name="favicon">Favicon</string>
<string name="open_with">Otwarte z</string> <string name="open_with">Otwórz przez</string>
<string name="action_playlist_edit">Edycja playlisty</string> <string name="action_playlist_edit">Edytuj listę odtwarzania</string>
<string name="close">Zamknij</string> <string name="close">Zamknij</string>
<string name="upload_video">Wczytaj</string> <string name="upload_video">Prześlij</string>
<string name="image_preview">Podgląd obrazu</string> <string name="image_preview">Podgląd obrazu</string>
<string name="file_to_upload">Wybierz plik do przesłania</string> <string name="file_to_upload">Wybierz plik do przesłania</string>
<string name="channel">Kanał</string> <string name="channel">Kanał</string>
<string name="videos">Filmy wideo</string> <string name="videos">Filmy</string>
<string name="channels">Kanały</string> <string name="channels">Kanały</string>
<string name="yes">Tak</string> <string name="yes">Tak</string>
<string name="no">Nie</string> <string name="no">Nie</string>
<string name="cancel">Anuluj</string> <string name="cancel">Anuluj</string>
<string name="download">Pobierz</string> <string name="download">Pobierz</string>
<string name="profile_picture">Zdjęcie profilowe</string> <string name="profile_picture">Zdjęcie profilowe</string>
<string name="update_video">Aktualizacja wideo</string> <string name="update_video">Aktualizuj film</string>
<string name="remove_from_playlist">Remove from playlist</string> <string name="remove_from_playlist">Usuń z listy odtwarzania</string>
<string name="date_seconds">%d s</string> <string name="date_seconds">%d s</string>
<string name="date_minutes">%d m</string> <string name="date_minutes">%d min</string>
<string name="date_hours">%d h</string> <string name="date_hours">%d h</string>
<string name="date_day">%d d</string> <string name="date_day">%d dni</string>
<string name="number_view_video">%s widoki</string> <string name="number_view_video">%s wyświetleń</string>
<string name="title_instance_login">Host instancji</string> <string name="title_instance_login">Host instancji</string>
<string name="uploading">Przesyłanie, proszę czekać…</string> <string name="uploading">Przesyłanie, proszę czekać…</string>
<string name="upload_video_success">Wideo zostało załadowane!</string> <string name="upload_video_success">Film został przesłany!</string>
<string name="toast_cancelled">Przesyłanie anulowane!</string> <string name="toast_cancelled">Przesyłanie anulowane!</string>
<string name="video_uploaded_action">Stuknij tutaj, aby edytować dane wideo.</string> <string name="video_uploaded_action">Dotknij tutaj, aby edytować dane filmu.</string>
<string name="toot_select_image_error">Podczas wyboru nośnika wystąpił błąd!</string> <string name="toot_select_image_error">Podczas wyboru nośnika wystąpił błąd!</string>
<string name="download_file">Pobierz %1$s</string> <string name="download_file">Pobierz %1$s</string>
<string name="action_privacy">Prywatność</string> <string name="action_privacy">Prywatność</string>
<string name="action_logout">Logout</string> <string name="action_logout">Wyloguj</string>
<string name="login">Login</string> <string name="login">Zaloguj</string>
<string name="password">Hasło</string> <string name="password">Hasło</string>
<string name="email">Email</string> <string name="email">E-mail</string>
<string name="tags">Tagi</string> <string name="tags">Znaczniki</string>
<string name="validate">Walidacja</string> <string name="validate">Potwierdź</string>
<string name="share_with">Dzielić się z</string> <string name="share_with">Udostępnij dla</string>
<string name="shared_via">Współdzielone przez TubeLab</string> <string name="shared_via">Udostępnione przez TubeLab</string>
<string name="username">Nazwa użytkownika</string> <string name="username">Nazwa użytkownika</string>
<string name="settings">Ustawienia</string> <string name="settings">Ustawienia</string>
<string name="logout_account_confirmation">Czy na pewno chcesz się wylogować @%1$s@%2$s?</string> <string name="logout_account_confirmation">Czy na pewno chcesz wylogować @%1$s@%2$s?</string>
<string name="following">Obserwowane</string> <string name="following">Obserwowane</string>
<string name="followers">Naśladowcy</string> <string name="followers">Obserwujący</string>
<string name="client_error">Nie można dostać identyfikatora klienta!</string> <string name="client_error">Błąd pobierania ID klienta!</string>
<string name="toast_error_loading_account">Podczas przełączania między kontami wystąpił błąd!</string> <string name="toast_error_loading_account">Wystąpił błąd podczas przełączania konta!</string>
<string name="toast_error_search">Podczas wyszukiwania wystąpił błąd!</string> <string name="toast_error_search">Podczas wyszukiwania wystąpił błąd!</string>
<string name="nothing_to_do">Nie można podjąć żadnych działań</string> <string name="nothing_to_do">Nie można podjąć żadnych działań</string>
<string name="action_follow">Śledź</string> <string name="action_follow">Obserwuj</string>
<string name="action_mute">Niemy</string> <string name="action_mute">Wycisz</string>
<string name="search">Szukaj</string> <string name="search">Szukaj</string>
<string name="delete">Skreślić</string> <string name="delete">Usuń</string>
<string name="action_lists_confirm_delete">Czy na pewno chcesz na stałe usunąć tę listę?</string> <string name="action_lists_confirm_delete">Czy na pewno chcesz na stałe usunąć tę listę?</string>
<string name="action_lists_delete">Usuń listę</string> <string name="action_lists_delete">Usuń listę</string>
<string name="no_comments">Bądź pierwszym, który zostawi komentarz do tego filmu za pomocą prawego górnego przycisku!</string> <string name="no_comments">Bądź pierwszym, który zostawi komentarz do tego filmu za pomocą prawego górnego przycisku!</string>
@ -83,59 +94,89 @@
<string name="delete_comment">Usuń komentarz</string> <string name="delete_comment">Usuń komentarz</string>
<string name="delete_comment_confirm">Czy na pewno usuniesz ten komentarz?</string> <string name="delete_comment_confirm">Czy na pewno usuniesz ten komentarz?</string>
<string name="set_video_mode">Tryb dla filmów wideo</string> <string name="set_video_mode">Tryb dla filmów wideo</string>
<string name="filter">Filtruj</string>
<string name="sepia_search">Wyszukiwanie Sepia</string>
<string name="sepia_element_nsfw">Wyświetlaj wrażliwe treści</string>
<string name="sepia_element_published_date">Data publikacji</string>
<string name="any">Każde</string>
<string name="today">Dzisiaj</string>
<string name="last_7_days">Ostatnie 7 dni</string>
<string name="last_30_days">Ostatnie 30 dni</string>
<string name="last_365_days">Ostatnie 365 dni</string>
<string name="sepia_element_duration">Czas trwania</string>
<string name="duration_short"><![CDATA[Krótkie (<4 min)]]></string>
<string name="duration_medium"><![CDATA[Medium (410 min)]]></string>
<string name="duration_long"><![CDATA[Długie (> 10 min)]]></string>
<string name="display_all_categories">Wyświetl wszystkie kategorie</string>
<string name="display_all_licenses">Wyświetl wszystkie licencje</string>
<string name="display_all_languages">Wyświetl wszystkie języki</string>
<string name="all_of_these_tags">Wszystkie z tych znaczników</string>
<string name="one_of_these_tags">Jeden z tych znaczników</string>
<string name="apply_filter">Zastosuj filtr</string>
<string-array name="sort_by_array">
<item>Najlepsze dopasowanie</item>
<item>Najnowsze</item>
<item>Najstarsze</item>
</string-array>
<string name="sort_by">Sortuj według</string>
<string name="sepia_search_hint">Słowo kluczowe, kanał, film itp.</string>
<string name="sepia_indication">Sepia Search displays videos and channels that match your search but is not the publisher, nor the owner. If you notice any problems with a video, report it to the administrators on the PeerTube website where the video is published.</string>
<string name="my_videos">Moje filmy</string> <string name="my_videos">Moje filmy</string>
<string name="title">Tytuł</string> <string name="title">Tytuł</string>
<string name="license">Licencja</string> <string name="license">Licencja</string>
<string name="category">Kategoria</string> <string name="category">Kategoria</string>
<string name="language">Język</string> <string name="language">Język</string>
<string name="peertube_nsfw">Ten film zawiera dojrzałą lub wyraźną treść</string> <string name="peertube_nsfw">Ten film zawiera treść dla dorosłych lub zawierającą przemoc</string>
<string name="peertube_enable_comments">Włączanie komentarzy wideo</string> <string name="peertube_enable_comments">Zezwól na komentarze</string>
<string name="description">Opis</string> <string name="description">Opis</string>
<string name="toast_peertube_video_updated">Film został zaktualizowany!</string> <string name="toast_peertube_video_updated">Film został zaktualizowany!</string>
<string name="register_account">Zarejestruj konto</string> <string name="register_account">Załóż konto</string>
<string name="email_address">Adres e-mail</string> <string name="email_address">Adres e-mail</string>
<string name="preview">Premiera</string> <string name="preview">Podgląd</string>
<string name="change_preview">Zmiana podglądu</string> <string name="change_preview">Zmi podgląd</string>
<string name="name">Nazwa</string> <string name="name">Nazwa</string>
<string name="display_more">Wyświetlaj więcej</string> <string name="display_more">Pokaż więcej</string>
<string name="no_channels">Żadnych kanałów!</string> <string name="no_channels">Brak kanałów!</string>
<string name="report_helper">Kilka wyjaśnień na temat twojego raportu…</string> <string name="report_helper">Kilka wyjaśnień na temat twojego raportu…</string>
<string name="report_video">Wideo sprawozdawcze</string> <string name="report_video">Zgłoś film</string>
<string name="report">Raport</string> <string name="report">Zgłoś</string>
<string name="change_instance">Wybierz inny przypadek</string> <string name="change_instance">Wybierz inną instancję</string>
<string name="my_history">Historia</string> <string name="my_history">Historia</string>
<string name="edit">Edycja</string> <string name="edit">Edytuj</string>
<string name="video_settings">Video settings</string> <string name="video_settings">Ustawienia filmu</string>
<string name="app_interface">Interface</string> <string name="app_interface">Interfejs</string>
<string name="set_cache_mode">Cache</string> <string name="set_cache_mode">Pamięć podręczna</string>
<string name="set_video_cache_description">Set the cache for videos (default 100Mb)</string> <string name="set_video_cache_description">Ustaw pamięć podręczną dla filmów (domyślnie 100Mb)</string>
<string name="set_video_quality_description">Define a default quality for videos</string> <string name="set_video_quality_description">Ustaw domyślną jakość filmów</string>
<string name="set_quality_mode">Resolution for videos</string> <string name="set_quality_mode">Rozdzielczość filmów</string>
<string name="video_cache_value">Video cache: %d Mb</string> <string name="video_cache_value">Pamięć podręczna: %d Mb</string>
<string name="captions">Podpisy</string> <string name="captions">Napisy</string>
<string name="pickup_captions">Wybierz podpisy</string> <string name="pickup_captions">Wybierz napisy</string>
<string name="none">Brak</string> <string name="none">Brak</string>
<string name="set_video_mode_description">Umożliwia zmianę trybu odtwarzania filmów (domyślnie, strumieniowo lub za pomocą przeglądarki).</string> <string name="set_video_mode_description">Umożliwia zmianę trybu odtwarzania filmów (domyślnie, strumieniowo lub za pomocą przeglądarki).</string>
<string name="delete_video">Usuń video</string> <string name="delete_account_comment">Usuń komentarze użytkownika</string>
<string name="delete_video_confirmation">Czy na pewno usuniesz ten film?</string> <string name="delete_account_comment_confirm">Czy na pewno chcesz usunąć wszystkie komentarze tego użytkownika?</string>
<string name="delete_video">Usuń film</string>
<string name="delete_video_confirmation">Czy na pewno chcesz usunąć ten film?</string>
<string name="no_video_to_display">Brak filmów do wyświetlenia!</string> <string name="no_video_to_display">Brak filmów do wyświetlenia!</string>
<string name="share">Podziel się</string> <string name="share">Udostępnij</string>
<string name="peertube_comment_on_video"><![CDATA[<b>%1$s</b> skomentował twój film <b>%2$s</b>]]></string> <string name="peertube_comment_on_video"><![CDATA[<b>%1$s</b> dodaje komentarz do Twojego filmu <b>%2$s</b>]]></string>
<string name="peertube_follow_channel"><![CDATA[<b>%1$s</b> podąża za twoim kanałem <b>%2$s</b>]]></string> <string name="peertube_follow_channel"><![CDATA[<b>%1$s</b> obserwuje Twój kanał <b>%2$s</b>]]></string>
<string name="peertube_follow_account"><![CDATA[<b>%1$s</b> śledzi twoje konto]]></string> <string name="peertube_follow_account"><![CDATA[<b>%1$s</b> obserwuje Twoje konto]]></string>
<string name="peertube_video_published"><![CDATA[Twój film <b>%1$s</b> został opublikowany]]></string> <string name="peertube_video_published"><![CDATA[Twój film <b>%1$s</b> został opublikowany]]></string>
<string name="peertube_video_import_success"><![CDATA[Twój import wideo <b>%1$s</b> udał się]]></string> <string name="peertube_video_import_success"><![CDATA[Twój import wideo <b>%1$s</b> udał się]]></string>
<string name="peertube_video_import_error"><![CDATA[Twój import wideo <b>%1$s</b> nie powiódł się]]></string> <string name="peertube_video_import_error"><![CDATA[Twój import wideo <b>%1$s</b> nie powiódł się]]></string>
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> opublikował nowe wideo: <b>%2$s</b>]]></string> <string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> publikuje nowy film: <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[Twój film <b>%1$s</b> został umieszczony na czarnej liście]]></string> <string name="peertube_video_blacklist"><![CDATA[Twój film <b>%1$s</b> został umieszczony na czarnej liście]]></string>
<string name="peertube_video_unblacklist"><![CDATA[Twój film <b>%1$s</b> został usunięty z czarnej listy]]></string> <string name="peertube_video_unblacklist"><![CDATA[Twój film <b>%1$s</b> został usunięty z czarnej listy]]></string>
<string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string> <string name="peertube_video_report_success"><![CDATA[ Your abuse <b>%1$s</b> has been accepted]]></string>
<string name="add_public_comment">Dodaj komentarz publiczny</string> <string name="peertube_video_abuse"><![CDATA[Nowe zgłoszenie nadużycia dla filmu: <b>%1$s</b>]]></string>
<string name="send_comment">Wyślij komentarz</string> <string name="add_public_comment">Dodaj publiczny komentarz</string>
<string name="send_comment">Prześlij komentarz</string>
<string name="all">Wszystkie</string> <string name="all">Wszystkie</string>
<!-- end languages --> <!-- end languages -->
<string name="playlists">Playlisty</string> <string name="playlists">Listy odtwarzania</string>
<string name="display_name">Nazwa wyświetlacza</string> <string name="display_name">Wyświetlana nazwa</string>
<string name="action_playlist_add">Nie masz żadnej playlisty. Stuknij ikonę \"+\", aby dodać nową listę odtwarzania</string> <string name="action_playlist_add">Nie masz żadnej playlisty. Stuknij ikonę \"+\", aby dodać nową listę odtwarzania</string>
<string name="error_display_name">Musisz podać nazwę wyświetlacza!</string> <string name="error_display_name">Musisz podać nazwę wyświetlacza!</string>
<string name="error_channel_mandatory">Kanał jest wymagany, gdy lista odtwarzania jest publiczna.</string> <string name="error_channel_mandatory">Kanał jest wymagany, gdy lista odtwarzania jest publiczna.</string>
@ -160,19 +201,24 @@
<b>Ważny</b>Jeśli Twoja instancja wymaga weryfikacji, otrzymasz e-mail, gdy zostanie potwierdzony! <b>Ważny</b>Jeśli Twoja instancja wymaga weryfikacji, otrzymasz e-mail, gdy zostanie potwierdzony!
</string> </string>
<string name="account">Konto</string> <string name="account">Konto</string>
<string name="report_account">Rachunek sprawozdawczy</string> <string name="report_account">Zgłoś konto</string>
<string-array name="settings_video_mode"> <string-array name="settings_video_mode">
<item>Webview</item> <item>Webview</item>
<item>Strumień bezpośredni</item> <item>Webview</item>
<item>Direct stream</item> <item>Bezpośrednio</item>
</string-array>
<string-array name="settings_theme">
<item>Jasny</item>
<item>Ciemny</item>
<item>Automatyczny</item>
</string-array> </string-array>
<string-array name="settings_video_quality"> <string-array name="settings_video_quality">
<item>High</item> <item>Wysoka</item>
<item>Medium</item> <item>Średnia</item>
<item>Low</item> <item>Niska</item>
</string-array> </string-array>
<string name="unfollow_confirm">Chcesz rozwinąć to konto?</string> <string name="unfollow_confirm">Czy chcesz przestać obserwować to konto?</string>
<string name="title_video_peertube">Tytuł filmu wideo</string> <string name="title_video_peertube">Tytuł filmu</string>
<string name="join_peertube">Dołącz do Peertube</string> <string name="join_peertube">Dołącz do Peertube</string>
<string name="agreement_check_peertube">Mam co najmniej 16 lat i zgadzam się na %1$s w tym przypadku</string> <string name="agreement_check_peertube">Mam co najmniej 16 lat i zgadzam się na %1$s w tym przypadku</string>
<string name="edit_profile">Profil edycyjny</string> <string name="edit_profile">Profil edycyjny</string>
@ -183,7 +229,7 @@
<string name="bookmark_peertube_empty">Nie ma żadnych filmów w twoich ulubionych!</string> <string name="bookmark_peertube_empty">Nie ma żadnych filmów w twoich ulubionych!</string>
<string name="delete_channel">Usuń kanał</string> <string name="delete_channel">Usuń kanał</string>
<string name="action_channel_confirm_delete">Czy na pewno na stałe usuniesz ten kanał?</string> <string name="action_channel_confirm_delete">Czy na pewno na stałe usuniesz ten kanał?</string>
<string name="modify_playlists">Video in playlists</string> <string name="modify_playlists">Filmy w liście odtwarzania</string>
<string name="no_muted">Nie ma wyciszonych kont!</string> <string name="no_muted">Nie ma wyciszonych kont!</string>
<string name="error_display_name_channel">Musisz zdefiniować nazwę i nazwę wyświetlania dla tego kanału!</string> <string name="error_display_name_channel">Musisz zdefiniować nazwę i nazwę wyświetlania dla tego kanału!</string>
<string name="action_channel_create">Stwórz kanał</string> <string name="action_channel_create">Stwórz kanał</string>
@ -192,7 +238,7 @@
<string name="report_comment_size">Proszę podać przyczyny</string> <string name="report_comment_size">Proszę podać przyczyny</string>
<string name="not_logged_in">Musisz być uwierzytelniony, aby przystąpić do tej akcji!</string> <string name="not_logged_in">Musisz być uwierzytelniony, aby przystąpić do tej akcji!</string>
<string name="successful_report">Rachunek został zgłoszony!</string> <string name="successful_report">Rachunek został zgłoszony!</string>
<string name="successful_report_comment">The comment has been reported!</string> <string name="successful_report_comment">Komentarz został zgłoszony!</string>
<string name="successful_video_report">Film został zgłoszony!</string> <string name="successful_video_report">Film został zgłoszony!</string>
<string name="password_length_error">Hasło musi zawierać co najmniej 6 znaków!</string> <string name="password_length_error">Hasło musi zawierać co najmniej 6 znaków!</string>
<string name="muted_done">Rachunek został wyciszony!</string> <string name="muted_done">Rachunek został wyciszony!</string>

View File

@ -1,5 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="add_public_reply">Add a public reply</string>
<plurals name="number_of_replies">
<item quantity="one">%d reply</item>
<item quantity="other">%d replies</item>
</plurals>
<string name="reply">Reply</string>
<string name="set_theme">Theme</string>
<string name="set_theme_description">Allow to change app theme</string>
<string name="federation_issue">The video cannot be federated!</string>
<string name="title_home">Home</string> <string name="title_home">Home</string>
<string name="title_local">Local</string> <string name="title_local">Local</string>
<string name="title_discover">Discover</string> <string name="title_discover">Discover</string>
@ -83,6 +92,33 @@
<string name="delete_comment">Delete a comment</string> <string name="delete_comment">Delete a comment</string>
<string name="delete_comment_confirm">Are you sure to delete this comment?</string> <string name="delete_comment_confirm">Are you sure to delete this comment?</string>
<string name="set_video_mode">Mode for videos</string> <string name="set_video_mode">Mode for videos</string>
<string name="filter">Filter</string>
<string name="sepia_search">Sepia search</string>
<string name="sepia_element_nsfw">Display sensitive content</string>
<string name="sepia_element_published_date">Published date</string>
<string name="any">Any</string>
<string name="today">Today</string>
<string name="last_7_days">Last 7 days</string>
<string name="last_30_days">Last 30 days</string>
<string name="last_365_days">Last 365 days</string>
<string name="sepia_element_duration">Duration</string>
<string name="duration_short"><![CDATA[Short (<4 min)]]></string>
<string name="duration_medium"><![CDATA[Medium (410 min)]]></string>
<string name="duration_long"><![CDATA[Long (> 10 min)]]></string>
<string name="display_all_categories">Display all categories</string>
<string name="display_all_licenses">Display all licenses</string>
<string name="display_all_languages">Display all languages</string>
<string name="all_of_these_tags">All of these tags</string>
<string name="one_of_these_tags">One of these tags</string>
<string name="apply_filter">Apply filter</string>
<string-array name="sort_by_array">
<item>Best match</item>
<item>Most recent</item>
<item>Least recent</item>
</string-array>
<string name="sort_by">Sort by</string>
<string name="sepia_search_hint">Keyword, channel, video, etc.</string>
<string name="sepia_indication">Sepia Search displays videos and channels that match your search but is not the publisher, nor the owner. If you notice any problems with a video, report it to the administrators on the PeerTube website where the video is published.</string>
<string name="my_videos">My videos</string> <string name="my_videos">My videos</string>
<string name="title">Title</string> <string name="title">Title</string>
<string name="license">License</string> <string name="license">License</string>
@ -116,6 +152,8 @@
<string name="pickup_captions">Pick captions</string> <string name="pickup_captions">Pick captions</string>
<string name="none">None</string> <string name="none">None</string>
<string name="set_video_mode_description">Allows to change mode for playing videos (default, streaming or via a browser).</string> <string name="set_video_mode_description">Allows to change mode for playing videos (default, streaming or via a browser).</string>
<string name="delete_account_comment">Delete account comments</string>
<string name="delete_account_comment_confirm">Are you sure you want to remove all the comments of this account?</string>
<string name="delete_video">Delete video</string> <string name="delete_video">Delete video</string>
<string name="delete_video_confirmation">Are you sure to delete this video?</string> <string name="delete_video_confirmation">Are you sure to delete this video?</string>
<string name="no_video_to_display">No videos to display!</string> <string name="no_video_to_display">No videos to display!</string>
@ -129,6 +167,7 @@
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> published a new video: <b>%2$s</b>]]></string> <string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> published a new video: <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[Your video <b>%1$s</b> has been blacklisted]]></string> <string name="peertube_video_blacklist"><![CDATA[Your video <b>%1$s</b> has been blacklisted]]></string>
<string name="peertube_video_unblacklist"><![CDATA[Your video <b>%1$s</b> has been unblacklisted]]></string> <string name="peertube_video_unblacklist"><![CDATA[Your video <b>%1$s</b> has been unblacklisted]]></string>
<string name="peertube_video_report_success"><![CDATA[ Your abuse <b>%1$s</b> has been accepted]]></string>
<string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string> <string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string>
<string name="add_public_comment">Add a public comment</string> <string name="add_public_comment">Add a public comment</string>
<string name="send_comment">Send comment</string> <string name="send_comment">Send comment</string>
@ -166,6 +205,11 @@
<item>Webview</item> <item>Webview</item>
<item>Direct stream</item> <item>Direct stream</item>
</string-array> </string-array>
<string-array name="settings_theme">
<item>Light</item>
<item>Dark</item>
<item>Automatic</item>
</string-array>
<string-array name="settings_video_quality"> <string-array name="settings_video_quality">
<item>High</item> <item>High</item>
<item>Medium</item> <item>Medium</item>

View File

@ -1,5 +1,15 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="add_public_reply">Add a public reply</string>
<plurals name="number_of_replies">
<item quantity="one">%d reply</item>
<item quantity="few">%d replies</item>
<item quantity="other">%d replies</item>
</plurals>
<string name="reply">Reply</string>
<string name="set_theme">Theme</string>
<string name="set_theme_description">Allow to change app theme</string>
<string name="federation_issue">The video cannot be federated!</string>
<string name="title_home">Home</string> <string name="title_home">Home</string>
<string name="title_local">Local</string> <string name="title_local">Local</string>
<string name="title_discover">Discover</string> <string name="title_discover">Discover</string>
@ -83,6 +93,33 @@
<string name="delete_comment">Delete a comment</string> <string name="delete_comment">Delete a comment</string>
<string name="delete_comment_confirm">Are you sure to delete this comment?</string> <string name="delete_comment_confirm">Are you sure to delete this comment?</string>
<string name="set_video_mode">Mode for videos</string> <string name="set_video_mode">Mode for videos</string>
<string name="filter">Filter</string>
<string name="sepia_search">Sepia search</string>
<string name="sepia_element_nsfw">Display sensitive content</string>
<string name="sepia_element_published_date">Published date</string>
<string name="any">Any</string>
<string name="today">Today</string>
<string name="last_7_days">Last 7 days</string>
<string name="last_30_days">Last 30 days</string>
<string name="last_365_days">Last 365 days</string>
<string name="sepia_element_duration">Duration</string>
<string name="duration_short"><![CDATA[Short (<4 min)]]></string>
<string name="duration_medium"><![CDATA[Medium (410 min)]]></string>
<string name="duration_long"><![CDATA[Long (> 10 min)]]></string>
<string name="display_all_categories">Display all categories</string>
<string name="display_all_licenses">Display all licenses</string>
<string name="display_all_languages">Display all languages</string>
<string name="all_of_these_tags">All of these tags</string>
<string name="one_of_these_tags">One of these tags</string>
<string name="apply_filter">Apply filter</string>
<string-array name="sort_by_array">
<item>Best match</item>
<item>Most recent</item>
<item>Least recent</item>
</string-array>
<string name="sort_by">Sort by</string>
<string name="sepia_search_hint">Keyword, channel, video, etc.</string>
<string name="sepia_indication">Sepia Search displays videos and channels that match your search but is not the publisher, nor the owner. If you notice any problems with a video, report it to the administrators on the PeerTube website where the video is published.</string>
<string name="my_videos">My videos</string> <string name="my_videos">My videos</string>
<string name="title">Title</string> <string name="title">Title</string>
<string name="license">License</string> <string name="license">License</string>
@ -116,6 +153,8 @@
<string name="pickup_captions">Pick captions</string> <string name="pickup_captions">Pick captions</string>
<string name="none">None</string> <string name="none">None</string>
<string name="set_video_mode_description">Allows to change mode for playing videos (default, streaming or via a browser).</string> <string name="set_video_mode_description">Allows to change mode for playing videos (default, streaming or via a browser).</string>
<string name="delete_account_comment">Delete account comments</string>
<string name="delete_account_comment_confirm">Are you sure you want to remove all the comments of this account?</string>
<string name="delete_video">Delete video</string> <string name="delete_video">Delete video</string>
<string name="delete_video_confirmation">Are you sure to delete this video?</string> <string name="delete_video_confirmation">Are you sure to delete this video?</string>
<string name="no_video_to_display">No videos to display!</string> <string name="no_video_to_display">No videos to display!</string>
@ -129,6 +168,7 @@
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> published a new video: <b>%2$s</b>]]></string> <string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> published a new video: <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[Your video <b>%1$s</b> has been blacklisted]]></string> <string name="peertube_video_blacklist"><![CDATA[Your video <b>%1$s</b> has been blacklisted]]></string>
<string name="peertube_video_unblacklist"><![CDATA[Your video <b>%1$s</b> has been unblacklisted]]></string> <string name="peertube_video_unblacklist"><![CDATA[Your video <b>%1$s</b> has been unblacklisted]]></string>
<string name="peertube_video_report_success"><![CDATA[ Your abuse <b>%1$s</b> has been accepted]]></string>
<string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string> <string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string>
<string name="add_public_comment">Add a public comment</string> <string name="add_public_comment">Add a public comment</string>
<string name="send_comment">Send comment</string> <string name="send_comment">Send comment</string>
@ -166,6 +206,11 @@
<item>Webview</item> <item>Webview</item>
<item>Direct stream</item> <item>Direct stream</item>
</string-array> </string-array>
<string-array name="settings_theme">
<item>Light</item>
<item>Dark</item>
<item>Automatic</item>
</string-array>
<string-array name="settings_video_quality"> <string-array name="settings_video_quality">
<item>High</item> <item>High</item>
<item>Medium</item> <item>Medium</item>

View File

@ -1,12 +1,23 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="add_public_reply">Add a public reply</string>
<plurals name="number_of_replies">
<item quantity="one">%d reply</item>
<item quantity="few">%d replies</item>
<item quantity="many">%d replies</item>
<item quantity="other">%d replies</item>
</plurals>
<string name="reply">Reply</string>
<string name="set_theme">Тема</string>
<string name="set_theme_description">Позволяет менять тему приложения</string>
<string name="federation_issue">Видео не может быть объединено!</string>
<string name="title_home">Главная</string> <string name="title_home">Главная</string>
<string name="title_local">Локальные</string> <string name="title_local">Локальные</string>
<string name="title_discover">Подборка</string> <string name="title_discover">Подборка</string>
<string name="title_notifications">Уведомления</string> <string name="title_notifications">Уведомления</string>
<string name="title_recently_added">По добавлению</string> <string name="title_recently_added">Свежие</string>
<string name="title_trending">Популярные</string> <string name="title_trending">Актуальное</string>
<string name="title_most_liked">Много лайков</string> <string name="title_most_liked">Популярные</string>
<string name="toast_error">Упс! Произошла ошибка!</string> <string name="toast_error">Упс! Произошла ошибка!</string>
<string name="title_muted">Беззвучный</string> <string name="title_muted">Беззвучный</string>
<string name="title_channel">Каналы</string> <string name="title_channel">Каналы</string>
@ -83,6 +94,33 @@
<string name="delete_comment">Удалить комментарий</string> <string name="delete_comment">Удалить комментарий</string>
<string name="delete_comment_confirm">Вы уверены, что хотите удалить этот комментарий?</string> <string name="delete_comment_confirm">Вы уверены, что хотите удалить этот комментарий?</string>
<string name="set_video_mode">Режим для видео</string> <string name="set_video_mode">Режим для видео</string>
<string name="filter">Фильтр</string>
<string name="sepia_search">Поисковик Sepia</string>
<string name="sepia_element_nsfw">Показывать неприличные видео</string>
<string name="sepia_element_published_date">Дата публикации</string>
<string name="any">Любые</string>
<string name="today">Сегодня</string>
<string name="last_7_days">Последние 7 дней</string>
<string name="last_30_days">Последние 30 дней</string>
<string name="last_365_days">Последние 365 дней</string>
<string name="sepia_element_duration">Длительность</string>
<string name="duration_short"><![CDATA[Короткие (<4 мин)]]></string>
<string name="duration_medium"><![CDATA[Средние (410 мин)]]></string>
<string name="duration_long"><![CDATA[Длинные (> 10 мин)]]></string>
<string name="display_all_categories">Показать все категории</string>
<string name="display_all_licenses">Показать все лицензии</string>
<string name="display_all_languages">Показать все языки</string>
<string name="all_of_these_tags">Все с этими тегами</string>
<string name="one_of_these_tags">Один из этих тегов</string>
<string name="apply_filter">Применить фильтр</string>
<string-array name="sort_by_array">
<item>Лучшее совпадение</item>
<item>Последние</item>
<item>Ранние</item>
</string-array>
<string name="sort_by">Сортировать по</string>
<string name="sepia_search_hint">Ключевое слово, канал, видео и т. д.</string>
<string name="sepia_indication">Sepia Search отображает видео и каналы, которые соответствуют вашему поиску, но не являются ни издателем, ни владельцем. Если вы заметили какие-либо проблемы с видео, сообщите об этом администраторам на сайте PeerTube, где это видео опубликовано.</string>
<string name="my_videos">Мои видео</string> <string name="my_videos">Мои видео</string>
<string name="title">Название</string> <string name="title">Название</string>
<string name="license">Лицензия</string> <string name="license">Лицензия</string>
@ -108,14 +146,16 @@
<string name="video_settings">Настройки видео</string> <string name="video_settings">Настройки видео</string>
<string name="app_interface">Интерфейс</string> <string name="app_interface">Интерфейс</string>
<string name="set_cache_mode">Кэш</string> <string name="set_cache_mode">Кэш</string>
<string name="set_video_cache_description">Определите кеш для видео (по умолчанию 100 Мб)</string> <string name="set_video_cache_description">Определите кэш для видео (по умолчанию 100 Мб)</string>
<string name="set_video_quality_description">Определить качество видео по умолчанию</string> <string name="set_video_quality_description">Определить качество видео по умолчанию</string>
<string name="set_quality_mode">Разрешение для видео</string> <string name="set_quality_mode">Разрешение для видео</string>
<string name="video_cache_value">Видео кэш: %d Мб</string> <string name="video_cache_value">Видео кэш: %d Мб</string>
<string name="captions">Субтитры</string> <string name="captions">Субтитры</string>
<string name="pickup_captions">Выбрать субтитры</string> <string name="pickup_captions">Выбрать субтитры</string>
<string name="none">Ничто</string> <string name="none">Ничто</string>
<string name="set_video_mode_description">Позволяет изменить режим воспроизведения видео (по умолчанию потоковый или через браузер).</string> <string name="set_video_mode_description">Позволяет изменить режим воспроизведения видео (по умолчанию, потоковый или через браузер).</string>
<string name="delete_account_comment">Удалить комментарии аккаунта</string>
<string name="delete_account_comment_confirm">Вы действительно хотите удалить все комментарии этого аккаунта?</string>
<string name="delete_video">Удалить видео</string> <string name="delete_video">Удалить видео</string>
<string name="delete_video_confirmation">Вы уверены, что хотите удалить это видео?</string> <string name="delete_video_confirmation">Вы уверены, что хотите удалить это видео?</string>
<string name="no_video_to_display">Нет видео для отображения!</string> <string name="no_video_to_display">Нет видео для отображения!</string>
@ -129,6 +169,7 @@
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> опубликовал новое видео: <b>%2$s</b>]]></string> <string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> опубликовал новое видео: <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[Ваше видео <b>%1$s</b> занесено в чёрный список]]></string> <string name="peertube_video_blacklist"><![CDATA[Ваше видео <b>%1$s</b> занесено в чёрный список]]></string>
<string name="peertube_video_unblacklist"><![CDATA[Ваше видео <b>%1$s</b> удалено из чёрного списка]]></string> <string name="peertube_video_unblacklist"><![CDATA[Ваше видео <b>%1$s</b> удалено из чёрного списка]]></string>
<string name="peertube_video_report_success"><![CDATA[ Your abuse <b>%1$s</b> has been accepted]]></string>
<string name="peertube_video_abuse"><![CDATA[Новый отчёт о нарушении для видео: <b>%1$s</b>]]></string> <string name="peertube_video_abuse"><![CDATA[Новый отчёт о нарушении для видео: <b>%1$s</b>]]></string>
<string name="add_public_comment">Добавить публичный комментарий</string> <string name="add_public_comment">Добавить публичный комментарий</string>
<string name="send_comment">Оставить комментарий</string> <string name="send_comment">Оставить комментарий</string>
@ -162,9 +203,14 @@
<string name="account">Аккаунт</string> <string name="account">Аккаунт</string>
<string name="report_account">Пожаловаться на аккаунт</string> <string name="report_account">Пожаловаться на аккаунт</string>
<string-array name="settings_video_mode"> <string-array name="settings_video_mode">
<item>По умолчанию</item>
<item>Веб-просмотр</item> <item>Веб-просмотр</item>
<item>Прямой поток</item> <item>Прямой поток</item>
<item>Прямой поток</item> </string-array>
<string-array name="settings_theme">
<item>Светлая</item>
<item>Тёмная</item>
<item>Авто</item>
</string-array> </string-array>
<string-array name="settings_video_quality"> <string-array name="settings_video_quality">
<item>Высокое</item> <item>Высокое</item>

View File

@ -1,5 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="add_public_reply">Add a public reply</string>
<plurals name="number_of_replies">
<item quantity="one">%d reply</item>
<item quantity="other">%d replies</item>
</plurals>
<string name="reply">Reply</string>
<string name="set_theme">Theme</string>
<string name="set_theme_description">Allow to change app theme</string>
<string name="federation_issue">The video cannot be federated!</string>
<string name="title_home">Home</string> <string name="title_home">Home</string>
<string name="title_local">Local</string> <string name="title_local">Local</string>
<string name="title_discover">Discover</string> <string name="title_discover">Discover</string>
@ -83,6 +92,33 @@
<string name="delete_comment">Delete a comment</string> <string name="delete_comment">Delete a comment</string>
<string name="delete_comment_confirm">Are you sure to delete this comment?</string> <string name="delete_comment_confirm">Are you sure to delete this comment?</string>
<string name="set_video_mode">Mode for videos</string> <string name="set_video_mode">Mode for videos</string>
<string name="filter">Filter</string>
<string name="sepia_search">Sepia search</string>
<string name="sepia_element_nsfw">Display sensitive content</string>
<string name="sepia_element_published_date">Published date</string>
<string name="any">Any</string>
<string name="today">Today</string>
<string name="last_7_days">Last 7 days</string>
<string name="last_30_days">Last 30 days</string>
<string name="last_365_days">Last 365 days</string>
<string name="sepia_element_duration">Duration</string>
<string name="duration_short"><![CDATA[Short (<4 min)]]></string>
<string name="duration_medium"><![CDATA[Medium (410 min)]]></string>
<string name="duration_long"><![CDATA[Long (> 10 min)]]></string>
<string name="display_all_categories">Display all categories</string>
<string name="display_all_licenses">Display all licenses</string>
<string name="display_all_languages">Display all languages</string>
<string name="all_of_these_tags">All of these tags</string>
<string name="one_of_these_tags">One of these tags</string>
<string name="apply_filter">Apply filter</string>
<string-array name="sort_by_array">
<item>Best match</item>
<item>Most recent</item>
<item>Least recent</item>
</string-array>
<string name="sort_by">Sort by</string>
<string name="sepia_search_hint">Keyword, channel, video, etc.</string>
<string name="sepia_indication">Sepia Search displays videos and channels that match your search but is not the publisher, nor the owner. If you notice any problems with a video, report it to the administrators on the PeerTube website where the video is published.</string>
<string name="my_videos">My videos</string> <string name="my_videos">My videos</string>
<string name="title">Title</string> <string name="title">Title</string>
<string name="license">License</string> <string name="license">License</string>
@ -116,6 +152,8 @@
<string name="pickup_captions">Pick captions</string> <string name="pickup_captions">Pick captions</string>
<string name="none">None</string> <string name="none">None</string>
<string name="set_video_mode_description">Allows to change mode for playing videos (default, streaming or via a browser).</string> <string name="set_video_mode_description">Allows to change mode for playing videos (default, streaming or via a browser).</string>
<string name="delete_account_comment">Delete account comments</string>
<string name="delete_account_comment_confirm">Are you sure you want to remove all the comments of this account?</string>
<string name="delete_video">Delete video</string> <string name="delete_video">Delete video</string>
<string name="delete_video_confirmation">Are you sure to delete this video?</string> <string name="delete_video_confirmation">Are you sure to delete this video?</string>
<string name="no_video_to_display">No videos to display!</string> <string name="no_video_to_display">No videos to display!</string>
@ -129,6 +167,7 @@
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> published a new video: <b>%2$s</b>]]></string> <string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> published a new video: <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[Your video <b>%1$s</b> has been blacklisted]]></string> <string name="peertube_video_blacklist"><![CDATA[Your video <b>%1$s</b> has been blacklisted]]></string>
<string name="peertube_video_unblacklist"><![CDATA[Your video <b>%1$s</b> has been unblacklisted]]></string> <string name="peertube_video_unblacklist"><![CDATA[Your video <b>%1$s</b> has been unblacklisted]]></string>
<string name="peertube_video_report_success"><![CDATA[ Your abuse <b>%1$s</b> has been accepted]]></string>
<string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string> <string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string>
<string name="add_public_comment">Add a public comment</string> <string name="add_public_comment">Add a public comment</string>
<string name="send_comment">Send comment</string> <string name="send_comment">Send comment</string>
@ -166,6 +205,11 @@
<item>Webview</item> <item>Webview</item>
<item>Direct stream</item> <item>Direct stream</item>
</string-array> </string-array>
<string-array name="settings_theme">
<item>Light</item>
<item>Dark</item>
<item>Automatic</item>
</string-array>
<string-array name="settings_video_quality"> <string-array name="settings_video_quality">
<item>High</item> <item>High</item>
<item>Medium</item> <item>Medium</item>

View File

@ -1,5 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="add_public_reply">Add a public reply</string>
<plurals name="number_of_replies">
<item quantity="other">%d replies</item>
</plurals>
<string name="reply">Reply</string>
<string name="set_theme">Theme</string>
<string name="set_theme_description">Allow to change app theme</string>
<string name="federation_issue">The video cannot be federated!</string>
<string name="title_home">Home</string> <string name="title_home">Home</string>
<string name="title_local">Local</string> <string name="title_local">Local</string>
<string name="title_discover">Discover</string> <string name="title_discover">Discover</string>
@ -83,6 +91,33 @@
<string name="delete_comment">Delete a comment</string> <string name="delete_comment">Delete a comment</string>
<string name="delete_comment_confirm">Are you sure to delete this comment?</string> <string name="delete_comment_confirm">Are you sure to delete this comment?</string>
<string name="set_video_mode">Mode for videos</string> <string name="set_video_mode">Mode for videos</string>
<string name="filter">Filter</string>
<string name="sepia_search">Sepia search</string>
<string name="sepia_element_nsfw">Display sensitive content</string>
<string name="sepia_element_published_date">Published date</string>
<string name="any">Any</string>
<string name="today">Today</string>
<string name="last_7_days">Last 7 days</string>
<string name="last_30_days">Last 30 days</string>
<string name="last_365_days">Last 365 days</string>
<string name="sepia_element_duration">Duration</string>
<string name="duration_short"><![CDATA[Short (<4 min)]]></string>
<string name="duration_medium"><![CDATA[Medium (410 min)]]></string>
<string name="duration_long"><![CDATA[Long (> 10 min)]]></string>
<string name="display_all_categories">Display all categories</string>
<string name="display_all_licenses">Display all licenses</string>
<string name="display_all_languages">Display all languages</string>
<string name="all_of_these_tags">All of these tags</string>
<string name="one_of_these_tags">One of these tags</string>
<string name="apply_filter">Apply filter</string>
<string-array name="sort_by_array">
<item>Best match</item>
<item>Most recent</item>
<item>Least recent</item>
</string-array>
<string name="sort_by">Sort by</string>
<string name="sepia_search_hint">Keyword, channel, video, etc.</string>
<string name="sepia_indication">Sepia Search displays videos and channels that match your search but is not the publisher, nor the owner. If you notice any problems with a video, report it to the administrators on the PeerTube website where the video is published.</string>
<string name="my_videos">My videos</string> <string name="my_videos">My videos</string>
<string name="title">Title</string> <string name="title">Title</string>
<string name="license">License</string> <string name="license">License</string>
@ -116,6 +151,8 @@
<string name="pickup_captions">Pick captions</string> <string name="pickup_captions">Pick captions</string>
<string name="none">None</string> <string name="none">None</string>
<string name="set_video_mode_description">Allows to change mode for playing videos (default, streaming or via a browser).</string> <string name="set_video_mode_description">Allows to change mode for playing videos (default, streaming or via a browser).</string>
<string name="delete_account_comment">Delete account comments</string>
<string name="delete_account_comment_confirm">Are you sure you want to remove all the comments of this account?</string>
<string name="delete_video">Delete video</string> <string name="delete_video">Delete video</string>
<string name="delete_video_confirmation">Are you sure to delete this video?</string> <string name="delete_video_confirmation">Are you sure to delete this video?</string>
<string name="no_video_to_display">No videos to display!</string> <string name="no_video_to_display">No videos to display!</string>
@ -129,6 +166,7 @@
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> published a new video: <b>%2$s</b>]]></string> <string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> published a new video: <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[Your video <b>%1$s</b> has been blacklisted]]></string> <string name="peertube_video_blacklist"><![CDATA[Your video <b>%1$s</b> has been blacklisted]]></string>
<string name="peertube_video_unblacklist"><![CDATA[Your video <b>%1$s</b> has been unblacklisted]]></string> <string name="peertube_video_unblacklist"><![CDATA[Your video <b>%1$s</b> has been unblacklisted]]></string>
<string name="peertube_video_report_success"><![CDATA[ Your abuse <b>%1$s</b> has been accepted]]></string>
<string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string> <string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string>
<string name="add_public_comment">Add a public comment</string> <string name="add_public_comment">Add a public comment</string>
<string name="send_comment">Send comment</string> <string name="send_comment">Send comment</string>
@ -166,6 +204,11 @@
<item>Webview</item> <item>Webview</item>
<item>Direct stream</item> <item>Direct stream</item>
</string-array> </string-array>
<string-array name="settings_theme">
<item>Light</item>
<item>Dark</item>
<item>Automatic</item>
</string-array>
<string-array name="settings_video_quality"> <string-array name="settings_video_quality">
<item>High</item> <item>High</item>
<item>Medium</item> <item>Medium</item>

View File

@ -1,5 +1,13 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="add_public_reply">Add a public reply</string>
<plurals name="number_of_replies">
<item quantity="other">%d replies</item>
</plurals>
<string name="reply">Reply</string>
<string name="set_theme">Theme</string>
<string name="set_theme_description">Allow to change app theme</string>
<string name="federation_issue">The video cannot be federated!</string>
<string name="title_home">Home</string> <string name="title_home">Home</string>
<string name="title_local">Local</string> <string name="title_local">Local</string>
<string name="title_discover">Discover</string> <string name="title_discover">Discover</string>
@ -83,6 +91,33 @@
<string name="delete_comment">Delete a comment</string> <string name="delete_comment">Delete a comment</string>
<string name="delete_comment_confirm">Are you sure to delete this comment?</string> <string name="delete_comment_confirm">Are you sure to delete this comment?</string>
<string name="set_video_mode">Mode for videos</string> <string name="set_video_mode">Mode for videos</string>
<string name="filter">Filter</string>
<string name="sepia_search">Sepia search</string>
<string name="sepia_element_nsfw">Display sensitive content</string>
<string name="sepia_element_published_date">Published date</string>
<string name="any">Any</string>
<string name="today">Today</string>
<string name="last_7_days">Last 7 days</string>
<string name="last_30_days">Last 30 days</string>
<string name="last_365_days">Last 365 days</string>
<string name="sepia_element_duration">Duration</string>
<string name="duration_short"><![CDATA[Short (<4 min)]]></string>
<string name="duration_medium"><![CDATA[Medium (410 min)]]></string>
<string name="duration_long"><![CDATA[Long (> 10 min)]]></string>
<string name="display_all_categories">Display all categories</string>
<string name="display_all_licenses">Display all licenses</string>
<string name="display_all_languages">Display all languages</string>
<string name="all_of_these_tags">All of these tags</string>
<string name="one_of_these_tags">One of these tags</string>
<string name="apply_filter">Apply filter</string>
<string-array name="sort_by_array">
<item>Best match</item>
<item>Most recent</item>
<item>Least recent</item>
</string-array>
<string name="sort_by">Sort by</string>
<string name="sepia_search_hint">Keyword, channel, video, etc.</string>
<string name="sepia_indication">Sepia Search displays videos and channels that match your search but is not the publisher, nor the owner. If you notice any problems with a video, report it to the administrators on the PeerTube website where the video is published.</string>
<string name="my_videos">My videos</string> <string name="my_videos">My videos</string>
<string name="title">Title</string> <string name="title">Title</string>
<string name="license">License</string> <string name="license">License</string>
@ -116,6 +151,8 @@
<string name="pickup_captions">Pick captions</string> <string name="pickup_captions">Pick captions</string>
<string name="none">None</string> <string name="none">None</string>
<string name="set_video_mode_description">Allows to change mode for playing videos (default, streaming or via a browser).</string> <string name="set_video_mode_description">Allows to change mode for playing videos (default, streaming or via a browser).</string>
<string name="delete_account_comment">Delete account comments</string>
<string name="delete_account_comment_confirm">Are you sure you want to remove all the comments of this account?</string>
<string name="delete_video">Delete video</string> <string name="delete_video">Delete video</string>
<string name="delete_video_confirmation">Are you sure to delete this video?</string> <string name="delete_video_confirmation">Are you sure to delete this video?</string>
<string name="no_video_to_display">No videos to display!</string> <string name="no_video_to_display">No videos to display!</string>
@ -129,6 +166,7 @@
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> published a new video: <b>%2$s</b>]]></string> <string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> published a new video: <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[Your video <b>%1$s</b> has been blacklisted]]></string> <string name="peertube_video_blacklist"><![CDATA[Your video <b>%1$s</b> has been blacklisted]]></string>
<string name="peertube_video_unblacklist"><![CDATA[Your video <b>%1$s</b> has been unblacklisted]]></string> <string name="peertube_video_unblacklist"><![CDATA[Your video <b>%1$s</b> has been unblacklisted]]></string>
<string name="peertube_video_report_success"><![CDATA[ Your abuse <b>%1$s</b> has been accepted]]></string>
<string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string> <string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string>
<string name="add_public_comment">Add a public comment</string> <string name="add_public_comment">Add a public comment</string>
<string name="send_comment">Send comment</string> <string name="send_comment">Send comment</string>
@ -166,6 +204,11 @@
<item>Webview</item> <item>Webview</item>
<item>Direct stream</item> <item>Direct stream</item>
</string-array> </string-array>
<string-array name="settings_theme">
<item>Light</item>
<item>Dark</item>
<item>Automatic</item>
</string-array>
<string-array name="settings_video_quality"> <string-array name="settings_video_quality">
<item>High</item> <item>High</item>
<item>Medium</item> <item>Medium</item>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#212529</color>
<color name="colorPrimaryDark">#000000</color>
<color name="colorAccent">#F2690D</color>
<color name="tag_color">#bbF2690D</color>
<color name="tag_color_text">#FAFAFA</color>
<color name="positive_thumbs">#2b90d9</color>
<color name="negative_thumbs">#F44336</color>
<color name="red_1">#F44336</color>
</resources>

View File

@ -1,5 +1,22 @@
<resources xmlns:tools="http://schemas.android.com/tools"> <resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name" translatable="false">Tubelab</string> <string name="app_name" translatable="false">Tubelab</string>
<string name="set_video_mode_choice" translatable="false">set_video_mode_choice</string>
<string name="set_video_minimize_choice" translatable="false">set_video_minimize_choice</string>
<string name="set_video_language_choice" translatable="false">set_video_language_choice</string>
<string name="set_video_quality_choice" translatable="false">set_video_quality_choice</string>
<string name="set_video_cache_choice" translatable="false">set_video_cache_choice</string>
<string name="set_theme_choice" translatable="false">set_theme_choice</string>
<string name="add_public_reply">Add a public reply</string>
<plurals name="number_of_replies">
<item quantity="one">%d reply</item>
<item quantity="other">%d replies</item>
</plurals>
<string name="reply">Reply</string>
<string name="set_theme">Theme</string>
<string name="set_theme_description">Allow to change app theme</string>
<string name="federation_issue">The video cannot be federated!</string>
<string name="title_home">Home</string> <string name="title_home">Home</string>
<string name="title_local">Local</string> <string name="title_local">Local</string>
<string name="title_discover">Discover</string> <string name="title_discover">Discover</string>
@ -110,6 +127,37 @@
<string name="delete_comment_confirm">Are you sure to delete this comment?</string> <string name="delete_comment_confirm">Are you sure to delete this comment?</string>
<string name="set_video_mode">Mode for videos</string> <string name="set_video_mode">Mode for videos</string>
<string name="filter">Filter</string>
<string name="sepia_search">Sepia search</string>
<string name="sepia_element_nsfw">Display sensitive content</string>
<string name="sepia_element_published_date">Published date</string>
<string name="any">Any</string>
<string name="today">Today</string>
<string name="last_7_days">Last 7 days</string>
<string name="last_30_days">Last 30 days</string>
<string name="last_365_days">Last 365 days</string>
<string name="sepia_element_duration">Duration</string>
<string name="duration_short"><![CDATA[Short (<4 min)]]></string>
<string name="duration_medium"><![CDATA[Medium (410 min)]]></string>
<string name="duration_long"><![CDATA[Long (> 10 min)]]></string>
<string name="display_all_categories">Display all categories</string>
<string name="display_all_licenses">Display all licenses</string>
<string name="display_all_languages">Display all languages</string>
<string name="all_of_these_tags">All of these tags</string>
<string name="one_of_these_tags">One of these tags</string>
<string name="apply_filter">Apply filter</string>
<string-array name="sort_by_array">
<item>Best match</item>
<item>Most recent</item>
<item>Least recent</item>
</string-array>
<string name="sort_by">Sort by</string>
<string name="sepia_search_hint">Keyword, channel, video, etc.</string>
<string name="sepia_indication">Sepia Search displays videos and channels that match your search but is not the publisher, nor the owner. If you notice any problems with a video, report it to the administrators on the PeerTube website where the video is published.</string>
<string name="my_videos">My videos</string> <string name="my_videos">My videos</string>
<string name="title">Title</string> <string name="title">Title</string>
<string name="license">License</string> <string name="license">License</string>
@ -139,11 +187,7 @@
<string name="video_settings">Video settings</string> <string name="video_settings">Video settings</string>
<string name="app_interface">Interface</string> <string name="app_interface">Interface</string>
<string name="set_video_mode_choice" translatable="false">set_video_mode_choice</string>
<string name="set_video_minimize_choice" translatable="false">set_video_minimize_choice</string>
<string name="set_video_language_choice" translatable="false">set_video_language_choice</string>
<string name="set_video_quality_choice" translatable="false">set_video_quality_choice</string>
<string name="set_video_cache_choice" translatable="false">set_video_cache_choice</string>
<string name="set_cache_mode">Cache</string> <string name="set_cache_mode">Cache</string>
<string name="set_video_cache_description">Set the cache for videos (default 100Mb)</string> <string name="set_video_cache_description">Set the cache for videos (default 100Mb)</string>
<string name="set_video_quality_description">Define a default quality for videos</string> <string name="set_video_quality_description">Define a default quality for videos</string>
@ -155,6 +199,8 @@
<string name="none">None</string> <string name="none">None</string>
<string name="set_video_mode_description">Allows to change mode for playing videos (default, streaming or via a browser).</string> <string name="set_video_mode_description">Allows to change mode for playing videos (default, streaming or via a browser).</string>
<string name="delete_account_comment">Delete account comments</string>
<string name="delete_account_comment_confirm">Are you sure you want to remove all the comments of this account?</string>
<string name="delete_video">Delete video</string> <string name="delete_video">Delete video</string>
<string name="delete_video_confirmation">Are you sure to delete this video?</string> <string name="delete_video_confirmation">Are you sure to delete this video?</string>
@ -170,6 +216,7 @@
<string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> published a new video: <b>%2$s</b>]]></string> <string name="peertube_video_from_subscription"><![CDATA[<b>%1$s</b> published a new video: <b>%2$s</b>]]></string>
<string name="peertube_video_blacklist"><![CDATA[Your video <b>%1$s</b> has been blacklisted]]></string> <string name="peertube_video_blacklist"><![CDATA[Your video <b>%1$s</b> has been blacklisted]]></string>
<string name="peertube_video_unblacklist"><![CDATA[Your video <b>%1$s</b> has been unblacklisted]]></string> <string name="peertube_video_unblacklist"><![CDATA[Your video <b>%1$s</b> has been unblacklisted]]></string>
<string name="peertube_video_report_success"><![CDATA[ Your abuse <b>%1$s</b> has been accepted]]></string>
<string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string> <string name="peertube_video_abuse"><![CDATA[New abuse report for video: <b>%1$s</b>]]></string>
<string name="add_public_comment">Add a public comment</string> <string name="add_public_comment">Add a public comment</string>
<string name="send_comment">Send comment</string> <string name="send_comment">Send comment</string>
@ -211,6 +258,14 @@
<item>Direct stream</item> <item>Direct stream</item>
</string-array> </string-array>
<string-array name="settings_theme">
<item>Light</item>
<item>Dark</item>
<item>Automatic</item>
</string-array>
<string-array name="settings_video_quality"> <string-array name="settings_video_quality">
<item>High</item> <item>High</item>
<item>Medium</item> <item>Medium</item>

View File

@ -1,21 +0,0 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary_full</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark_full</item>
<item name="colorAccent">@color/colorAccent_full</item>
</style>
<style name="AppThemeNoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary_full</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark_full</item>
<item name="colorAccent">@color/colorAccent_full</item>
</style>
<style name="progress" parent="SpinKitView.Circle" />
<style name="progressBottom" parent="SpinKitView.ThreeBounce" />
</resources>

View File

@ -58,6 +58,11 @@
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
android:label="@string/app_name" android:label="@string/app_name"
android:windowSoftInputMode="stateAlwaysHidden" /> android:windowSoftInputMode="stateAlwaysHidden" />
<activity
android:name=".ShowAccountActivity"
android:configChanges="orientation|screenSize"
android:label="@string/app_name"
android:windowSoftInputMode="stateAlwaysHidden" />
<activity <activity
android:name=".AccountActivity" android:name=".AccountActivity"
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
@ -90,6 +95,11 @@
android:configChanges="orientation|screenSize" android:configChanges="orientation|screenSize"
android:label="@string/app_name" android:label="@string/app_name"
android:windowSoftInputMode="stateAlwaysHidden" /> android:windowSoftInputMode="stateAlwaysHidden" />
<activity
android:name=".SepiaSearchActivity"
android:configChanges="orientation|screenSize"
android:label="@string/sepia_search"
android:windowSoftInputMode="stateAlwaysHidden" />
<activity <activity
android:name=".WebviewActivity" android:name=".WebviewActivity"
android:configChanges="keyboardHidden|orientation|screenSize" android:configChanges="keyboardHidden|orientation|screenSize"

File diff suppressed because it is too large Load Diff

View File

@ -15,12 +15,16 @@ package app.fedilab.fedilabtube;
* see <http://www.gnu.org/licenses>. */ * see <http://www.gnu.org/licenses>. */
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import androidx.multidex.MultiDex; import androidx.multidex.MultiDex;
import androidx.multidex.MultiDexApplication; import androidx.multidex.MultiDexApplication;
import net.gotev.uploadservice.UploadService; import net.gotev.uploadservice.UploadService;
import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.helper.ThemeHelper;
public class FedilabTube extends MultiDexApplication { public class FedilabTube extends MultiDexApplication {
@Override @Override
protected void attachBaseContext(Context base) { protected void attachBaseContext(Context base) {
@ -29,7 +33,12 @@ public class FedilabTube extends MultiDexApplication {
MultiDex.install(FedilabTube.this); MultiDex.install(FedilabTube.this);
UploadService.NAMESPACE = BuildConfig.APPLICATION_ID; UploadService.NAMESPACE = BuildConfig.APPLICATION_ID;
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
int themePref = sharedpreferences.getInt(Helper.SET_THEME, Helper.DEFAULT_MODE);
ThemeHelper.switchTo(themePref);
} }
} }

View File

@ -117,7 +117,6 @@ public class InstancePickerActivity extends AppCompatActivity {
pickup_languages.setOnClickListener(v -> { pickup_languages.setOnClickListener(v -> {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(InstancePickerActivity.this); AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(InstancePickerActivity.this);
int i = 0; int i = 0;
if (languages.size() > 0) { if (languages.size() > 0) {
Iterator<Map.Entry<String, String>> it = languages.entrySet().iterator(); Iterator<Map.Entry<String, String>> it = languages.entrySet().iterator();
@ -175,7 +174,7 @@ public class InstancePickerActivity extends AppCompatActivity {
}); });
} }
if (peertubeInformation != null && peertubeInformation.getLanguages() != null) { if (peertubeInformation != null && peertubeInformation.getCategories() != null) {
LinkedHashMap<Integer, String> categories = new LinkedHashMap<>(peertubeInformation.getCategories()); LinkedHashMap<Integer, String> categories = new LinkedHashMap<>(peertubeInformation.getCategories());
checkedItemsCategory = new boolean[categories.size()]; checkedItemsCategory = new boolean[categories.size()];
itemsLabelCategory = new String[categories.size()]; itemsLabelCategory = new String[categories.size()];

View File

@ -134,6 +134,7 @@ public class LoginActivity extends AppCompatActivity {
String[] emailArray = login_uid.getText().toString().split("@"); String[] emailArray = login_uid.getText().toString().split("@");
if (emailArray.length > 1 && !Arrays.asList(Helper.valideEmails).contains(emailArray[1])) { if (emailArray.length > 1 && !Arrays.asList(Helper.valideEmails).contains(emailArray[1])) {
Toasty.error(LoginActivity.this, getString(R.string.email_error_domain, emailArray[1])).show(); Toasty.error(LoginActivity.this, getString(R.string.email_error_domain, emailArray[1])).show();
connectionButton.setEnabled(true);
return; return;
} }
host = emailArray[1]; host = emailArray[1];
@ -141,6 +142,7 @@ public class LoginActivity extends AppCompatActivity {
} else { } else {
if (login_instance == null || login_instance.getText() == null || login_instance.getText().toString().trim().length() == 0) { if (login_instance == null || login_instance.getText() == null || login_instance.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();
connectionButton.setEnabled(true);
return; return;
} }
instance = host = login_instance.getText().toString().trim().toLowerCase(); instance = host = login_instance.getText().toString().trim().toLowerCase();
@ -215,6 +217,7 @@ public class LoginActivity extends AppCompatActivity {
} catch (Error error) { } catch (Error error) {
Error.displayError(LoginActivity.this, error); Error.displayError(LoginActivity.this, error);
error.printStackTrace(); error.printStackTrace();
runOnUiThread(() -> connectionButton.setEnabled(true));
} }
} }
}).start(); }).start();

View File

@ -22,6 +22,7 @@ import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.widget.EditText; import android.widget.EditText;
@ -36,6 +37,7 @@ import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.kobakei.ratethisapp.RateThisApp;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -71,31 +73,27 @@ public class MainActivity extends AppCompatActivity {
Fragment active; Fragment active;
private DisplayVideosFragment recentFragment, locaFragment, trendingFragment, subscriptionFragment, mostLikedFragment; private DisplayVideosFragment recentFragment, locaFragment, trendingFragment, subscriptionFragment, mostLikedFragment;
private DisplayOverviewFragment overviewFragment; private DisplayOverviewFragment overviewFragment;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
private final BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= item -> { = item -> {
DisplayVideosFragment displayVideosFragment = null; DisplayVideosFragment displayVideosFragment = null;
switch (item.getItemId()) { int itemId = item.getItemId();
case R.id.navigation_subscription: if (itemId == R.id.navigation_subscription) {
displayVideosFragment = subscriptionFragment; displayVideosFragment = subscriptionFragment;
setTitle(R.string.subscriptions); setTitle(R.string.subscriptions);
break; } else if (itemId == R.id.navigation_trending) {
case R.id.navigation_trending:
setTitle(R.string.title_trending); setTitle(R.string.title_trending);
displayVideosFragment = trendingFragment; displayVideosFragment = trendingFragment;
break; } else if (itemId == R.id.navigation_most_liked) {
case R.id.navigation_most_liked:
setTitle(R.string.title_most_liked); setTitle(R.string.title_most_liked);
displayVideosFragment = mostLikedFragment; displayVideosFragment = mostLikedFragment;
break; } else if (itemId == R.id.navigation_recently_added) {
case R.id.navigation_recently_added:
setTitle(R.string.title_recently_added); setTitle(R.string.title_recently_added);
displayVideosFragment = recentFragment; displayVideosFragment = recentFragment;
break; } else if (itemId == R.id.navigation_local) {
case R.id.navigation_local:
setTitle(R.string.title_local); setTitle(R.string.title_local);
displayVideosFragment = locaFragment; displayVideosFragment = locaFragment;
break; } else if (itemId == R.id.navigation_discover) {
case R.id.navigation_discover:
setTitle(R.string.title_discover); setTitle(R.string.title_discover);
fm.beginTransaction().hide(active).show(overviewFragment).commit(); fm.beginTransaction().hide(active).show(overviewFragment).commit();
active = overviewFragment; active = overviewFragment;
@ -122,6 +120,22 @@ public class MainActivity extends AppCompatActivity {
navView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener); navView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
Fragment fragment = getSupportFragmentManager().findFragmentByTag("5");
if(fragment != null)
getSupportFragmentManager().beginTransaction().remove(fragment).commit();
fragment = getSupportFragmentManager().findFragmentByTag("4");
if(fragment != null)
getSupportFragmentManager().beginTransaction().remove(fragment).commit();
fragment = getSupportFragmentManager().findFragmentByTag("3");
if(fragment != null)
getSupportFragmentManager().beginTransaction().remove(fragment).commit();
fragment = getSupportFragmentManager().findFragmentByTag("2");
if(fragment != null)
getSupportFragmentManager().beginTransaction().remove(fragment).commit();
fragment = getSupportFragmentManager().findFragmentByTag("1");
if(fragment != null)
getSupportFragmentManager().beginTransaction().remove(fragment).commit();
recentFragment = new DisplayVideosFragment(); recentFragment = new DisplayVideosFragment();
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putSerializable(Helper.TIMELINE_TYPE, TimelineVM.TimelineType.RECENT); bundle.putSerializable(Helper.TIMELINE_TYPE, TimelineVM.TimelineType.RECENT);
@ -149,7 +163,9 @@ public class MainActivity extends AppCompatActivity {
overviewFragment = new DisplayOverviewFragment(); overviewFragment = new DisplayOverviewFragment();
if( active == null) {
active = overviewFragment; active = overviewFragment;
}
fm.beginTransaction().add(R.id.nav_host_fragment, locaFragment, "5").hide(locaFragment).commit(); fm.beginTransaction().add(R.id.nav_host_fragment, locaFragment, "5").hide(locaFragment).commit();
if (!Helper.isLoggedIn(MainActivity.this)) { if (!Helper.isLoggedIn(MainActivity.this)) {
@ -158,7 +174,6 @@ public class MainActivity extends AppCompatActivity {
fm.beginTransaction().add(R.id.nav_host_fragment, trendingFragment, "2").hide(trendingFragment).commit(); fm.beginTransaction().add(R.id.nav_host_fragment, trendingFragment, "2").hide(trendingFragment).commit();
fm.beginTransaction().add(R.id.nav_host_fragment, overviewFragment, "1").commit(); fm.beginTransaction().add(R.id.nav_host_fragment, overviewFragment, "1").commit();
} }
toolbar.setOnClickListener(v->{ toolbar.setOnClickListener(v->{
if(active instanceof DisplayVideosFragment) { if(active instanceof DisplayVideosFragment) {
((DisplayVideosFragment) active).scrollToTop(); ((DisplayVideosFragment) active).scrollToTop();
@ -191,12 +206,15 @@ public class MainActivity extends AppCompatActivity {
runOnUiThread(() -> Helper.logoutCurrentUser(MainActivity.this, account)); runOnUiThread(() -> Helper.logoutCurrentUser(MainActivity.this, account));
return; return;
} }
runOnUiThread(() -> { runOnUiThread(() -> {
//To avoid a token issue with subscriptions, adding fragment is done when the token is refreshed. //To avoid a token issue with subscriptions, adding fragment is done when the token is refreshed.
fm.beginTransaction().add(R.id.nav_host_fragment, recentFragment, "4").hide(recentFragment).commit(); new Handler().post(() -> {
fm.beginTransaction().add(R.id.nav_host_fragment, trendingFragment, "3").hide(trendingFragment).commit(); fm.beginTransaction().add(R.id.nav_host_fragment, recentFragment, "4").hide(recentFragment).commitAllowingStateLoss();
fm.beginTransaction().add(R.id.nav_host_fragment, subscriptionFragment, "2").hide(subscriptionFragment).commit(); fm.beginTransaction().add(R.id.nav_host_fragment, trendingFragment, "3").hide(trendingFragment).commitAllowingStateLoss();
fm.beginTransaction().add(R.id.nav_host_fragment, overviewFragment, "1").commit(); fm.beginTransaction().add(R.id.nav_host_fragment, subscriptionFragment, "2").hide(subscriptionFragment).commitAllowingStateLoss();
fm.beginTransaction().add(R.id.nav_host_fragment, overviewFragment, "1").commitAllowingStateLoss();
});
}); });
UserMe userMe = new RetrofitPeertubeAPI(MainActivity.this, instance, token.getAccess_token()).verifyCredentials(); UserMe userMe = new RetrofitPeertubeAPI(MainActivity.this, instance, token.getAccess_token()).verifyCredentials();
@ -207,6 +225,7 @@ public class MainActivity extends AppCompatActivity {
editor.putString(Helper.PREF_KEY_NAME, account.getUsername()); editor.putString(Helper.PREF_KEY_NAME, account.getUsername());
//Sync languages from server //Sync languages from server
List<String> videoLanguageServer = userMe.getVideoLanguages(); List<String> videoLanguageServer = userMe.getVideoLanguages();
if( videoLanguageServer != null) {
Set<String> videoLanguageServerSet = new TreeSet<>(videoLanguageServer); Set<String> videoLanguageServerSet = new TreeSet<>(videoLanguageServer);
videoLanguageServerSet.addAll(videoLanguageServer); videoLanguageServerSet.addAll(videoLanguageServer);
Set<String> videoLanguageLocal = sharedpreferences.getStringSet(getString(R.string.set_video_language_choice), null); Set<String> videoLanguageLocal = sharedpreferences.getStringSet(getString(R.string.set_video_language_choice), null);
@ -216,6 +235,7 @@ public class MainActivity extends AppCompatActivity {
editor.putStringSet(getString(R.string.set_video_language_choice), videoLanguageServerSet); editor.putStringSet(getString(R.string.set_video_language_choice), videoLanguageServerSet);
editor.apply(); editor.apply();
} }
}
} catch (Error error) { } catch (Error error) {
error.printStackTrace(); error.printStackTrace();
} }
@ -227,6 +247,11 @@ public class MainActivity extends AppCompatActivity {
} }
startInForeground(); startInForeground();
if(BuildConfig.google_restriction && BuildConfig.full_instances) {
RateThisApp.onCreate(this);
RateThisApp.showRateDialogIfNeeded(this);
}
} }
private void startInForeground() { private void startInForeground() {
@ -272,6 +297,7 @@ public class MainActivity extends AppCompatActivity {
MenuItem historyItem = menu.findItem(R.id.action_history); MenuItem historyItem = menu.findItem(R.id.action_history);
MenuItem mostLikedItem = menu.findItem(R.id.action_most_liked); MenuItem mostLikedItem = menu.findItem(R.id.action_most_liked);
MenuItem settingsItem = menu.findItem(R.id.action_settings); MenuItem settingsItem = menu.findItem(R.id.action_settings);
MenuItem sepiaSearchItem = menu.findItem(R.id.action_sepia_search);
if (Helper.isLoggedIn(MainActivity.this)) { if (Helper.isLoggedIn(MainActivity.this)) {
instanceItem.setVisible(false); instanceItem.setVisible(false);
uploadItem.setVisible(true); uploadItem.setVisible(true);
@ -289,6 +315,9 @@ public class MainActivity extends AppCompatActivity {
settingsItem.setVisible(true); settingsItem.setVisible(true);
mostLikedItem.setVisible(false); mostLikedItem.setVisible(false);
} }
if( !BuildConfig.full_instances) {
sepiaSearchItem.setVisible(false);
}
return true; return true;
} }
@ -343,6 +372,10 @@ public class MainActivity extends AppCompatActivity {
Intent intent = new Intent(MainActivity.this, AllPlaylistsActivity.class); Intent intent = new Intent(MainActivity.this, AllPlaylistsActivity.class);
startActivity(intent); startActivity(intent);
return true; return true;
}else if(item.getItemId() == R.id.action_sepia_search) {
Intent intent = new Intent(MainActivity.this, SepiaSearchActivity.class);
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);
@ -351,6 +384,14 @@ public class MainActivity extends AppCompatActivity {
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
public void setActive(DisplayVideosFragment displayVideosFragment){
this.active = displayVideosFragment;
}
public void setSubscriptionFragment(DisplayVideosFragment displayVideosFragment) {
this.subscriptionFragment = displayVideosFragment;
}
@Override @Override
protected void onNewIntent(Intent intent) { protected void onNewIntent(Intent intent) {
super.onNewIntent(intent); super.onNewIntent(intent);

View File

@ -224,7 +224,7 @@ public class PeertubeEditUploadActivity extends AppCompatActivity {
TimelineVM feedsViewModel = new ViewModelProvider(PeertubeEditUploadActivity.this).get(TimelineVM.class); TimelineVM feedsViewModel = new ViewModelProvider(PeertubeEditUploadActivity.this).get(TimelineVM.class);
feedsViewModel.getMyVideo(videoId).observe(PeertubeEditUploadActivity.this, this::manageVIewVideo); feedsViewModel.getMyVideo(null, videoId).observe(PeertubeEditUploadActivity.this, this::manageVIewVideo);
channels = new LinkedHashMap<>(); channels = new LinkedHashMap<>();
setTitle(R.string.edit_video); setTitle(R.string.edit_video);

View File

@ -145,10 +145,12 @@ public class PeertubeRegisterActivity extends AppCompatActivity {
return; return;
} }
String[] emailArray = email.getText().toString().split("@"); String[] emailArray = email.getText().toString().split("@");
if (!BuildConfig.full_instances) {
if (emailArray.length > 1 && !Arrays.asList(Helper.valideEmails).contains(emailArray[1])) { if (emailArray.length > 1 && !Arrays.asList(Helper.valideEmails).contains(emailArray[1])) {
Toasty.error(PeertubeRegisterActivity.this, getString(R.string.email_error_domain, emailArray[1])).show(); Toasty.error(PeertubeRegisterActivity.this, getString(R.string.email_error_domain, emailArray[1])).show();
return; return;
} }
}
if (password.getText().toString().trim().length() < 8) { if (password.getText().toString().trim().length() < 8) {
Toasty.error(PeertubeRegisterActivity.this, getString(R.string.password_too_short)).show(); Toasty.error(PeertubeRegisterActivity.this, getString(R.string.password_too_short)).show();

View File

@ -0,0 +1,399 @@
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;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.RadioGroup;
import android.widget.Spinner;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import com.mancj.materialsearchbar.MaterialSearchBar;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import app.fedilab.fedilabtube.client.entities.SepiaSearch;
import app.fedilab.fedilabtube.fragment.DisplaySepiaSearchFragment;
import app.fedilab.fedilabtube.helper.Helper;
import mabbas007.tagsedittext.TagsEditText;
import static app.fedilab.fedilabtube.MainActivity.peertubeInformation;
import static app.fedilab.fedilabtube.PeertubeActivity.hideKeyboard;
public class SepiaSearchActivity extends AppCompatActivity {
private SepiaSearch sepiaSearchVideo, sepiaSearchChannel;
private TagsEditText sepia_element_all_of_tags, sepia_element_one_of_tags;
private MaterialSearchBar searchBar;
private ConstraintLayout filter_elements;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sepia_search);
sepiaSearchVideo = new SepiaSearch();
sepiaSearchChannel = new SepiaSearch();
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
sepiaSearchVideo.setCount(String.valueOf(sharedpreferences.getInt(Helper.SET_VIDEOS_PER_PAGE, Helper.VIDEOS_PER_PAGE)));
sepiaSearchVideo.setDurationMin(0);
sepiaSearchVideo.setDurationMax(9999999);
sepiaSearchVideo.setStart("0");
sepiaSearchVideo.setSort("-match");
if (getSupportActionBar() != null)
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Button filter = findViewById(R.id.filter);
filter_elements = findViewById(R.id.filter_elements);
filter.setOnClickListener(view -> {
if( filter_elements.getVisibility() == View.VISIBLE) {
filter_elements.setVisibility(View.GONE);
}else{
filter_elements.setVisibility(View.VISIBLE);
}
});
RadioGroup sepia_element_nsfw = findViewById(R.id.sepia_element_nsfw);
sepia_element_nsfw.setOnCheckedChangeListener((group, checkedId) -> sepiaSearchVideo.setNsfw(checkedId != R.id.sepia_element_nsfw_no));
RadioGroup radio_date = findViewById(R.id.radio_date);
radio_date.setOnCheckedChangeListener((group, checkedId) -> {
if (checkedId == R.id.sepia_element_published_date_today) {
Calendar cal = GregorianCalendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
sepiaSearchVideo.setStartDate(cal.getTime());
} else if (checkedId == R.id.sepia_element_published_date_last_7_days) {
Calendar cal;
cal = GregorianCalendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.DAY_OF_YEAR, -7);
sepiaSearchVideo.setStartDate(cal.getTime());
} else if (checkedId == R.id.sepia_element_published_date_last_30_days) {
Calendar cal;
cal = GregorianCalendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.DAY_OF_YEAR, -30);
sepiaSearchVideo.setStartDate(cal.getTime());
} else if (checkedId == R.id.sepia_element_published_date_last_365_days) {
Calendar cal;
cal = GregorianCalendar.getInstance();
cal.setTime(new Date());
cal.add(Calendar.DAY_OF_YEAR, -365);
sepiaSearchVideo.setStartDate(cal.getTime());
} else {
sepiaSearchVideo.setStartDate(null);
}
});
RadioGroup duration = findViewById(R.id.duration);
duration.setOnCheckedChangeListener((group, checkedId) -> {
if (checkedId == R.id.sepia_element_duration_short) {
sepiaSearchVideo.setDurationMin(0);
sepiaSearchVideo.setDurationMax(240);
} else if (checkedId == R.id.sepia_element_duration_medium) {
sepiaSearchVideo.setDurationMin(240);
sepiaSearchVideo.setDurationMax(600);
} else if (checkedId == R.id.sepia_element_duration_long) {
sepiaSearchVideo.setDurationMin(600);
sepiaSearchVideo.setDurationMax(999999999);
} else {
sepiaSearchVideo.setDurationMin(0);
sepiaSearchVideo.setDurationMax(999999999);
}
});
Spinner sort_by = findViewById(R.id.sort_by);
ArrayAdapter<String> adapterSortBy = new ArrayAdapter<>(SepiaSearchActivity.this,
android.R.layout.simple_spinner_dropdown_item, getResources().getStringArray(R.array.sort_by_array));
sort_by.setAdapter(adapterSortBy);
sort_by.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String orderby, channelOrderBy;
switch (position){
case 1:
orderby = "-publishedAt";
channelOrderBy = "-createdAt";
break;
case 2:
orderby = "publishedAt";
channelOrderBy = "createdAt";
break;
default:
orderby = "-match";
channelOrderBy = null;
}
sepiaSearchVideo.setSort(orderby);
sepiaSearchChannel.setSort(channelOrderBy);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
Spinner sepia_element_category = findViewById(R.id.sepia_element_category);
Spinner sepia_element_license = findViewById(R.id.sepia_element_license);
Spinner sepia_element_language = findViewById(R.id.sepia_element_language);
sepia_element_all_of_tags = findViewById(R.id.sepia_element_all_of_tags);
sepia_element_one_of_tags = findViewById(R.id.sepia_element_one_of_tags);
LinkedHashMap<Integer, String> categories = new LinkedHashMap<>(peertubeInformation.getCategories());
LinkedHashMap<Integer, String> licences = new LinkedHashMap<>(peertubeInformation.getLicences());
LinkedHashMap<String, String> languages = new LinkedHashMap<>(peertubeInformation.getLanguages());
LinkedHashMap<String, String> translations = new LinkedHashMap<>(peertubeInformation.getTranslations());
//Populate catgories
String[] categoriesA = new String[categories.size()+1];
categoriesA[0] = getString(R.string.display_all_categories);
Iterator<Map.Entry<Integer, String>> it = categories.entrySet().iterator();
int i = 1;
while (it.hasNext()) {
Map.Entry<Integer, String> pair = it.next();
if (translations.size() == 0 || !translations.containsKey(pair.getValue()))
categoriesA[i] = pair.getValue();
else
categoriesA[i] = translations.get(pair.getValue());
it.remove();
i++;
}
ArrayAdapter<String> adapterCatgories = new ArrayAdapter<>(SepiaSearchActivity.this,
android.R.layout.simple_spinner_dropdown_item, categoriesA);
sepia_element_category.setAdapter(adapterCatgories);
//Populate licenses
String[] licensesA = new String[licences.size()+1];
licensesA[0] = getString(R.string.display_all_licenses);
it = licences.entrySet().iterator();
i = 1;
while (it.hasNext()) {
Map.Entry<Integer, String> pair = it.next();
if (translations.size() == 0 || !translations.containsKey(pair.getValue()))
licensesA[i] = pair.getValue();
else
licensesA[i] = translations.get(pair.getValue());
it.remove();
i++;
}
ArrayAdapter<String> adapterLicenses = new ArrayAdapter<>(SepiaSearchActivity.this,
android.R.layout.simple_spinner_dropdown_item, licensesA);
sepia_element_license.setAdapter(adapterLicenses);
//Populate languages
String[] languagesA = new String[languages.size()+1];
languagesA[0] = getString(R.string.display_all_languages);
Iterator<Map.Entry<String, String>> itl = languages.entrySet().iterator();
i = 1;
while (itl.hasNext()) {
Map.Entry<String, String> pair = itl.next();
if (translations.size() == 0 || !translations.containsKey(pair.getValue()))
languagesA[i] = pair.getValue();
else
languagesA[i] = translations.get(pair.getValue());
itl.remove();
i++;
}
ArrayAdapter<String> adapterLanguages = new ArrayAdapter<>(SepiaSearchActivity.this,
android.R.layout.simple_spinner_dropdown_item, languagesA);
sepia_element_language.setAdapter(adapterLanguages);
sepia_element_license.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
updateLicensePosition(position);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
//Manage categories
sepia_element_category.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
updateCategoryPosition(position);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
//Manage languages
sepia_element_language.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
updateLanguagesPosition(position);
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
searchBar = findViewById(R.id.searchBar);
searchBar.setOnSearchActionListener(new MaterialSearchBar.OnSearchActionListener() {
@Override
public void onSearchStateChanged(boolean enabled) {
}
@Override
public void onSearchConfirmed(CharSequence text) {
makeSearch();
}
@Override
public void onButtonClicked(int buttonCode) {
makeSearch();
}
});
Button apply_filter = findViewById(R.id.apply_filter);
apply_filter.setOnClickListener(v-> makeSearch());
searchBar.openSearch();
}
private void makeSearch(){
hideKeyboard(SepiaSearchActivity.this);
sepiaSearchVideo.setStart("0");
if( sepia_element_one_of_tags.getTags().size() > 0 ) {
sepiaSearchVideo.setTagsOneOf(sepia_element_one_of_tags.getTags());
}else{
sepiaSearchVideo.setTagsOneOf(null);
}
if( sepia_element_all_of_tags.getTags().size() > 0 ) {
sepiaSearchVideo.setTagsAllOf(sepia_element_all_of_tags.getTags());
}else{
sepiaSearchVideo.setTagsAllOf(null);
}
Fragment fragment = getSupportFragmentManager().findFragmentByTag("SEPIA_SEARCH");
if(fragment != null)
getSupportFragmentManager().beginTransaction().remove(fragment).commit();
filter_elements.setVisibility(View.GONE);
sepiaSearchVideo.setSearch(searchBar.getText());
DisplaySepiaSearchFragment displaySepiaSearchFragment = new DisplaySepiaSearchFragment();
Bundle bundle = new Bundle();
bundle.putParcelable("sepiaSearchVideo", sepiaSearchVideo);
displaySepiaSearchFragment.setArguments(bundle);
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(R.id.container, displaySepiaSearchFragment,"SEPIA_SEARCH").commit();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
private void updateLanguagesPosition(int position) {
LinkedHashMap<String, String> languagesCheck = new LinkedHashMap<>(peertubeInformation.getLanguages());
Iterator<Map.Entry<String, String>> it = languagesCheck.entrySet().iterator();
int i = 0;
while (it.hasNext()) {
Map.Entry<String, String> pair = it.next();
if (i == position && position > 0) {
List<String> languages = new ArrayList<>();
languages.add(pair.getKey());
sepiaSearchVideo.setBoostLanguages(languages);
break;
}else {
sepiaSearchVideo.setBoostLanguages(null);
}
it.remove();
i++;
}
}
private void updateCategoryPosition(int position) {
LinkedHashMap<Integer, String> categoriesCheck = new LinkedHashMap<>(peertubeInformation.getCategories());
Iterator<Map.Entry<Integer, String>> it = categoriesCheck.entrySet().iterator();
int i = 0;
while (it.hasNext()) {
Map.Entry<Integer, String> pair = it.next();
if (i == position && position > 0 ) {
List<Integer> categories = new ArrayList<>();
categories.add(pair.getKey());
sepiaSearchVideo.setCategoryOneOf(categories);
break;
}else {
sepiaSearchVideo.setCategoryOneOf(null);
}
it.remove();
i++;
}
}
private void updateLicensePosition(int position) {
LinkedHashMap<Integer, String> licensesCheck = new LinkedHashMap<>(peertubeInformation.getLicences());
Iterator<Map.Entry<Integer, String>> it = licensesCheck.entrySet().iterator();
int i = 0;
while (it.hasNext()) {
Map.Entry<Integer, String> pair = it.next();
if (i == position && position > 0) {
List<Integer> licenses = new ArrayList<>();
licenses.add(pair.getKey());
sepiaSearchVideo.setLicenceOneOf(licenses);
break;
}else {
sepiaSearchVideo.setLicenceOneOf(null);
}
it.remove();
i++;
}
}
}

View File

@ -14,9 +14,6 @@ package app.fedilab.fedilabtube;
* 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 android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.ColorStateList;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.Html; import android.text.Html;
@ -26,8 +23,6 @@ import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
@ -36,7 +31,6 @@ import android.widget.Toast;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter; import androidx.fragment.app.FragmentStatePagerAdapter;
@ -48,45 +42,34 @@ import com.google.android.material.tabs.TabLayout;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import app.fedilab.fedilabtube.client.APIResponse; import app.fedilab.fedilabtube.client.APIResponse;
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI; import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
import app.fedilab.fedilabtube.client.data.ChannelData.Channel; import app.fedilab.fedilabtube.client.data.AccountData;
import app.fedilab.fedilabtube.fragment.DisplayAccountsFragment; import app.fedilab.fedilabtube.fragment.DisplayAccountsFragment;
import app.fedilab.fedilabtube.fragment.DisplayChannelsFragment;
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.viewmodel.ChannelsVM; import app.fedilab.fedilabtube.viewmodel.AccountsVM;
import app.fedilab.fedilabtube.viewmodel.PostActionsVM; import app.fedilab.fedilabtube.viewmodel.PostActionsVM;
import app.fedilab.fedilabtube.viewmodel.RelationshipVM;
import app.fedilab.fedilabtube.viewmodel.TimelineVM; import app.fedilab.fedilabtube.viewmodel.TimelineVM;
import es.dmoral.toasty.Toasty; import es.dmoral.toasty.Toasty;
import static androidx.core.text.HtmlCompat.FROM_HTML_MODE_LEGACY; import static androidx.core.text.HtmlCompat.FROM_HTML_MODE_LEGACY;
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.FOLLOW;
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.MUTE; import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.MUTE;
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.REPORT_ACCOUNT; import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.REPORT_ACCOUNT;
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.UNFOLLOW;
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.DataType.CHANNEL;
import static app.fedilab.fedilabtube.helper.Helper.getLiveInstance;
import static app.fedilab.fedilabtube.helper.Helper.isLoggedIn;
public class ShowAccountActivity extends AppCompatActivity { public class ShowAccountActivity extends AppCompatActivity {
private Button account_follow;
private ViewPager mPager; private ViewPager mPager;
private TabLayout tabLayout; private TabLayout tabLayout;
private TextView account_note, subscriber_count; private TextView account_note, subscriber_count;
private Map<String, Boolean> relationship;
private ImageView account_pp; private ImageView account_pp;
private TextView account_dn; private TextView account_dn;
private Channel channel; private AccountData.Account account;
private action doAction; private String accountAcct;
private String channelAcct;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -94,15 +77,13 @@ public class ShowAccountActivity extends AppCompatActivity {
setContentView(R.layout.activity_show_account); setContentView(R.layout.activity_show_account);
setTitle(""); setTitle("");
Bundle b = getIntent().getExtras(); Bundle b = getIntent().getExtras();
account_follow = findViewById(R.id.account_follow);
subscriber_count = findViewById(R.id.subscriber_count); subscriber_count = findViewById(R.id.subscriber_count);
account_follow.setEnabled(false);
account_pp = findViewById(R.id.account_pp); account_pp = findViewById(R.id.account_pp);
account_dn = findViewById(R.id.account_dn); account_dn = findViewById(R.id.account_dn);
account_pp.setBackgroundResource(R.drawable.account_pp_border); account_pp.setBackgroundResource(R.drawable.account_pp_border);
if (b != null) { if (b != null) {
channel = b.getParcelable("channel"); account = b.getParcelable("account");
channelAcct = b.getString("channelId"); accountAcct = b.getString("accountAcct");
} else { } else {
Toasty.error(ShowAccountActivity.this, getString(R.string.toast_error_loading_account), Toast.LENGTH_LONG).show(); Toasty.error(ShowAccountActivity.this, getString(R.string.toast_error_loading_account), Toast.LENGTH_LONG).show();
} }
@ -114,11 +95,9 @@ public class ShowAccountActivity extends AppCompatActivity {
tabLayout = findViewById(R.id.account_tabLayout); tabLayout = findViewById(R.id.account_tabLayout);
account_note = findViewById(R.id.account_note); account_note = findViewById(R.id.account_note);
manageAccount();
ChannelsVM viewModel = new ViewModelProvider(ShowAccountActivity.this).get(ChannelsVM.class); AccountsVM viewModel = new ViewModelProvider(ShowAccountActivity.this).get(AccountsVM.class);
viewModel.getAccount(accountAcct == null ? account.getUsername() + "@" + account.getHost() : accountAcct).observe(ShowAccountActivity.this, this::manageViewAccounts);
manageChannel();
viewModel.get(CHANNEL, channelAcct == null ? channel.getName() + "@" + channel.getHost() : channelAcct).observe(ShowAccountActivity.this, this::manageViewAccounts);
} }
@Override @Override
@ -137,7 +116,7 @@ public class ShowAccountActivity extends AppCompatActivity {
return true; return true;
} else if (item.getItemId() == R.id.action_mute) { } else if (item.getItemId() == R.id.action_mute) {
PostActionsVM viewModel = new ViewModelProvider(ShowAccountActivity.this).get(PostActionsVM.class); PostActionsVM viewModel = new ViewModelProvider(ShowAccountActivity.this).get(PostActionsVM.class);
viewModel.post(MUTE, channel.getOwnerAccount() != null ? channel.getOwnerAccount().getAcct() : channel.getAcct(), null).observe(ShowAccountActivity.this, apiResponse -> manageVIewPostActions(MUTE, apiResponse)); viewModel.post(MUTE, accountAcct == null ? account.getUsername() + "@" + account.getHost() : accountAcct, null).observe(ShowAccountActivity.this, apiResponse -> manageVIewPostActions(MUTE, apiResponse));
} else if (item.getItemId() == R.id.action_report) { } else if (item.getItemId() == R.id.action_report) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(ShowAccountActivity.this); AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(ShowAccountActivity.this);
LayoutInflater inflater1 = getLayoutInflater(); LayoutInflater inflater1 = getLayoutInflater();
@ -150,7 +129,7 @@ public class ShowAccountActivity extends AppCompatActivity {
Toasty.info(ShowAccountActivity.this, getString(R.string.report_comment_size), Toasty.LENGTH_LONG).show(); Toasty.info(ShowAccountActivity.this, getString(R.string.report_comment_size), Toasty.LENGTH_LONG).show();
} else { } else {
PostActionsVM viewModel = new ViewModelProvider(ShowAccountActivity.this).get(PostActionsVM.class); PostActionsVM viewModel = new ViewModelProvider(ShowAccountActivity.this).get(PostActionsVM.class);
viewModel.post(REPORT_ACCOUNT, channel.getId(), report_content.getText().toString()).observe(ShowAccountActivity.this, apiResponse -> manageVIewPostActions(REPORT_ACCOUNT, apiResponse)); viewModel.post(REPORT_ACCOUNT, account.getId(), report_content.getText().toString()).observe(ShowAccountActivity.this, apiResponse -> manageVIewPostActions(REPORT_ACCOUNT, apiResponse));
dialog.dismiss(); dialog.dismiss();
} }
}); });
@ -160,30 +139,18 @@ public class ShowAccountActivity extends AppCompatActivity {
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
private void manageChannel() { private void manageAccount() {
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
String accountIdRelation = channel.getAcct();
if (isLoggedIn(ShowAccountActivity.this)) {
RelationshipVM viewModel = new ViewModelProvider(ShowAccountActivity.this).get(RelationshipVM.class);
List<String> uids = new ArrayList<>();
uids.add(accountIdRelation);
viewModel.get(uids).observe(ShowAccountActivity.this, this::manageVIewRelationship);
}
setTitle(channel.getAcct());
setTitle(account.getAcct());
mPager = findViewById(R.id.account_viewpager); mPager = findViewById(R.id.account_viewpager);
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.channels)));
tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.videos))); tabLayout.addTab(tabLayout.newTab().setText(getString(R.string.videos)));
mPager.setOffscreenPageLimit(1); mPager.setOffscreenPageLimit(2);
PagerAdapter mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager()); PagerAdapter mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
mPager.setAdapter(mPagerAdapter); mPager.setAdapter(mPagerAdapter);
ViewGroup.LayoutParams params = tabLayout.getLayoutParams();
params.height = 0;
tabLayout.setLayoutParams(params);
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override @Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
@ -222,112 +189,26 @@ public class ShowAccountActivity extends AppCompatActivity {
switch (tab.getPosition()) { switch (tab.getPosition()) {
case 0: case 0:
if (fragment != null) { if (fragment != null) {
DisplayVideosFragment displayVideosFragment = ((DisplayVideosFragment) fragment); DisplayChannelsFragment displayChannelsFragment = ((DisplayChannelsFragment) fragment);
displayVideosFragment.scrollToTop(); displayChannelsFragment.scrollToTop();
} }
break; break;
case 1: case 1:
if (fragment != null) { if (fragment != null) {
DisplayAccountsFragment displayAccountsFragment = ((DisplayAccountsFragment) fragment); DisplayVideosFragment displayVideosFragment = ((DisplayVideosFragment) fragment);
displayAccountsFragment.scrollToTop(); displayVideosFragment.scrollToTop();
} }
break; break;
} }
} }
}); });
account_dn.setText(channel.getDisplayName()); account_dn.setText(account.getDisplayName());
manageNotes(account);
manageNotes(channel); Helper.loadGiF(ShowAccountActivity.this, account.getAvatar() != null ? account.getAvatar().getPath() : null, account_pp);
Helper.loadGiF(ShowAccountActivity.this, channel.getAvatar() != null ? channel.getAvatar().getPath() : null, account_pp);
//Follow button
String target = channel.getAcct();
account_follow.setOnClickListener(v -> {
if (doAction == action.NOTHING) {
Toasty.info(ShowAccountActivity.this, getString(R.string.nothing_to_do), Toast.LENGTH_LONG).show();
} else if (doAction == action.FOLLOW) {
account_follow.setEnabled(false);
PostActionsVM viewModel = new ViewModelProvider(ShowAccountActivity.this).get(PostActionsVM.class);
viewModel.post(FOLLOW, target, null).observe(ShowAccountActivity.this, apiResponse -> manageVIewPostActions(FOLLOW, apiResponse));
} else if (doAction == action.UNFOLLOW) {
boolean confirm_unfollow = sharedpreferences.getBoolean(Helper.SET_UNFOLLOW_VALIDATION, true);
if (confirm_unfollow) {
AlertDialog.Builder unfollowConfirm = new AlertDialog.Builder(ShowAccountActivity.this);
unfollowConfirm.setTitle(getString(R.string.unfollow_confirm));
unfollowConfirm.setMessage(channel.getAcct());
unfollowConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
unfollowConfirm.setPositiveButton(R.string.yes, (dialog, which) -> {
account_follow.setEnabled(false);
PostActionsVM viewModel = new ViewModelProvider(ShowAccountActivity.this).get(PostActionsVM.class);
viewModel.post(UNFOLLOW, target, null).observe(ShowAccountActivity.this, apiResponse -> manageVIewPostActions(UNFOLLOW, apiResponse));
dialog.dismiss();
});
unfollowConfirm.show();
} else {
account_follow.setEnabled(false);
PostActionsVM viewModel = new ViewModelProvider(ShowAccountActivity.this).get(PostActionsVM.class);
viewModel.post(UNFOLLOW, target, null).observe(ShowAccountActivity.this, apiResponse -> manageVIewPostActions(UNFOLLOW, apiResponse));
} }
}
});
}
public void manageVIewRelationship(APIResponse apiResponse) {
if (apiResponse.getError() != null) {
Toasty.error(ShowAccountActivity.this, apiResponse.getError().getError(), Toast.LENGTH_LONG).show();
return;
}
this.relationship = apiResponse.getRelationships();
manageButtonVisibility();
invalidateOptionsMenu();
}
//Manages the visibility of the button
private void manageButtonVisibility() {
if (relationship == null)
return;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
int[][] states = new int[][]{
new int[]{android.R.attr.state_enabled}, // enabled
new int[]{-android.R.attr.state_enabled}, // disabled
new int[]{-android.R.attr.state_checked}, // unchecked
new int[]{android.R.attr.state_pressed} // pressed
};
int[] colors = new int[]{
ContextCompat.getColor(ShowAccountActivity.this, Helper.getColorAccent()),
ContextCompat.getColor(ShowAccountActivity.this, Helper.getColorAccent()),
ContextCompat.getColor(ShowAccountActivity.this, Helper.getColorAccent()),
ContextCompat.getColor(ShowAccountActivity.this, Helper.getColorAccent())
};
account_follow.setBackgroundTintList(new ColorStateList(states, colors));
}
account_follow.setEnabled(true);
boolean isFollowing = relationship.get(channel.getAcct());
if (isFollowing) {
account_follow.setText(R.string.action_unfollow);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
account_follow.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(ShowAccountActivity.this, R.color.red_1)));
}
doAction = action.UNFOLLOW;
account_follow.setVisibility(View.VISIBLE);
} else {
account_follow.setText(R.string.action_follow);
doAction = action.FOLLOW;
account_follow.setVisibility(View.VISIBLE);
}
}
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
@ -345,47 +226,31 @@ public class ShowAccountActivity extends AppCompatActivity {
Toasty.error(ShowAccountActivity.this, apiResponse.getError().getError(), Toast.LENGTH_LONG).show(); Toasty.error(ShowAccountActivity.this, apiResponse.getError().getError(), Toast.LENGTH_LONG).show();
return; return;
} }
String target = channel.getAcct(); if (statusAction == RetrofitPeertubeAPI.ActionType.MUTE) {
//IF action is unfollow or mute, sends an intent to remove statuses
if (statusAction == RetrofitPeertubeAPI.ActionType.UNFOLLOW) {
Bundle b = new Bundle();
b.putString("receive_action", apiResponse.getTargetedId());
Intent intentBC = new Intent(Helper.RECEIVE_ACTION);
intentBC.putExtras(b);
}
if (statusAction == RetrofitPeertubeAPI.ActionType.UNFOLLOW || statusAction == RetrofitPeertubeAPI.ActionType.FOLLOW) {
RelationshipVM viewModel = new ViewModelProvider(ShowAccountActivity.this).get(RelationshipVM.class);
List<String> uris = new ArrayList<>();
uris.add(target);
viewModel.get(uris).observe(ShowAccountActivity.this, this::manageVIewRelationship);
} else if (statusAction == RetrofitPeertubeAPI.ActionType.MUTE) {
Toasty.info(ShowAccountActivity.this, getString(R.string.muted_done), Toast.LENGTH_LONG).show(); Toasty.info(ShowAccountActivity.this, getString(R.string.muted_done), Toast.LENGTH_LONG).show();
} }
} }
public void manageViewAccounts(APIResponse apiResponse) { public void manageViewAccounts(APIResponse apiResponse) {
if (apiResponse.getChannels() != null && apiResponse.getChannels().size() == 1) { if (apiResponse.getAccounts() != null && apiResponse.getAccounts().size() == 1) {
Channel channel = apiResponse.getChannels().get(0); AccountData.Account account = apiResponse.getAccounts().get(0);
if (this.channel == null) { if (this.account == null) {
this.channel = channel; this.account = account;
manageChannel(); manageAccount();
} }
if (channel.getOwnerAccount() != null) { subscriber_count.setText(getString(R.string.followers_count, Helper.withSuffix(account.getFollowersCount())));
this.channel.setOwnerAccount(channel.getOwnerAccount());
}
subscriber_count.setText(getString(R.string.followers_count, Helper.withSuffix(channel.getFollowersCount())));
subscriber_count.setVisibility(View.VISIBLE); subscriber_count.setVisibility(View.VISIBLE);
manageNotes(channel); manageNotes(account);
} }
} }
private void manageNotes(Channel channel) { private void manageNotes(AccountData.Account account) {
if (channel.getDescription() != null && channel.getDescription().compareTo("null") != 0 && channel.getDescription().trim().length() > 0) { if (account.getDescription() != null && account.getDescription().compareTo("null") != 0 && account.getDescription().trim().length() > 0) {
SpannableString spannableString; SpannableString spannableString;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
spannableString = new SpannableString(Html.fromHtml(channel.getDescription(), FROM_HTML_MODE_LEGACY)); spannableString = new SpannableString(Html.fromHtml(account.getDescription(), FROM_HTML_MODE_LEGACY));
else else
spannableString = new SpannableString(Html.fromHtml(channel.getDescription())); spannableString = new SpannableString(Html.fromHtml(account.getDescription()));
account_note.setText(spannableString, TextView.BufferType.SPANNABLE); account_note.setText(spannableString, TextView.BufferType.SPANNABLE);
account_note.setMovementMethod(LinkMovementMethod.getInstance()); account_note.setMovementMethod(LinkMovementMethod.getInstance());
@ -395,11 +260,6 @@ public class ShowAccountActivity extends AppCompatActivity {
} }
} }
public enum action {
FOLLOW,
UNFOLLOW,
NOTHING
}
/** /**
* Pager adapter for the 2 fragments * Pager adapter for the 2 fragments
@ -415,25 +275,24 @@ public class ShowAccountActivity extends AppCompatActivity {
public Fragment getItem(int position) { public Fragment getItem(int position) {
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
if (position == 0) { if (position == 0) {
DisplayChannelsFragment displayChannelsFragment = new DisplayChannelsFragment();
bundle.putString("name", account.getAcct());
bundle.putBoolean("myChannels", false);
displayChannelsFragment.setArguments(bundle);
return displayChannelsFragment;
}
DisplayVideosFragment displayVideosFragment = new DisplayVideosFragment(); DisplayVideosFragment displayVideosFragment = new DisplayVideosFragment();
bundle = new Bundle(); bundle.putSerializable(Helper.TIMELINE_TYPE, TimelineVM.TimelineType.ACCOUNT_VIDEOS);
bundle.putSerializable("type", TimelineVM.TimelineType.USER_VIDEOS); bundle.putString("channelId", account.getAcct());
bundle.putString("channelId", channel.getAcct()); bundle.putString("peertube_instance", account.getHost());
displayVideosFragment.setArguments(bundle); displayVideosFragment.setArguments(bundle);
return displayVideosFragment; return displayVideosFragment;
} }
DisplayAccountsFragment displayAccountsFragment = new DisplayAccountsFragment();
bundle.putString("targetedid", channel.getId());
bundle.putString("instance", getLiveInstance(ShowAccountActivity.this));
bundle.putString("name", channel.getAcct());
displayAccountsFragment.setArguments(bundle);
return displayAccountsFragment;
}
@Override @Override
public int getCount() { public int getCount() {
return 1; return 2;
} }
} }

View File

@ -70,7 +70,6 @@ import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.MUTE
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.REPORT_ACCOUNT; import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.REPORT_ACCOUNT;
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.UNFOLLOW; import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.UNFOLLOW;
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.DataType.CHANNEL; import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.DataType.CHANNEL;
import static app.fedilab.fedilabtube.helper.Helper.getLiveInstance;
import static app.fedilab.fedilabtube.helper.Helper.isLoggedIn; import static app.fedilab.fedilabtube.helper.Helper.isLoggedIn;
@ -87,11 +86,13 @@ public class ShowChannelActivity extends AppCompatActivity {
private Channel channel; private Channel channel;
private action doAction; private action doAction;
private String channelAcct; private String channelAcct;
private boolean sepiaSearch;
private String peertubeInstance;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_show_account); setContentView(R.layout.activity_show_channel);
setTitle(""); setTitle("");
Bundle b = getIntent().getExtras(); Bundle b = getIntent().getExtras();
account_follow = findViewById(R.id.account_follow); account_follow = findViewById(R.id.account_follow);
@ -103,6 +104,9 @@ public class ShowChannelActivity extends AppCompatActivity {
if (b != null) { if (b != null) {
channel = b.getParcelable("channel"); channel = b.getParcelable("channel");
channelAcct = b.getString("channelId"); channelAcct = b.getString("channelId");
sepiaSearch = b.getBoolean("sepia_search", false);
peertubeInstance = b.getString("peertube_instance", null);
} else { } else {
Toasty.error(ShowChannelActivity.this, getString(R.string.toast_error_loading_account), Toast.LENGTH_LONG).show(); Toasty.error(ShowChannelActivity.this, getString(R.string.toast_error_loading_account), Toast.LENGTH_LONG).show();
} }
@ -116,14 +120,14 @@ public class ShowChannelActivity extends AppCompatActivity {
ChannelsVM viewModel = new ViewModelProvider(ShowChannelActivity.this).get(ChannelsVM.class); ChannelsVM viewModel = new ViewModelProvider(ShowChannelActivity.this).get(ChannelsVM.class);
viewModel.get(CHANNEL, channelAcct == null ? channel.getAcct() : channelAcct).observe(ShowChannelActivity.this, this::manageViewAccounts); viewModel.get(sepiaSearch?peertubeInstance:null, CHANNEL, channelAcct == null ? channel.getAcct() : channelAcct).observe(ShowChannelActivity.this, this::manageViewAccounts);
manageChannel(); manageChannel();
} }
@Override @Override
public boolean onCreateOptionsMenu(@NotNull Menu menu) { public boolean onCreateOptionsMenu(@NotNull Menu menu) {
getMenuInflater().inflate(R.menu.main_account, menu); getMenuInflater().inflate(R.menu.main_account, menu);
if (!Helper.isLoggedIn(ShowChannelActivity.this)) { if (!Helper.isLoggedIn(ShowChannelActivity.this) || sepiaSearch) {
menu.findItem(R.id.action_mute).setVisible(false); menu.findItem(R.id.action_mute).setVisible(false);
} }
return true; return true;
@ -163,7 +167,7 @@ public class ShowChannelActivity extends AppCompatActivity {
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE); SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
String accountIdRelation = channel.getAcct(); String accountIdRelation = channel.getAcct();
if (isLoggedIn(ShowChannelActivity.this)) { if (isLoggedIn(ShowChannelActivity.this) && !sepiaSearch) {
RelationshipVM viewModel = new ViewModelProvider(ShowChannelActivity.this).get(RelationshipVM.class); RelationshipVM viewModel = new ViewModelProvider(ShowChannelActivity.this).get(RelationshipVM.class);
List<String> uids = new ArrayList<>(); List<String> uids = new ArrayList<>();
uids.add(accountIdRelation); uids.add(accountIdRelation);
@ -239,7 +243,7 @@ public class ShowChannelActivity extends AppCompatActivity {
manageNotes(channel); manageNotes(channel);
Helper.loadGiF(ShowChannelActivity.this, channel.getAvatar() != null ? channel.getAvatar().getPath() : null, account_pp); Helper.loadGiF(ShowChannelActivity.this, sepiaSearch?peertubeInstance:null, channel.getAvatar() != null ? channel.getAvatar().getPath() : null, account_pp);
//Follow button //Follow button
String target = channel.getAcct(); String target = channel.getAcct();
@ -318,12 +322,11 @@ public class ShowChannelActivity extends AppCompatActivity {
account_follow.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(ShowChannelActivity.this, R.color.red_1))); account_follow.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(ShowChannelActivity.this, R.color.red_1)));
} }
doAction = action.UNFOLLOW; doAction = action.UNFOLLOW;
account_follow.setVisibility(View.VISIBLE);
} else { } else {
account_follow.setText(R.string.action_follow); account_follow.setText(R.string.action_follow);
doAction = action.FOLLOW; doAction = action.FOLLOW;
account_follow.setVisibility(View.VISIBLE);
} }
account_follow.setVisibility(View.VISIBLE);
} }
@ -412,22 +415,15 @@ public class ShowChannelActivity extends AppCompatActivity {
@NotNull @NotNull
@Override @Override
public Fragment getItem(int position) { public Fragment getItem(int position) {
Bundle bundle = new Bundle();
if (position == 0) {
DisplayVideosFragment displayVideosFragment = new DisplayVideosFragment(); DisplayVideosFragment displayVideosFragment = new DisplayVideosFragment();
bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putSerializable(Helper.TIMELINE_TYPE, TimelineVM.TimelineType.USER_VIDEOS); bundle.putSerializable(Helper.TIMELINE_TYPE, TimelineVM.TimelineType.CHANNEL_VIDEOS);
bundle.putString("channelId", channel.getAcct()); bundle.putString("channelId", channel.getAcct());
bundle.putString("peertube_instance", channel.getHost());
bundle.putBoolean("sepia_search", sepiaSearch);
displayVideosFragment.setArguments(bundle); displayVideosFragment.setArguments(bundle);
return displayVideosFragment; return displayVideosFragment;
} }
DisplayAccountsFragment displayAccountsFragment = new DisplayAccountsFragment();
bundle.putString("targetedid", channel.getId());
bundle.putString("instance", getLiveInstance(ShowChannelActivity.this));
bundle.putString("name", channel.getAcct());
displayAccountsFragment.setArguments(bundle);
return displayAccountsFragment;
}
@Override @Override

View File

@ -129,11 +129,11 @@ public class WebviewActivity extends AppCompatActivity {
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { int itemId = item.getItemId();
case android.R.id.home: if (itemId == android.R.id.home) {
finish(); finish();
return true; return true;
case R.id.action_go: } else if (itemId == R.id.action_go) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
try { try {
startActivity(browserIntent); startActivity(browserIntent);
@ -141,9 +141,8 @@ public class WebviewActivity extends AppCompatActivity {
Toasty.error(WebviewActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show(); Toasty.error(WebviewActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show();
} }
return true; return true;
default:
return super.onOptionsItemSelected(item);
} }
return super.onOptionsItemSelected(item);
} }
public void setUrl(String newUrl) { public void setUrl(String newUrl) {

View File

@ -46,6 +46,7 @@ public class APIResponse {
private List<CommentData.Comment> comments = null; private List<CommentData.Comment> comments = null;
private List<Block> muted; private List<Block> muted;
private List<VideoPlaylist> videoPlaylist; private List<VideoPlaylist> videoPlaylist;
private CommentData.CommentThreadData commentThreadData;
private List<NotificationData.Notification> peertubeNotifications = null; private List<NotificationData.Notification> peertubeNotifications = null;
private List<PlaylistData.Playlist> playlists = null; private List<PlaylistData.Playlist> playlists = null;
private List<String> domains = null; private List<String> domains = null;
@ -247,4 +248,12 @@ public class APIResponse {
public void setVideoExistPlaylist(Map<String, List<PlaylistExist>> videoExistPlaylist) { public void setVideoExistPlaylist(Map<String, List<PlaylistExist>> videoExistPlaylist) {
this.videoExistPlaylist = videoExistPlaylist; this.videoExistPlaylist = videoExistPlaylist;
} }
public CommentData.CommentThreadData getCommentThreadData() {
return commentThreadData;
}
public void setCommentThreadData(CommentData.CommentThreadData commentThreadData) {
this.commentThreadData = commentThreadData;
}
} }

View File

@ -17,6 +17,7 @@ package app.fedilab.fedilabtube.client;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import app.fedilab.fedilabtube.client.data.AccountData; import app.fedilab.fedilabtube.client.data.AccountData;
import app.fedilab.fedilabtube.client.data.BlockData; import app.fedilab.fedilabtube.client.data.BlockData;
import app.fedilab.fedilabtube.client.data.CaptionData; import app.fedilab.fedilabtube.client.data.CaptionData;
@ -66,7 +67,7 @@ public interface PeertubeService {
Call<WellKnownNodeinfo> getWellKnownNodeinfo(); Call<WellKnownNodeinfo> getWellKnownNodeinfo();
@GET("{nodeInfoPath}") @GET("{nodeInfoPath}")
Call<WellKnownNodeinfo.NodeInfo> getNodeinfo(@Path("nodeInfoPath") String nodeInfoPath); Call<WellKnownNodeinfo.NodeInfo> getNodeinfo(@Path(value = "nodeInfoPath", encoded = true) String nodeInfoPath);
@GET("{captionContent}") @GET("{captionContent}")
Call<String> getCaptionContent(@Path("captionContent") String captionContent); Call<String> getCaptionContent(@Path("captionContent") String captionContent);
@ -165,7 +166,7 @@ public interface PeertubeService {
//Get my video //Get my video
@GET("accounts/{name}/videos?sort=-publishedAt") @GET("accounts/{name}/videos?sort=-publishedAt")
Call<VideoData.Video> getVideosForAccount(@Query("start") String maxId, @Query("count") String count); Call<VideoData> getVideosForAccount(@Path("name") String name, @Query("start") String maxId, @Query("count") String count);
@Multipart @Multipart
@PUT("videos/{id}") @PUT("videos/{id}")
@ -228,6 +229,11 @@ public interface PeertubeService {
@GET("video-playlists") @GET("video-playlists")
Call<PlaylistData> getPlaylists(); Call<PlaylistData> getPlaylists();
//Get a single account
@GET("accounts/{accountHandle}")
Call<AccountData.Account> getAccount(@Path("accountHandle") String accountHandle);
//Get/Post/Update/Delete playlist //Get/Post/Update/Delete playlist
@GET("accounts/{accountHandle}/video-playlists") @GET("accounts/{accountHandle}/video-playlists")
Call<PlaylistData> getPlaylistsForAccount(@Header("Authorization") String credentials, @Path("accountHandle") String accountHandle); Call<PlaylistData> getPlaylistsForAccount(@Header("Authorization") String credentials, @Path("accountHandle") String accountHandle);
@ -288,7 +294,7 @@ public interface PeertubeService {
//Subscribe/Unsubscribe //Subscribe/Unsubscribe
//subscribers //subscribers
@GET("users/me/subscriptions") @GET("users/me/subscriptions")
Call<AccountData> getSubscription(@Header("Authorization") String credentials, @Query("start") String maxId, @Query("count") String count); Call<ChannelData> getSubscription(@Header("Authorization") String credentials, @Query("start") String maxId, @Query("count") String count);
@GET("users/me/subscriptions/exist") @GET("users/me/subscriptions/exist")
Call<Map<String, Boolean>> getSubscriptionsExist(@Header("Authorization") String credentials, @Query("uris") List<String> uris); Call<Map<String, Boolean>> getSubscriptionsExist(@Header("Authorization") String credentials, @Query("uris") List<String> uris);
@ -328,22 +334,25 @@ public interface PeertubeService {
Call<CommentData> getComments(@Path("id") String id, @Query("start") String maxId, @Query("count") String count); Call<CommentData> getComments(@Path("id") String id, @Query("start") String maxId, @Query("count") String count);
@GET("videos/{id}/comment-threads/{threadId}") @GET("videos/{id}/comment-threads/{threadId}")
Call<CommentData> getReplies(@Path("id") String id, @Path("threadId") String threadId); Call<CommentData.CommentThreadData> getReplies(@Path("id") String id, @Path("threadId") String threadId);
@FormUrlEncoded @FormUrlEncoded
@POST("videos/{id}/comment-threads") @POST("videos/{id}/comment-threads")
Call<String> postComment(@Header("Authorization") String credentials, @Path("id") String id, @Field("text") String text); Call<CommentData.CommentPosted> postComment(@Header("Authorization") String credentials, @Path("id") String id, @Field("text") String text);
@FormUrlEncoded @FormUrlEncoded
@POST("videos/{id}/comments/{commentId}") @POST("videos/{id}/comments/{commentId}")
Call<String> postReply(@Header("Authorization") String credentials, @Path("id") String id, @Path("commentId") String commentId, @Field("text") String text); Call<CommentData.CommentPosted> postReply(@Header("Authorization") String credentials, @Path("id") String id, @Path("commentId") String commentId, @Field("text") String text);
@DELETE("videos/{id}/comments/{commentId}") @DELETE("videos/{id}/comments/{commentId}")
Call<String> deleteComment(@Header("Authorization") String credentials, @Path("id") String id, @Path("commentId") String commentId); Call<String> deleteComment(@Header("Authorization") String credentials, @Path("id") String id, @Path("commentId") String commentId);
@POST("bulk/remove-comments-of")
Call<String> deleteAllCommentForAccount(@Header("Authorization") String credentials, @Field("accountName") String accountName, @Field("scope") String scope);
@Headers({"Content-Type: application/json", "Cache-Control: max-age=640000"}) @Headers({"Content-Type: application/json", "Cache-Control: max-age=640000"})
@POST("abuses") @POST("abuses")
Call<String> report( Call<Report.ReportReturn> report(
@Header("Authorization") String credentials, @Header("Authorization") String credentials,
@Body Report report); @Body Report report);

View File

@ -25,6 +25,7 @@ import android.os.Looper;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -81,12 +82,12 @@ import retrofit2.converter.gson.GsonConverterFactory;
@SuppressWarnings({"unused", "RedundantSuppression"}) @SuppressWarnings({"unused", "RedundantSuppression"})
public class RetrofitPeertubeAPI { public class RetrofitPeertubeAPI {
private String finalUrl; private final String finalUrl;
private Context _context; private final Context _context;
private String instance; private final String instance;
private String token; private String token;
private Set<String> selection; private Set<String> selection;
private String count = String.valueOf(Helper.VIDEOS_PER_PAGE); private final String count;
public RetrofitPeertubeAPI(Context context) { public RetrofitPeertubeAPI(Context context) {
_context = context; _context = context;
@ -310,7 +311,7 @@ public class RetrofitPeertubeAPI {
return apiResponse; return apiResponse;
} }
public APIResponse getTL(TimelineVM.TimelineType timelineType, String max_id) { public APIResponse getTL(TimelineVM.TimelineType timelineType, String max_id, String forAccount) {
APIResponse apiResponse = new APIResponse(); APIResponse apiResponse = new APIResponse();
PeertubeService peertubeService = init(); PeertubeService peertubeService = init();
Call<VideoData> videoCall = null; Call<VideoData> videoCall = null;
@ -319,8 +320,15 @@ public class RetrofitPeertubeAPI {
case MY_VIDEOS: case MY_VIDEOS:
videoCall = peertubeService.getMyVideos(getToken(), max_id, count); videoCall = peertubeService.getMyVideos(getToken(), max_id, count);
break; break;
case ACCOUNT_VIDEOS:
videoCall = peertubeService.getVideosForAccount(forAccount, max_id, count);
break;
case SUBSCRIBTIONS: case SUBSCRIBTIONS:
if (forAccount == null) {
videoCall = peertubeService.getSubscriptionVideos(getToken(), max_id, count, filter); videoCall = peertubeService.getSubscriptionVideos(getToken(), max_id, count, filter);
} else {
videoCall = peertubeService.getChannelVideos(forAccount, max_id, count);
}
break; break;
case MOST_LIKED: case MOST_LIKED:
videoCall = peertubeService.getMostLikedVideos(max_id, count, filter); videoCall = peertubeService.getMostLikedVideos(max_id, count, filter);
@ -557,6 +565,9 @@ public class RetrofitPeertubeAPI {
lang = lang.split("-")[0] + "-" + lang.split("-")[1].toUpperCase(); lang = lang.split("-")[0] + "-" + lang.split("-")[1].toUpperCase();
} }
} }
if( lang == null || lang.trim().length() == 0) {
lang = "en";
}
Call<Map<String, String>> translations = initTranslation().getTranslations(lang); Call<Map<String, String>> translations = initTranslation().getTranslations(lang);
try { try {
Response<Map<String, String>> response = translations.execute(); Response<Map<String, String>> response = translations.execute();
@ -687,12 +698,12 @@ public class RetrofitPeertubeAPI {
public APIResponse report(Report report) { public APIResponse report(Report report) {
PeertubeService peertubeService = init(); PeertubeService peertubeService = init();
Call<String> report1 = peertubeService.report(getToken(), report); Call<Report.ReportReturn> report1 = peertubeService.report(getToken(), report);
APIResponse apiResponse = new APIResponse(); APIResponse apiResponse = new APIResponse();
try { try {
Response<String> response = report1.execute(); Response<Report.ReportReturn> response = report1.execute();
if (response.isSuccessful()) { if (response.isSuccessful() && response.body() != null) {
apiResponse.setActionReturn(response.body()); apiResponse.setActionReturn(response.body().getItemStr().getLabel());
} else { } else {
setError(apiResponse, response.code(), response.errorBody()); setError(apiResponse, response.code(), response.errorBody());
} }
@ -811,6 +822,9 @@ public class RetrofitPeertubeAPI {
case PEERTUBEDELETECOMMENT: case PEERTUBEDELETECOMMENT:
postCall = peertubeService.deleteComment(getToken(), id, element); postCall = peertubeService.deleteComment(getToken(), id, element);
break; break;
case PEERTUBE_DELETE_ALL_COMMENT_FOR_ACCOUNT:
postCall = peertubeService.deleteAllCommentForAccount(getToken(), id, element);
break;
case DELETE_CHANNEL: case DELETE_CHANNEL:
postCall = peertubeService.deleteChannel(getToken(), id); postCall = peertubeService.deleteChannel(getToken(), id);
break; break;
@ -833,6 +847,38 @@ public class RetrofitPeertubeAPI {
return apiResponse; return apiResponse;
} }
/**
* Get single account by its handle
*
* @param accountHandle String
* @return APIResponse
*/
public APIResponse getAccount(String accountHandle) {
PeertubeService peertubeService = init();
Call<AccountData.Account> accountDataCall = peertubeService.getAccount(accountHandle);
APIResponse apiResponse = new APIResponse();
if (accountDataCall != null) {
try {
Response<AccountData.Account> response = accountDataCall.execute();
if (response.isSuccessful() && response.body() != null) {
List<AccountData.Account> accountList = new ArrayList<>();
accountList.add(response.body());
apiResponse.setAccounts(accountList);
} else {
setError(apiResponse, response.code(), response.errorBody());
}
} catch (IOException e) {
Error error = new Error();
error.setError(_context.getString(R.string.toast_error));
apiResponse.setError(error);
e.printStackTrace();
}
}
return apiResponse;
}
/** /**
* Get muted accounts * Get muted accounts
* *
@ -869,13 +915,13 @@ public class RetrofitPeertubeAPI {
*/ */
public APIResponse getSubscribtions(String maxId) { public APIResponse getSubscribtions(String maxId) {
PeertubeService peertubeService = init(); PeertubeService peertubeService = init();
Call<AccountData> accountDataCall = peertubeService.getSubscription("Bearer " + token, maxId, count); Call<ChannelData> channelDataCall = peertubeService.getSubscription("Bearer " + token, maxId, count);
APIResponse apiResponse = new APIResponse(); APIResponse apiResponse = new APIResponse();
if (accountDataCall != null) { if (channelDataCall != null) {
try { try {
Response<AccountData> response = accountDataCall.execute(); Response<ChannelData> response = channelDataCall.execute();
if (response.isSuccessful() && response.body() != null) { if (response.isSuccessful() && response.body() != null) {
apiResponse.setAccounts(response.body().data); apiResponse.setChannels(response.body().data);
} else { } else {
setError(apiResponse, response.code(), response.errorBody()); setError(apiResponse, response.code(), response.errorBody());
} }
@ -959,13 +1005,18 @@ public class RetrofitPeertubeAPI {
* @return APIResponse * @return APIResponse
*/ */
public WellKnownNodeinfo.NodeInfo getNodeInfo() { public WellKnownNodeinfo.NodeInfo getNodeInfo() {
PeertubeService peertubeService = init(); PeertubeService peertubeService = initTranslation();
try { try {
Call<WellKnownNodeinfo> wellKnownNodeinfoCall = peertubeService.getWellKnownNodeinfo(); Call<WellKnownNodeinfo> wellKnownNodeinfoCall = peertubeService.getWellKnownNodeinfo();
Response<WellKnownNodeinfo> response = wellKnownNodeinfoCall.execute(); Response<WellKnownNodeinfo> response = wellKnownNodeinfoCall.execute();
if (response.isSuccessful() && response.body() != null) { if (response.isSuccessful() && response.body() != null) {
if (response.body().getHref() != null) { int size = response.body().getLinks().size();
Call<WellKnownNodeinfo.NodeInfo> nodeinfo = peertubeService.getNodeinfo(response.body().getHref()); String url = response.body().getLinks().get(size - 1).getHref();
if (size > 0 && url != null) {
peertubeService = initTranslation();
String path = new URL(url).getPath();
path = path.replaceFirst("/", "").trim();
Call<WellKnownNodeinfo.NodeInfo> nodeinfo = peertubeService.getNodeinfo(path);
Response<WellKnownNodeinfo.NodeInfo> responseNodeInfo = nodeinfo.execute(); Response<WellKnownNodeinfo.NodeInfo> responseNodeInfo = nodeinfo.execute();
return responseNodeInfo.body(); return responseNodeInfo.body();
} }
@ -994,7 +1045,6 @@ public class RetrofitPeertubeAPI {
try { try {
Response<ChannelData> response = channelDataCall.execute(); Response<ChannelData> response = channelDataCall.execute();
if (response.isSuccessful() && response.body() != null) { if (response.isSuccessful() && response.body() != null) {
apiResponse.setChannels(response.body().data); apiResponse.setChannels(response.body().data);
} else { } else {
setError(apiResponse, response.code(), response.errorBody()); setError(apiResponse, response.code(), response.errorBody());
@ -1188,10 +1238,10 @@ public class RetrofitPeertubeAPI {
setError(apiResponse, response.code(), response.errorBody()); setError(apiResponse, response.code(), response.errorBody());
} }
} else if (type == CommentVM.action.GET_REPLIES) { } else if (type == CommentVM.action.GET_REPLIES) {
Call<CommentData> commentsCall = peertubeService.getReplies(videoId, forCommentId); Call<CommentData.CommentThreadData> commentsCall = peertubeService.getReplies(videoId, forCommentId);
Response<CommentData> response = commentsCall.execute(); Response<CommentData.CommentThreadData> response = commentsCall.execute();
if (response.isSuccessful() && response.body() != null) { if (response.isSuccessful() && response.body() != null) {
apiResponse.setComments(response.body().data); apiResponse.setCommentThreadData(response.body());
} else { } else {
setError(apiResponse, response.code(), response.errorBody()); setError(apiResponse, response.code(), response.errorBody());
} }
@ -1220,18 +1270,22 @@ public class RetrofitPeertubeAPI {
APIResponse apiResponse = new APIResponse(); APIResponse apiResponse = new APIResponse();
try { try {
if (type == ActionType.ADD_COMMENT) { if (type == ActionType.ADD_COMMENT) {
Call<String> stringCall = peertubeService.postComment(getToken(), videoId, text); Call<CommentData.CommentPosted> commentPostedCall = peertubeService.postComment(getToken(), videoId, text);
Response<String> response = stringCall.execute(); Response<CommentData.CommentPosted> response = commentPostedCall.execute();
if (response.isSuccessful()) { if (response.isSuccessful() && response.body() != null) {
apiResponse.setActionReturn(response.body()); List<CommentData.Comment> comments = new ArrayList<>();
comments.add(response.body().getComment());
apiResponse.setComments(comments);
} else { } else {
setError(apiResponse, response.code(), response.errorBody()); setError(apiResponse, response.code(), response.errorBody());
} }
} else if (type == ActionType.REPLY) { } else if (type == ActionType.REPLY) {
Call<String> stringCall = peertubeService.postReply(getToken(), videoId, toCommentId, text); Call<CommentData.CommentPosted> commentPostedCall = peertubeService.postReply(getToken(), videoId, toCommentId, text);
Response<String> response = stringCall.execute(); Response<CommentData.CommentPosted> response = commentPostedCall.execute();
if (response.isSuccessful()) { if (response.isSuccessful() && response.body() != null) {
apiResponse.setActionReturn(response.body()); List<CommentData.Comment> comments = new ArrayList<>();
comments.add(response.body().getComment());
apiResponse.setComments(comments);
} else { } else {
setError(apiResponse, response.code(), response.errorBody()); setError(apiResponse, response.code(), response.errorBody());
} }
@ -1334,6 +1388,7 @@ public class RetrofitPeertubeAPI {
APIResponse apiResponse = new APIResponse(); APIResponse apiResponse = new APIResponse();
try { try {
Response<VideoData.Video> response = video.execute(); Response<VideoData.Video> response = video.execute();
if (response.isSuccessful()) { if (response.isSuccessful()) {
List<VideoData.Video> videos = new ArrayList<>(); List<VideoData.Video> videos = new ArrayList<>();
videos.add(response.body()); videos.add(response.body());
@ -1374,6 +1429,7 @@ public class RetrofitPeertubeAPI {
UNMUTE, UNMUTE,
RATEVIDEO, RATEVIDEO,
PEERTUBEDELETECOMMENT, PEERTUBEDELETECOMMENT,
PEERTUBE_DELETE_ALL_COMMENT_FOR_ACCOUNT,
PEERTUBEDELETEVIDEO, PEERTUBEDELETEVIDEO,
REPORT_VIDEO, REPORT_VIDEO,
REPORT_ACCOUNT, REPORT_ACCOUNT,

View File

@ -0,0 +1,86 @@
package app.fedilab.fedilabtube.client;
/* 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 java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Locale;
import app.fedilab.fedilabtube.client.data.VideoData;
import app.fedilab.fedilabtube.client.entities.SepiaSearch;
import app.fedilab.fedilabtube.helper.Helper;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitSepiaSearchAPI {
private String finalUrl;
public RetrofitSepiaSearchAPI() {
finalUrl = "https://search.joinpeertube.org/api/v1/";
}
private SepiaSearchService init() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(finalUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit.create(SepiaSearchService.class);
}
/**
* Return videos for a sepia search
* @param sepiaSearch SepiaSearch
* @return VideoData
*/
public VideoData getVideos(SepiaSearch sepiaSearch) {
SepiaSearchService sepiaSearchService = init();
SimpleDateFormat fmtOut = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH);
String startDate = null;
if(sepiaSearch.getStartDate() != null) {
startDate = fmtOut.format(sepiaSearch.getStartDate());
}
Call<VideoData> videoDataCall = sepiaSearchService.getVideos(
sepiaSearch.getStart(),
sepiaSearch.getCount(),
sepiaSearch.getSearch(),
sepiaSearch.getDurationMin(),
sepiaSearch.getDurationMax(),
startDate,
sepiaSearch.getBoostLanguages(),
sepiaSearch.getCategoryOneOf(),
sepiaSearch.getLicenceOneOf(),
sepiaSearch.getTagsOneOf(),
sepiaSearch.getTagsAllOf(),
sepiaSearch.isNsfw(),
sepiaSearch.getSort());
try {
Response<VideoData> response = videoDataCall.execute();
if (response.isSuccessful() && response.body() != null) {
return response.body();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}

View File

@ -0,0 +1,54 @@
package app.fedilab.fedilabtube.client;
/* 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 java.util.Date;
import java.util.List;
import app.fedilab.fedilabtube.client.data.ChannelData;
import app.fedilab.fedilabtube.client.data.VideoData;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
interface SepiaSearchService {
@GET("search/videos")
Call<VideoData> getVideos(
@Query("start") String maxId,
@Query("count") String count,
@Query("search") String search,
@Query("durationMin") int durationMin,
@Query("durationMax") int durationMax,
@Query("startDate") String startDate,
@Query("boostLanguages") List<String> languageOneOf,
@Query("categoryOneOf") List<Integer> categoryOneOf,
@Query("licenceOneOf") List<Integer> licenceOneOf,
@Query("tagsOneOf") List<String> tagsOneOf,
@Query("tagsAllOf") List<String> tagsAllOf,
@Query("nsfw") boolean nsfw,
@Query("sort") String sort
);
@GET("search/channels")
Call<ChannelData> getChannels(
@Query("search") String search,
@Query("start") String maxId,
@Query("count") String count
);
}

View File

@ -77,7 +77,7 @@ public class AccountData {
private String client_id; private String client_id;
private String client_secret; private String client_secret;
private String refresh_token; private String refresh_token;
private boolean selected;
public Account() { public Account() {
} }
@ -197,14 +197,6 @@ public class AccountData {
this.url = url; this.url = url;
} }
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
public String getAcct() { public String getAcct() {
return name + "@" + host; return name + "@" + host;
} }

View File

@ -80,6 +80,7 @@ public class ChannelData {
@SerializedName("viewsPerDay") @SerializedName("viewsPerDay")
private List<ViewsPerDay> viewsPerDays; private List<ViewsPerDay> viewsPerDays;
private String acct; private String acct;
private boolean selected;
public Channel() { public Channel() {
} }
@ -243,6 +244,14 @@ public class ChannelData {
this.viewsPerDays = viewsPerDays; this.viewsPerDays = viewsPerDays;
} }
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
@Override @Override
public int describeContents() { public int describeContents() {
return 0; return 0;

View File

@ -56,6 +56,8 @@ public class CommentData {
private String url; private String url;
@SerializedName("videoId") @SerializedName("videoId")
private String videoId; private String videoId;
private boolean isReply = false;
private boolean isReplyViewOpen = false;
public AccountData.Account getAccount() { public AccountData.Account getAccount() {
@ -161,8 +163,63 @@ public class CommentData {
public void setVideoId(String videoId) { public void setVideoId(String videoId) {
this.videoId = videoId; this.videoId = videoId;
} }
public boolean isReply() {
return isReply;
} }
public void setReply(boolean reply) {
isReply = reply;
}
public boolean isReplyViewOpen() {
return isReplyViewOpen;
}
public void setReplyViewOpen(boolean replyViewOpen) {
isReplyViewOpen = replyViewOpen;
}
}
public static class CommentThreadData {
@SerializedName("comment")
public Comment comment;
@SerializedName("children")
public List<CommentThreadData> children;
public Comment getComment() {
return comment;
}
public void setComment(Comment comment) {
this.comment = comment;
}
public List<CommentThreadData> getChildren() {
return children;
}
public void setChildren(List<CommentThreadData> children) {
this.children = children;
}
}
public static class CommentPosted{
@SerializedName("comment")
private Comment comment;
public Comment getComment() {
return comment;
}
public void setComment(Comment comment) {
this.comment = comment;
}
}
public static class NotificationComment { public static class NotificationComment {
@SerializedName("id") @SerializedName("id")
private String id; private String id;

View File

@ -46,6 +46,8 @@ public class NotificationData {
private CommentData.NotificationComment comment; private CommentData.NotificationComment comment;
@SerializedName("videoAbuse") @SerializedName("videoAbuse")
private VideoAbuse videoAbuse; private VideoAbuse videoAbuse;
@SerializedName("abuse")
private VideoAbuse.Abuse abuse;
@SerializedName("videoBlacklist") @SerializedName("videoBlacklist")
private VideoBlacklist videoBlacklist; private VideoBlacklist videoBlacklist;
@SerializedName("account") @SerializedName("account")
@ -153,5 +155,13 @@ public class NotificationData {
public void setUpdatedAt(Date updatedAt) { public void setUpdatedAt(Date updatedAt) {
this.updatedAt = updatedAt; this.updatedAt = updatedAt;
} }
public VideoAbuse.Abuse getAbuse() {
return abuse;
}
public void setAbuse(VideoAbuse.Abuse abuse) {
this.abuse = abuse;
}
} }
} }

View File

@ -81,6 +81,8 @@ public class VideoData {
private int duration; private int duration;
@SerializedName("embedPath") @SerializedName("embedPath")
private String embedPath; private String embedPath;
@SerializedName("embedUrl")
private String embedUrl;
@SerializedName("files") @SerializedName("files")
private List<File> files; private List<File> files;
@SerializedName("id") @SerializedName("id")
@ -151,6 +153,7 @@ public class VideoData {
this.downloadEnabled = in.readByte() != 0; this.downloadEnabled = in.readByte() != 0;
this.duration = in.readInt(); this.duration = in.readInt();
this.embedPath = in.readString(); this.embedPath = in.readString();
this.embedUrl = in.readString();
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();
@ -349,6 +352,14 @@ public class VideoData {
this.embedPath = embedPath; this.embedPath = embedPath;
} }
public String getEmbedUrl() {
return embedUrl;
}
public void setEmbedUrl(String embedUrl) {
this.embedUrl = embedUrl;
}
public List<File> getFiles() { public List<File> getFiles() {
return files; return files;
} }
@ -585,6 +596,7 @@ public class VideoData {
dest.writeByte(this.downloadEnabled ? (byte) 1 : (byte) 0); dest.writeByte(this.downloadEnabled ? (byte) 1 : (byte) 0);
dest.writeInt(this.duration); dest.writeInt(this.duration);
dest.writeString(this.embedPath); dest.writeString(this.embedPath);
dest.writeString(this.embedUrl);
dest.writeList(this.files); dest.writeList(this.files);
dest.writeString(this.id); dest.writeString(this.id);
dest.writeByte(this.isLocal ? (byte) 1 : (byte) 0); dest.writeByte(this.isLocal ? (byte) 1 : (byte) 0);

View File

@ -131,4 +131,17 @@ public class Report {
this.id = id; this.id = id;
} }
} }
public static class ReportReturn {
@SerializedName("abuse")
private ItemStr reply;
public ItemStr getItemStr() {
return reply;
}
public void setItemStr(ItemStr itemStr) {
this.reply = itemStr;
}
}
} }

View File

@ -0,0 +1,217 @@
package app.fedilab.fedilabtube.client.entities;
/* 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.os.Parcel;
import android.os.Parcelable;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@SuppressWarnings("unused")
public class SepiaSearch implements Parcelable {
@SerializedName("start")
private String start;
@SerializedName("count")
private String count;
@SerializedName("search")
private String search;
@SerializedName("durationMax")
private int durationMax;
@SerializedName("durationMin")
private int durationMin;
@SerializedName("startDate")
private Date startDate;
@SerializedName("boostLanguages")
private List<String> boostLanguages;
@SerializedName("categoryOneOf")
private List<Integer> categoryOneOf;
@SerializedName("licenceOneOf")
private List<Integer> licenceOneOf;
@SerializedName("tagsOneOf")
private List<String> tagsOneOf;
@SerializedName("tagsAllOf")
private List<String> tagsAllOf;
@SerializedName("nsfw")
private boolean nsfw;
@SerializedName("sort")
private String sort;
public String getStart() {
return start;
}
public void setStart(String start) {
this.start = start;
}
public String getCount() {
return count;
}
public void setCount(String count) {
this.count = count;
}
public String getSearch() {
return search;
}
public void setSearch(String search) {
this.search = search;
}
public int getDurationMax() {
return durationMax;
}
public void setDurationMax(int durationMax) {
this.durationMax = durationMax;
}
public int getDurationMin() {
return durationMin;
}
public void setDurationMin(int durationMin) {
this.durationMin = durationMin;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public List<String> getBoostLanguages() {
return boostLanguages;
}
public void setBoostLanguages(List<String> boostLanguages) {
this.boostLanguages = boostLanguages;
}
public List<Integer> getCategoryOneOf() {
return categoryOneOf;
}
public void setCategoryOneOf(List<Integer> categoryOneOf) {
this.categoryOneOf = categoryOneOf;
}
public List<Integer> getLicenceOneOf() {
return licenceOneOf;
}
public void setLicenceOneOf(List<Integer> licenceOneOf) {
this.licenceOneOf = licenceOneOf;
}
public List<String> getTagsOneOf() {
return tagsOneOf;
}
public void setTagsOneOf(List<String> tagsOneOf) {
this.tagsOneOf = tagsOneOf;
}
public List<String> getTagsAllOf() {
return tagsAllOf;
}
public void setTagsAllOf(List<String> tagsAllOf) {
this.tagsAllOf = tagsAllOf;
}
public boolean isNsfw() {
return nsfw;
}
public void setNsfw(boolean nsfw) {
this.nsfw = nsfw;
}
public String getSort() {
return sort;
}
public void setSort(String sort) {
this.sort = sort;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.start);
dest.writeString(this.count);
dest.writeString(this.search);
dest.writeInt(this.durationMax);
dest.writeInt(this.durationMin);
dest.writeLong(this.startDate != null ? this.startDate.getTime() : -1);
dest.writeStringList(this.boostLanguages);
dest.writeList(this.categoryOneOf);
dest.writeList(this.licenceOneOf);
dest.writeStringList(this.tagsOneOf);
dest.writeStringList(this.tagsAllOf);
dest.writeByte(this.nsfw ? (byte) 1 : (byte) 0);
dest.writeString(this.sort);
}
public SepiaSearch() {
}
protected SepiaSearch(Parcel in) {
this.start = in.readString();
this.count = in.readString();
this.search = in.readString();
this.durationMax = in.readInt();
this.durationMin = in.readInt();
long tmpStartDate = in.readLong();
this.startDate = tmpStartDate == -1 ? null : new Date(tmpStartDate);
this.boostLanguages = in.createStringArrayList();
this.categoryOneOf = new ArrayList<>();
in.readList(this.categoryOneOf, Integer.class.getClassLoader());
this.licenceOneOf = new ArrayList<>();
in.readList(this.licenceOneOf, Integer.class.getClassLoader());
this.tagsOneOf = in.createStringArrayList();
this.tagsAllOf = in.createStringArrayList();
this.nsfw = in.readByte() != 0;
this.sort = in.readString();
}
public static final Creator<SepiaSearch> CREATOR = new Creator<SepiaSearch>() {
@Override
public SepiaSearch createFromParcel(Parcel source) {
return new SepiaSearch(source);
}
@Override
public SepiaSearch[] newArray(int size) {
return new SepiaSearch[size];
}
};
}

View File

@ -16,6 +16,7 @@ package app.fedilab.fedilabtube.client.entities;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import app.fedilab.fedilabtube.client.data.CommentData;
import app.fedilab.fedilabtube.client.data.VideoData; import app.fedilab.fedilabtube.client.data.VideoData;
@SuppressWarnings({"unused", "RedundantSuppression"}) @SuppressWarnings({"unused", "RedundantSuppression"})
@ -41,4 +42,38 @@ public class VideoAbuse {
public void setVideo(VideoData.Video video) { public void setVideo(VideoData.Video video) {
this.video = video; this.video = video;
} }
public static class Abuse{
@SerializedName("comment")
private CommentData.Comment comment;
@SerializedName("threadId")
private String threadId;
@SerializedName("id")
private String id;
public CommentData.Comment getComment() {
return comment;
}
public void setComment(CommentData.Comment comment) {
this.comment = comment;
}
public String getThreadId() {
return threadId;
}
public void setThreadId(String threadId) {
this.threadId = threadId;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
} }

View File

@ -17,8 +17,24 @@ package app.fedilab.fedilabtube.client.entities;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import java.util.List;
@SuppressWarnings({"unused", "RedundantSuppression"}) @SuppressWarnings({"unused", "RedundantSuppression"})
public class WellKnownNodeinfo { public class WellKnownNodeinfo {
@SerializedName("links")
private List<NodeInfoLinks> links;
public List<NodeInfoLinks> getLinks() {
return links;
}
public void setLinks(List<NodeInfoLinks> links) {
this.links = links;
}
public static class NodeInfoLinks {
@SerializedName("reel") @SerializedName("reel")
private String reel; private String reel;
@SerializedName("href") @SerializedName("href")
@ -39,6 +55,7 @@ public class WellKnownNodeinfo {
public void setHref(String href) { public void setHref(String href) {
this.href = href; this.href = href;
} }
}
public static class NodeInfo { public static class NodeInfo {
@SerializedName("version") @SerializedName("version")

View File

@ -31,18 +31,18 @@ import androidx.recyclerview.widget.RecyclerView;
import java.util.List; import java.util.List;
import app.fedilab.fedilabtube.R; import app.fedilab.fedilabtube.R;
import app.fedilab.fedilabtube.client.data.AccountData.Account; import app.fedilab.fedilabtube.client.data.ChannelData;
import app.fedilab.fedilabtube.helper.Helper; import app.fedilab.fedilabtube.helper.Helper;
public class AccountsHorizontalListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public class AccountsHorizontalListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
EventListener listener; EventListener listener;
private List<Account> accounts; private List<ChannelData.Channel> channels;
private Context context; private Context context;
public AccountsHorizontalListAdapter(List<Account> accounts, EventListener listener) { public AccountsHorizontalListAdapter(List<ChannelData.Channel> channels, EventListener listener) {
this.accounts = accounts; this.channels = channels;
this.listener = listener; this.listener = listener;
} }
@ -57,17 +57,17 @@ public class AccountsHorizontalListAdapter extends RecyclerView.Adapter<Recycler
@Override @Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) { public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
final AccountsHorizontalListAdapter.ViewHolder holder = (AccountsHorizontalListAdapter.ViewHolder) viewHolder; final AccountsHorizontalListAdapter.ViewHolder holder = (AccountsHorizontalListAdapter.ViewHolder) viewHolder;
final Account account = accounts.get(position); final ChannelData.Channel channel = channels.get(position);
if (account.getDisplayName() != null && !account.getDisplayName().trim().equals("")) if (channel.getDisplayName() != null && !channel.getDisplayName().trim().equals(""))
holder.account_dn.setText(account.getDisplayName()); holder.account_dn.setText(channel.getDisplayName());
else else
holder.account_dn.setText(account.getUsername().replace("@", "")); holder.account_dn.setText(channel.getName().replace("@", ""));
//Profile picture //Profile picture
Helper.loadGiF(context, account.getAvatar() != null ? account.getAvatar().getPath() : null, holder.account_pp, 270); Helper.loadGiF(context, channel.getAvatar() != null ? channel.getAvatar().getPath() : null, holder.account_pp, 270);
if (account.isSelected()) { if (channel.isSelected()) {
holder.main_container.setBackgroundColor(ColorUtils.setAlphaComponent(ContextCompat.getColor(context, Helper.getColorAccent()), 50)); holder.main_container.setBackgroundColor(ColorUtils.setAlphaComponent(ContextCompat.getColor(context, Helper.getColorAccent()), 50));
} else { } else {
holder.main_container.setBackgroundColor(Color.TRANSPARENT); holder.main_container.setBackgroundColor(Color.TRANSPARENT);
@ -82,7 +82,7 @@ public class AccountsHorizontalListAdapter extends RecyclerView.Adapter<Recycler
@Override @Override
public int getItemCount() { public int getItemCount() {
return accounts.size(); return channels.size();
} }
@ -106,16 +106,16 @@ public class AccountsHorizontalListAdapter extends RecyclerView.Adapter<Recycler
@Override @Override
public void onClick(View v) { public void onClick(View v) {
Account account = accounts.get(getAdapterPosition()); ChannelData.Channel channel = channels.get(getAdapterPosition());
listener.click(account.getId()); listener.click(channel.getAcct());
for (Account acc : accounts) { for (ChannelData.Channel acc : channels) {
if (acc.getId().compareTo(account.getId()) == 0) { if (acc.getId().compareTo(channel.getId()) == 0) {
acc.setSelected(true); acc.setSelected(true);
} else { } else {
acc.setSelected(false); acc.setSelected(false);
} }
} }
notifyItemRangeChanged(0, accounts.size()); notifyItemRangeChanged(0, channels.size());
} }
} }

View File

@ -48,10 +48,10 @@ import es.dmoral.toasty.Toasty;
public class AccountsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public class AccountsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public AllAccountsRemoved allAccountsRemoved; public AllAccountsRemoved allAccountsRemoved;
private List<Account> accounts; private final List<Account> accounts;
private Context context; private Context context;
private AccountsListAdapter accountsListAdapter; private final AccountsListAdapter accountsListAdapter;
private RetrofitPeertubeAPI.DataType type; private final RetrofitPeertubeAPI.DataType type;
public AccountsListAdapter(RetrofitPeertubeAPI.DataType type, List<Account> accounts) { public AccountsListAdapter(RetrofitPeertubeAPI.DataType type, List<Account> accounts) {
this.accounts = accounts; this.accounts = accounts;
@ -96,7 +96,8 @@ public class AccountsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
holder.account_pp.setOnClickListener(v -> { holder.account_pp.setOnClickListener(v -> {
Intent intent = new Intent(context, ShowAccountActivity.class); Intent intent = new Intent(context, ShowAccountActivity.class);
Bundle b = new Bundle(); Bundle b = new Bundle();
b.putParcelable("channel", account); b.putParcelable("account", account);
b.putString("accountAcct", account.getAcct());
intent.putExtras(b); intent.putExtras(b);
context.startActivity(intent); context.startActivity(intent);
}); });

View File

@ -46,12 +46,14 @@ public class ChannelListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
public AllChannelRemoved allChannelRemoved; public AllChannelRemoved allChannelRemoved;
public EditAlertDialog editAlertDialog; public EditAlertDialog editAlertDialog;
private List<Channel> channels; private final List<Channel> channels;
private Context context; private Context context;
private final boolean myChannel;
public ChannelListAdapter(List<Channel> channels) { public ChannelListAdapter(List<Channel> channels, boolean myChannel) {
this.channels = channels; this.channels = channels;
this.myChannel = myChannel;
} }
@NonNull @NonNull
@ -75,7 +77,9 @@ public class ChannelListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
//Profile picture //Profile picture
Helper.loadGiF(context, channel.getAvatar() != null ? channel.getAvatar().getPath() : null, holder.account_pp); Helper.loadGiF(context, channel.getAvatar() != null ? channel.getAvatar().getPath() : null, holder.account_pp);
if( !this.myChannel) {
holder.more_actions.setVisibility(View.GONE);
}
holder.more_actions.setOnClickListener(view -> { holder.more_actions.setOnClickListener(view -> {
PopupMenu popup = new PopupMenu(context, holder.more_actions); PopupMenu popup = new PopupMenu(context, holder.more_actions);
popup.getMenuInflater() popup.getMenuInflater()
@ -84,8 +88,8 @@ public class ChannelListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
popup.getMenu().findItem(R.id.action_delete).setEnabled(false); popup.getMenu().findItem(R.id.action_delete).setEnabled(false);
} }
popup.setOnMenuItemClickListener(item -> { popup.setOnMenuItemClickListener(item -> {
switch (item.getItemId()) { int itemId = item.getItemId();
case R.id.action_delete: if (itemId == R.id.action_delete) {
AlertDialog.Builder builder = new AlertDialog.Builder(context); AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(context.getString(R.string.delete_channel) + ": " + channel.getName()); builder.setTitle(context.getString(R.string.delete_channel) + ": " + channel.getName());
builder.setMessage(context.getString(R.string.action_channel_confirm_delete)); builder.setMessage(context.getString(R.string.action_channel_confirm_delete));
@ -107,12 +111,10 @@ public class ChannelListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
}) })
.setNegativeButton(R.string.no, (dialog, which) -> dialog.dismiss()) .setNegativeButton(R.string.no, (dialog, which) -> dialog.dismiss())
.show(); .show();
break; } else if (itemId == R.id.action_edit) {
case R.id.action_edit:
if (context instanceof AccountActivity) { if (context instanceof AccountActivity) {
editAlertDialog.show(channel); editAlertDialog.show(channel);
} }
break;
} }
return true; return true;
}); });

View File

@ -16,8 +16,11 @@ package app.fedilab.fedilabtube.drawer;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.text.Html; import android.text.Html;
@ -38,6 +41,7 @@ import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.widget.PopupMenu; import androidx.appcompat.widget.PopupMenu;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
@ -48,14 +52,23 @@ import java.util.List;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import app.fedilab.fedilabtube.PeertubeActivity;
import app.fedilab.fedilabtube.R; import app.fedilab.fedilabtube.R;
import app.fedilab.fedilabtube.ShowAccountActivity;
import app.fedilab.fedilabtube.ShowChannelActivity;
import app.fedilab.fedilabtube.client.APIResponse; import app.fedilab.fedilabtube.client.APIResponse;
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI; import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
import app.fedilab.fedilabtube.client.data.CommentData.Comment; import app.fedilab.fedilabtube.client.data.CommentData.Comment;
import app.fedilab.fedilabtube.client.entities.Report; import app.fedilab.fedilabtube.client.entities.Report;
import app.fedilab.fedilabtube.helper.EmojiHelper;
import app.fedilab.fedilabtube.helper.Helper; import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.viewmodel.PostActionsVM; import app.fedilab.fedilabtube.viewmodel.PostActionsVM;
import es.dmoral.toasty.Toasty; import es.dmoral.toasty.Toasty;
import studio.carbonylgroup.textfieldboxes.ExtendedEditText;
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.MUTE;
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.REPLY;
import static app.fedilab.fedilabtube.helper.Helper.isLoggedIn;
public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@ -63,12 +76,14 @@ public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
public AllCommentRemoved allCommentRemoved; public AllCommentRemoved allCommentRemoved;
private Context context; private Context context;
private List<Comment> comments; private final List<Comment> comments;
private CommentListAdapter commentListAdapter; private final CommentListAdapter commentListAdapter;
boolean isVideoOwner;
public CommentListAdapter(List<Comment> comments) { public CommentListAdapter(List<Comment> comments, boolean isVideoOwner) {
this.comments = comments; this.comments = comments;
commentListAdapter = this; commentListAdapter = this;
this.isVideoOwner = isVideoOwner;
} }
@Override @Override
@ -104,7 +119,7 @@ public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
if (comment == null) if (comment == null)
return; return;
holder.main_container.setTag(i);
holder.more_actions.setOnClickListener(view -> { holder.more_actions.setOnClickListener(view -> {
PopupMenu popup = new PopupMenu(context, holder.more_actions); PopupMenu popup = new PopupMenu(context, holder.more_actions);
@ -112,11 +127,23 @@ public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
.inflate(R.menu.comment_menu, popup.getMenu()); .inflate(R.menu.comment_menu, popup.getMenu());
if (!Helper.isOwner(context, comment.getAccount())) { if (!Helper.isOwner(context, comment.getAccount())) {
popup.getMenu().findItem(R.id.action_delete).setVisible(false); popup.getMenu().findItem(R.id.action_delete).setVisible(false);
}else {
popup.getMenu().findItem(R.id.action_mute).setVisible(false);
popup.getMenu().findItem(R.id.action_remove_comments).setVisible(false);
popup.getMenu().findItem(R.id.action_report).setVisible(false);
}
if( !isVideoOwner) {
popup.getMenu().findItem(R.id.action_remove_comments).setVisible(false);
}
if( !Helper.isLoggedIn(context)) {
popup.getMenu().findItem(R.id.action_mute).setVisible(false);
popup.getMenu().findItem(R.id.action_remove_comments).setVisible(false);
popup.getMenu().findItem(R.id.action_delete).setVisible(false);
} }
popup.setOnMenuItemClickListener(item -> { popup.setOnMenuItemClickListener(item -> {
switch (item.getItemId()) { int itemId = item.getItemId();
case R.id.action_delete: if (itemId == R.id.action_delete) {
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(context); AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.delete_comment); builder.setTitle(R.string.delete_comment);
builder.setMessage(R.string.delete_comment_confirm); builder.setMessage(R.string.delete_comment_confirm);
builder.setIcon(android.R.drawable.ic_dialog_alert) builder.setIcon(android.R.drawable.ic_dialog_alert)
@ -138,10 +165,40 @@ public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
}) })
.setNegativeButton(R.string.no, (dialog, which) -> dialog.dismiss()) .setNegativeButton(R.string.no, (dialog, which) -> dialog.dismiss())
.show(); .show();
break; } else if (itemId == R.id.action_report) {
case R.id.action_report:
reportComment(comment); reportComment(comment);
break; } else if (itemId == R.id.action_mute) {
PostActionsVM viewModel = new ViewModelProvider((ViewModelStoreOwner) context).get(PostActionsVM.class);
viewModel.post(MUTE, comment.getAccount().getAcct(), null).observe((LifecycleOwner) context, apiResponse -> manageVIewPostActions(MUTE, 0, apiResponse));
comments.remove(comment);
notifyDataSetChanged();
if (comments.size() == 0) {
allCommentRemoved.onAllCommentRemoved();
}
} else if (itemId == R.id.action_remove_comments) {
AlertDialog.Builder builder;
builder = new AlertDialog.Builder(context);
builder.setTitle(R.string.delete_account_comment);
builder.setMessage(R.string.delete_account_comment_confirm);
builder.setIcon(android.R.drawable.ic_dialog_alert)
.setPositiveButton(R.string.delete, (dialog, which) -> {
new Thread(() -> {
new RetrofitPeertubeAPI(context).post(RetrofitPeertubeAPI.ActionType.PEERTUBE_DELETE_ALL_COMMENT_FOR_ACCOUNT, comment.getAccount().getAcct(), "my-videos");
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> {
comments.remove(comment);
notifyDataSetChanged();
if (comments.size() == 0) {
allCommentRemoved.onAllCommentRemoved();
}
};
mainHandler.post(myRunnable);
}).start();
dialog.dismiss();
})
.setNegativeButton(R.string.no, (dialog, which) -> dialog.dismiss())
.show();
} }
return true; return true;
}); });
@ -159,15 +216,26 @@ public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
Spanned commentSpan; Spanned commentSpan;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
commentSpan = Html.fromHtml(comment.getText(), Html.FROM_HTML_MODE_LEGACY); commentSpan = Html.fromHtml(EmojiHelper.shortnameToUnicode(comment.getText()), Html.FROM_HTML_MODE_COMPACT);
else else
commentSpan = Html.fromHtml(comment.getText()); commentSpan = Html.fromHtml(EmojiHelper.shortnameToUnicode(comment.getText()));
holder.comment_content.setText(commentSpan, TextView.BufferType.SPANNABLE); holder.comment_content.setText(commentSpan, TextView.BufferType.SPANNABLE);
holder.comment_content.setMovementMethod(LinkMovementMethod.getInstance()); holder.comment_content.setMovementMethod(LinkMovementMethod.getInstance());
holder.comment_account_displayname.setText(comment.getAccount().getDisplayName()); holder.comment_account_displayname.setText(comment.getAccount().getDisplayName());
if( context instanceof PeertubeActivity && !comment.isReply()) {
holder.main_container.setOnClickListener(v -> ((PeertubeActivity) context).openCommentThread(comment, i));
holder.comment_content.setOnClickListener(v -> ((PeertubeActivity) context).openCommentThread(comment, i));
}
if( comment.getTotalReplies() > 0) {
holder.number_of_replies.setVisibility(View.VISIBLE);
holder.number_of_replies.setText(context.getResources().getQuantityString(R.plurals.number_of_replies, comment.getTotalReplies(), comment.getTotalReplies()));
} else {
holder.number_of_replies.setVisibility(View.GONE);
}
if (comment.getAccount() != null) { if (comment.getAccount() != null) {
Spannable wordtoSpan; Spannable wordtoSpan;
Pattern hashAcct; Pattern hashAcct;
@ -188,9 +256,50 @@ public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
Helper.loadGiF(context, comment.getAccount().getAvatar() != null ? comment.getAccount().getAvatar().getPath() : null, holder.comment_account_profile); Helper.loadGiF(context, comment.getAccount().getAvatar() != null ? comment.getAccount().getAvatar().getPath() : null, holder.comment_account_profile);
holder.comment_account_profile.setOnClickListener(v->{
Bundle b = new Bundle();
Intent intent = new Intent(context, ShowAccountActivity.class);
b.putParcelable("account", comment.getAccount());
b.putString("accountAcct", comment.getAccount().getAcct());
intent.putExtras(b);
context.startActivity(intent);
});
if(comment.isReply()) {
holder.replyButton.setVisibility(View.VISIBLE);
}else{
holder.replyButton.setVisibility(View.GONE);
}
if( comment.isReply() && comment.isReplyViewOpen()) {
holder.write_comment_container_reply.setVisibility(View.VISIBLE);
}else{
holder.write_comment_container_reply.setVisibility(View.GONE);
}
if( holder.add_comment_write_reply.getText() == null || holder.add_comment_write_reply.getText().toString().trim().length() == 0) {
holder.add_comment_write_reply.setText(String.format("@%s ", comment.getAccount().getAcct()));
holder.add_comment_write_reply.setSelection(holder.add_comment_write_reply.getText().length());
}
holder.replyButton.setOnClickListener(v->{
comment.setReplyViewOpen(!comment.isReplyViewOpen());
notifyItemChanged(i);
});
holder.send_reply.setOnClickListener(null);
holder.send_reply.setOnClickListener(v -> {
if (isLoggedIn(context)) {
String commentView = holder.add_comment_write_reply.getText().toString();
if (commentView.trim().length() > 0) {
PostActionsVM viewModelComment = new ViewModelProvider((ViewModelStoreOwner) context).get(PostActionsVM.class);
viewModelComment.comment(REPLY, comment.getVideoId(), comment.getId(), commentView).observe((LifecycleOwner) context, apiResponse1 -> manageVIewPostActions(REPLY, (int)holder.main_container.getTag(), apiResponse1));
holder.add_comment_write_reply.setText("");
comment.setReplyViewOpen(false);
notifyItemChanged(i);
}
}
});
} }
public void manageVIewPostActions(RetrofitPeertubeAPI.ActionType statusAction, APIResponse apiResponse) { public void manageVIewPostActions(RetrofitPeertubeAPI.ActionType statusAction, int i, APIResponse apiResponse) {
if (apiResponse.getError() != null) { if (apiResponse.getError() != null) {
Toasty.error(context, apiResponse.getError().getError(), Toast.LENGTH_LONG).show(); Toasty.error(context, apiResponse.getError().getError(), Toast.LENGTH_LONG).show();
@ -206,8 +315,15 @@ public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
} }
position++; position++;
} }
} else if (statusAction == REPLY) {
if( apiResponse.getComments() != null && apiResponse.getComments().size() > 0 ) {
comments.add(i+1, apiResponse.getComments().get(0));
notifyItemInserted(i+1);
}
}else if (statusAction == RetrofitPeertubeAPI.ActionType.REPORT_COMMENT) { }else if (statusAction == RetrofitPeertubeAPI.ActionType.REPORT_COMMENT) {
Toasty.success(context, context.getString(R.string.successful_report_comment), Toasty.LENGTH_LONG).show(); Toasty.success(context, context.getString(R.string.successful_report_comment), Toasty.LENGTH_LONG).show();
}else if (statusAction == MUTE) {
Toasty.info(context, context.getString(R.string.muted_done), Toast.LENGTH_LONG).show();
} }
} }
@ -229,7 +345,7 @@ public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
commentReport.setId(comment.getId()); commentReport.setId(comment.getId());
report.setComment(commentReport); report.setComment(commentReport);
report.setReason(report_content.getText().toString()); report.setReason(report_content.getText().toString());
viewModel.report(report).observe((LifecycleOwner) context, apiResponse -> manageVIewPostActions(RetrofitPeertubeAPI.ActionType.REPORT_COMMENT, apiResponse)); viewModel.report(report).observe((LifecycleOwner) context, apiResponse -> manageVIewPostActions(RetrofitPeertubeAPI.ActionType.REPORT_COMMENT, 0, apiResponse));
dialog.dismiss(); dialog.dismiss();
} }
}); });
@ -246,10 +362,13 @@ public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
TextView comment_content; TextView comment_content;
TextView comment_account_username; TextView comment_account_username;
TextView comment_account_displayname; TextView comment_account_displayname;
ImageView comment_account_profile; ImageView comment_account_profile, send_reply;
TextView comment_date; TextView comment_date, replyButton;
LinearLayout main_container; LinearLayout main_container;
TextView more_actions; TextView more_actions, number_of_replies;
ExtendedEditText add_comment_write_reply;
ConstraintLayout write_comment_container_reply;
@SuppressLint("SetJavaScriptEnabled") @SuppressLint("SetJavaScriptEnabled")
ViewHolder(View itemView) { ViewHolder(View itemView) {
@ -261,6 +380,11 @@ public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
comment_date = itemView.findViewById(R.id.comment_date); comment_date = itemView.findViewById(R.id.comment_date);
main_container = itemView.findViewById(R.id.main_container); main_container = itemView.findViewById(R.id.main_container);
more_actions = itemView.findViewById(R.id.more_actions); more_actions = itemView.findViewById(R.id.more_actions);
number_of_replies = itemView.findViewById(R.id.number_of_replies);
add_comment_write_reply = itemView.findViewById(R.id.add_comment_write_reply);
send_reply = itemView.findViewById(R.id.send_reply);
replyButton = itemView.findViewById(R.id.replyButton);
write_comment_container_reply = itemView.findViewById(R.id.write_comment_container_reply);
} }

View File

@ -58,6 +58,7 @@ import es.dmoral.toasty.Toasty;
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.FOLLOW; import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.FOLLOW;
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.UNFOLLOW; import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.UNFOLLOW;
import static app.fedilab.fedilabtube.viewmodel.TimelineVM.TimelineType.MY_VIDEOS; import static app.fedilab.fedilabtube.viewmodel.TimelineVM.TimelineType.MY_VIDEOS;
import static app.fedilab.fedilabtube.viewmodel.TimelineVM.TimelineType.SEPIA_SEARCH;
public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@ -67,13 +68,17 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
private List<VideoData.Video> videos; private List<VideoData.Video> videos;
private Context context; private Context context;
private TimelineVM.TimelineType timelineType; private TimelineVM.TimelineType timelineType;
private boolean sepiaSearch;
public PeertubeAdapter(List<VideoData.Video> videos, TimelineVM.TimelineType timelineType) {
public PeertubeAdapter(List<VideoData.Video> videos, TimelineVM.TimelineType timelineType, boolean sepiaSearch) {
this.videos = videos; this.videos = videos;
this.timelineType = timelineType; this.timelineType = timelineType;
this.sepiaSearch = sepiaSearch || timelineType == SEPIA_SEARCH;
} }
public PeertubeAdapter(List<VideoData.Video> videos) { public PeertubeAdapter(List<VideoData.Video> videos) {
this.videos = videos; this.videos = videos;
} }
@ -93,7 +98,9 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
final PeertubeAdapter.ViewHolder holder = (PeertubeAdapter.ViewHolder) viewHolder; final PeertubeAdapter.ViewHolder holder = (PeertubeAdapter.ViewHolder) viewHolder;
final VideoData.Video video = videos.get(position); final VideoData.Video video = videos.get(position);
if( video == null) {
return;
}
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, ""); String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, "");
@ -104,18 +111,23 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
if (timelineType == TimelineVM.TimelineType.MY_VIDEOS) { if (timelineType == TimelineVM.TimelineType.MY_VIDEOS) {
ownVideos = true; ownVideos = true;
} else { } else {
ownVideos = video.getAccount() != null && video.getAccount().getId() != null && video.getAccount().getHost().compareTo(Helper.getLiveInstance(context)) == 0 && video.getAccount().getId().compareTo(userId) == 0; ownVideos = Helper.isVideoOwner(context, video);
}
String instance = null;
if( sepiaSearch) {
instance = video.getAccount().getHost();
} }
holder.peertube_account_name.setText(video.getChannel().getAcct()); holder.peertube_account_name.setText(video.getChannel().getAcct());
Helper.loadGiF(context, video.getChannel().getAvatar() != null ? video.getChannel().getAvatar().getPath() : null, holder.peertube_profile); Helper.loadGiF(context, instance, video.getChannel().getAvatar() != null ? video.getChannel().getAvatar().getPath() : null, holder.peertube_profile);
holder.peertube_title.setText(video.getName()); holder.peertube_title.setText(video.getName());
holder.peertube_duration.setText(Helper.secondsToString(video.getDuration())); holder.peertube_duration.setText(Helper.secondsToString(video.getDuration()));
holder.peertube_date.setText(String.format(" - %s", Helper.dateDiff(context, video.getCreatedAt()))); holder.peertube_date.setText(String.format(" - %s", Helper.dateDiff(context, video.getCreatedAt())));
holder.peertube_views.setText(context.getString(R.string.number_view_video, Helper.withSuffix(video.getViews()))); holder.peertube_views.setText(context.getString(R.string.number_view_video, Helper.withSuffix(video.getViews())));
Helper.loadGiF(context, video.getThumbnailPath(), holder.peertube_video_image); Helper.loadGiF(context, instance, video.getThumbnailPath(), holder.peertube_video_image);
//For Overview Videos: boolean values for displaying title is managed in the fragment //For Overview Videos: boolean values for displaying title is managed in the fragment
if (video.isHasTitle()) { if (video.isHasTitle()) {
@ -138,6 +150,10 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
Intent intent = new Intent(context, ShowChannelActivity.class); Intent intent = new Intent(context, ShowChannelActivity.class);
Bundle b = new Bundle(); Bundle b = new Bundle();
b.putParcelable("channel", video.getChannel()); b.putParcelable("channel", video.getChannel());
b.putBoolean("sepia_search", sepiaSearch);
if( sepiaSearch) {
b.putString("peertube_instance", video.getAccount().getHost());
}
intent.putExtras(b); intent.putExtras(b);
context.startActivity(intent); context.startActivity(intent);
}); });
@ -245,6 +261,11 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
b.putString("video_id", video.getId()); b.putString("video_id", video.getId());
b.putString("video_uuid", video.getUuid()); b.putString("video_uuid", video.getUuid());
b.putBoolean("isMyVideo", ownVideos); b.putBoolean("isMyVideo", ownVideos);
b.putBoolean("sepia_search", sepiaSearch);
b.putParcelable("video", video);
if( sepiaSearch) {
b.putString("peertube_instance", video.getAccount().getHost());
}
intent.putExtras(b); intent.putExtras(b);
context.startActivity(intent); context.startActivity(intent);
}); });
@ -252,8 +273,13 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
Intent intent = new Intent(context, PeertubeActivity.class); Intent intent = new Intent(context, PeertubeActivity.class);
Bundle b = new Bundle(); Bundle b = new Bundle();
b.putString("video_id", video.getId()); b.putString("video_id", video.getId());
b.putParcelable("video", video);
b.putString("video_uuid", video.getUuid()); b.putString("video_uuid", video.getUuid());
b.putBoolean("isMyVideo", ownVideos); b.putBoolean("isMyVideo", ownVideos);
b.putBoolean("sepia_search", sepiaSearch);
if( sepiaSearch) {
b.putString("peertube_instance", video.getAccount().getHost());
}
intent.putExtras(b); intent.putExtras(b);
context.startActivity(intent); context.startActivity(intent);
}); });

View File

@ -46,7 +46,7 @@ import app.fedilab.fedilabtube.helper.Helper;
public class PeertubeNotificationsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { public class PeertubeNotificationsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context; private Context context;
private List<Notification> notifications; private final List<Notification> notifications;
public PeertubeNotificationsListAdapter(List<Notification> notifications) { public PeertubeNotificationsListAdapter(List<Notification> notifications) {
this.notifications = notifications; this.notifications = notifications;
@ -68,7 +68,7 @@ public class PeertubeNotificationsListAdapter extends RecyclerView.Adapter<Recyc
Notification notification = notifications.get(position); Notification notification = notifications.get(position);
//Follow Notification //Follow Notification
holder.peertube_notif_pp.setVisibility(View.VISIBLE);
AccountData.Account accountAction = null; AccountData.Account accountAction = null;
ChannelData.Channel channelAction = null; ChannelData.Channel channelAction = null;
if (notification.getActorFollow() != null) { if (notification.getActorFollow() != null) {
@ -77,7 +77,7 @@ public class PeertubeNotificationsListAdapter extends RecyclerView.Adapter<Recyc
Actor accountActionFollow = notification.getActorFollow().getFollower(); Actor accountActionFollow = notification.getActorFollow().getFollower();
String type = notification.getActorFollow().getFollowing().getType(); String type = notification.getActorFollow().getFollowing().getType();
String message; String message;
if (type != null && type.equals("account")) { if (type != null && type.compareTo("channel") == 0) {
message = context.getString(R.string.peertube_follow_channel, notification.getActorFollow().getFollower().getDisplayName(), notification.getActorFollow().getFollowing().getDisplayName()); message = context.getString(R.string.peertube_follow_channel, notification.getActorFollow().getFollower().getDisplayName(), notification.getActorFollow().getFollowing().getDisplayName());
} else { } else {
message = context.getString(R.string.peertube_follow_account, accountActionFollow.getDisplayName()); message = context.getString(R.string.peertube_follow_account, accountActionFollow.getDisplayName());
@ -86,13 +86,12 @@ public class PeertubeNotificationsListAdapter extends RecyclerView.Adapter<Recyc
holder.peertube_notif_message.setText(Html.fromHtml(message, Html.FROM_HTML_MODE_LEGACY)); holder.peertube_notif_message.setText(Html.fromHtml(message, Html.FROM_HTML_MODE_LEGACY));
else else
holder.peertube_notif_message.setText(Html.fromHtml(message)); holder.peertube_notif_message.setText(Html.fromHtml(message));
holder.peertube_notif_pp.setOnClickListener(v -> { Actor actor = notification.getActorFollow().getFollower();
Intent intent = new Intent(context, ShowChannelActivity.class); accountAction = new AccountData.Account();
Bundle b = new Bundle(); accountAction.setAvatar(actor.getAvatar());
b.putString("channelId", accountActionFollow.getName() + "@" + accountActionFollow.getHost()); accountAction.setDisplayName(actor.getDisplayName());
intent.putExtras(b); accountAction.setHost(actor.getHost());
context.startActivity(intent); accountAction.setUsername(actor.getName());
});
} else if (notification.getComment() != null) { //Comment Notification } else if (notification.getComment() != null) { //Comment Notification
String profileUrl = notification.getComment().getAccount().getAvatar() != null ? notification.getComment().getAccount().getAvatar().getPath() : null; String profileUrl = notification.getComment().getAccount().getAvatar() != null ? notification.getComment().getAccount().getAvatar().getPath() : null;
Helper.loadGiF(context, profileUrl, holder.peertube_notif_pp); Helper.loadGiF(context, profileUrl, holder.peertube_notif_pp);
@ -107,6 +106,7 @@ public class PeertubeNotificationsListAdapter extends RecyclerView.Adapter<Recyc
holder.peertube_notif_message.setOnClickListener(v -> { holder.peertube_notif_message.setOnClickListener(v -> {
Intent intent = new Intent(context, PeertubeActivity.class); Intent intent = new Intent(context, PeertubeActivity.class);
Bundle b = new Bundle(); Bundle b = new Bundle();
b.putParcelable("video", notification.getVideo());
b.putString("peertube_instance", finalAccountAction1.getHost()); b.putString("peertube_instance", finalAccountAction1.getHost());
b.putString("video_id", notification.getComment().getVideo().getId()); b.putString("video_id", notification.getComment().getVideo().getId());
b.putString("video_uuid", notification.getComment().getVideo().getUuid()); b.putString("video_uuid", notification.getComment().getVideo().getUuid());
@ -116,22 +116,26 @@ public class PeertubeNotificationsListAdapter extends RecyclerView.Adapter<Recyc
} else { } else {
String profileUrl = notification.getVideo() != null && notification.getVideo().getChannel().getAvatar() != null ? notification.getVideo().getChannel().getAvatar().getPath() : null; String profileUrl = notification.getVideo() != null && notification.getVideo().getChannel().getAvatar() != null ? notification.getVideo().getChannel().getAvatar().getPath() : null;
Helper.loadGiF(context, profileUrl, holder.peertube_notif_pp); Helper.loadGiF(context, profileUrl, holder.peertube_notif_pp);
String message = ""; String message = "";
boolean myVideo = false;
holder.peertube_notif_pp.setVisibility(View.INVISIBLE);
if (notification.getVideo() != null) { if (notification.getVideo() != null) {
if (notification.getType() == DisplayNotificationsFragment.MY_VIDEO_PUBLISHED) { if (notification.getType() == DisplayNotificationsFragment.MY_VIDEO_PUBLISHED) {
message = context.getString(R.string.peertube_video_published, notification.getVideo().getName()); message = context.getString(R.string.peertube_video_published, notification.getVideo().getName());
myVideo = true;
} else if (notification.getType() == DisplayNotificationsFragment.MY_VIDEO_IMPORT_ERROR) { } else if (notification.getType() == DisplayNotificationsFragment.MY_VIDEO_IMPORT_ERROR) {
message = context.getString(R.string.peertube_video_import_error, notification.getVideo().getName()); message = context.getString(R.string.peertube_video_import_error, notification.getVideo().getName());
myVideo = true;
} else if (notification.getType() == DisplayNotificationsFragment.MY_VIDEO_IMPORT_SUCCESS) { } else if (notification.getType() == DisplayNotificationsFragment.MY_VIDEO_IMPORT_SUCCESS) {
message = context.getString(R.string.peertube_video_import_success, notification.getVideo().getName()); message = context.getString(R.string.peertube_video_import_success, notification.getVideo().getName());
myVideo = true;
} else if (notification.getType() == DisplayNotificationsFragment.NEW_VIDEO_FROM_SUBSCRIPTION) { } else if (notification.getType() == DisplayNotificationsFragment.NEW_VIDEO_FROM_SUBSCRIPTION) {
channelAction = notification.getVideo().getChannel(); channelAction = notification.getVideo().getChannel();
message = context.getString(R.string.peertube_video_from_subscription, channelAction.getDisplayName(), notification.getVideo().getName()); message = context.getString(R.string.peertube_video_from_subscription, channelAction.getDisplayName(), notification.getVideo().getName());
holder.peertube_notif_pp.setVisibility(View.VISIBLE);
} else if (notification.getType() == DisplayNotificationsFragment.BLACKLIST_ON_MY_VIDEO) { } else if (notification.getType() == DisplayNotificationsFragment.BLACKLIST_ON_MY_VIDEO) {
message = context.getString(R.string.peertube_video_blacklist, notification.getVideo().getName()); message = context.getString(R.string.peertube_video_blacklist, notification.getVideo().getName());
} else if (notification.getType() == DisplayNotificationsFragment.UNBLACKLIST_ON_MY_VIDEO) { } else if (notification.getType() == DisplayNotificationsFragment.UNBLACKLIST_ON_MY_VIDEO) {
message = context.getString(R.string.peertube_video_unblacklist, notification.getVideo().getName()); message = context.getString(R.string.peertube_video_unblacklist, notification.getVideo().getName());
} }
@ -139,10 +143,13 @@ public class PeertubeNotificationsListAdapter extends RecyclerView.Adapter<Recyc
holder.peertube_notif_message.setText(Html.fromHtml(message, Html.FROM_HTML_MODE_LEGACY)); holder.peertube_notif_message.setText(Html.fromHtml(message, Html.FROM_HTML_MODE_LEGACY));
else else
holder.peertube_notif_message.setText(Html.fromHtml(message)); holder.peertube_notif_message.setText(Html.fromHtml(message));
boolean finalMyVideo = myVideo;
holder.peertube_notif_message.setOnClickListener(v -> { holder.peertube_notif_message.setOnClickListener(v -> {
Intent intent = new Intent(context, PeertubeActivity.class); Intent intent = new Intent(context, PeertubeActivity.class);
Bundle b = new Bundle(); Bundle b = new Bundle();
b.putParcelable("video", notification.getVideo());
b.putString("peertube_instance", Helper.getLiveInstance(context)); b.putString("peertube_instance", Helper.getLiveInstance(context));
b.putBoolean("isMyVideo", finalMyVideo);
b.putString("video_id", notification.getVideo().getId()); b.putString("video_id", notification.getVideo().getId());
b.putString("video_uuid", notification.getVideo().getUuid()); b.putString("video_uuid", notification.getVideo().getUuid());
intent.putExtras(b); intent.putExtras(b);
@ -154,10 +161,17 @@ public class PeertubeNotificationsListAdapter extends RecyclerView.Adapter<Recyc
holder.peertube_notif_message.setText(Html.fromHtml(message, Html.FROM_HTML_MODE_LEGACY)); holder.peertube_notif_message.setText(Html.fromHtml(message, Html.FROM_HTML_MODE_LEGACY));
else else
holder.peertube_notif_message.setText(Html.fromHtml(message)); holder.peertube_notif_message.setText(Html.fromHtml(message));
}else if (notification.getAbuse() != null){
if (notification.getType() == DisplayNotificationsFragment.MY_VIDEO_REPPORT_SUCCESS) {
message = context.getString(R.string.peertube_video_report_success, notification.getAbuse().getId());
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
holder.peertube_notif_message.setText(Html.fromHtml(message, Html.FROM_HTML_MODE_LEGACY));
else
holder.peertube_notif_message.setText(Html.fromHtml(message));
} }
} }
holder.peertube_notif_date.setText(Helper.dateDiff(context, notification.getCreatedAt())); holder.peertube_notif_date.setText(Helper.dateDiff(context, notification.getCreatedAt()));
AccountData.Account finalAccountAction = accountAction; AccountData.Account finalAccountAction = accountAction;
ChannelData.Channel finalChannelAction = channelAction; ChannelData.Channel finalChannelAction = channelAction;
holder.peertube_notif_pp.setOnClickListener(v -> { holder.peertube_notif_pp.setOnClickListener(v -> {
@ -165,7 +179,8 @@ public class PeertubeNotificationsListAdapter extends RecyclerView.Adapter<Recyc
Intent intent = null; Intent intent = null;
if (finalAccountAction != null) { if (finalAccountAction != null) {
intent = new Intent(context, ShowAccountActivity.class); intent = new Intent(context, ShowAccountActivity.class);
b.putString("channel", finalAccountAction.getAcct()); b.putParcelable("account", finalAccountAction);
b.putString("accountAcct", finalAccountAction.getUsername()+"@"+finalAccountAction.getHost());
} else if (finalChannelAction != null) { } else if (finalChannelAction != null) {
intent = new Intent(context, ShowChannelActivity.class); intent = new Intent(context, ShowChannelActivity.class);
b.putParcelable("channel", finalChannelAction); b.putParcelable("channel", finalChannelAction);

View File

@ -67,6 +67,7 @@ public class DisplayChannelsFragment extends Fragment implements ChannelListAdap
private RecyclerView lv_channels; private RecyclerView lv_channels;
private View rootView; private View rootView;
private FloatingActionButton action_button; private FloatingActionButton action_button;
private boolean myChannels;
@Override @Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
@ -76,8 +77,10 @@ public class DisplayChannelsFragment extends Fragment implements ChannelListAdap
context = getContext(); context = getContext();
Bundle bundle = this.getArguments(); Bundle bundle = this.getArguments();
channels = new ArrayList<>(); channels = new ArrayList<>();
myChannels = true;
if (bundle != null) { if (bundle != null) {
name = bundle.getString("name", null); name = bundle.getString("name", null);
myChannels = bundle.getBoolean("myChannels", true);
} }
swiped = false; swiped = false;
@ -86,9 +89,11 @@ public class DisplayChannelsFragment extends Fragment implements ChannelListAdap
if (getActivity() != null) { if (getActivity() != null) {
action_button = getActivity().findViewById(R.id.action_button); action_button = getActivity().findViewById(R.id.action_button);
if( action_button != null) {
action_button.setVisibility(View.VISIBLE); action_button.setVisibility(View.VISIBLE);
action_button.setOnClickListener(view -> manageAlert(null)); action_button.setOnClickListener(view -> manageAlert(null));
} }
}
lv_channels = rootView.findViewById(R.id.lv_elements); lv_channels = rootView.findViewById(R.id.lv_elements);
lv_channels.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL)); lv_channels.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL));
@ -97,7 +102,7 @@ public class DisplayChannelsFragment extends Fragment implements ChannelListAdap
textviewNoAction = rootView.findViewById(R.id.no_action); textviewNoAction = rootView.findViewById(R.id.no_action);
mainLoader.setVisibility(View.VISIBLE); mainLoader.setVisibility(View.VISIBLE);
nextElementLoader.setVisibility(View.GONE); nextElementLoader.setVisibility(View.GONE);
channelListAdapter = new ChannelListAdapter(this.channels); channelListAdapter = new ChannelListAdapter(this.channels, myChannels);
channelListAdapter.allChannelRemoved = this; channelListAdapter.allChannelRemoved = this;
channelListAdapter.editAlertDialog = this; channelListAdapter.editAlertDialog = this;
lv_channels.setAdapter(channelListAdapter); lv_channels.setAdapter(channelListAdapter);
@ -170,7 +175,7 @@ public class DisplayChannelsFragment extends Fragment implements ChannelListAdap
textviewNoAction.setVisibility(View.GONE); textviewNoAction.setVisibility(View.GONE);
if (swiped) { if (swiped) {
channelListAdapter = new ChannelListAdapter(this.channels); channelListAdapter = new ChannelListAdapter(this.channels, myChannels);
channelListAdapter.allChannelRemoved = DisplayChannelsFragment.this; channelListAdapter.allChannelRemoved = DisplayChannelsFragment.this;
channelListAdapter.editAlertDialog = DisplayChannelsFragment.this; channelListAdapter.editAlertDialog = DisplayChannelsFragment.this;
lv_channels.setAdapter(channelListAdapter); lv_channels.setAdapter(channelListAdapter);
@ -267,12 +272,16 @@ public class DisplayChannelsFragment extends Fragment implements ChannelListAdap
} }
channelListAdapter.notifyItemChanged(position); channelListAdapter.notifyItemChanged(position);
} }
if( action_button != null) {
action_button.setEnabled(true); action_button.setEnabled(true);
}
}; };
mainHandler.post(myRunnable); mainHandler.post(myRunnable);
}).start(); }).start();
alertDialog.dismiss(); alertDialog.dismiss();
if( action_button != null) {
action_button.setEnabled(false); action_button.setEnabled(false);
}
} else { } else {
Toasty.error(context, context.getString(R.string.error_display_name_channel), Toast.LENGTH_LONG).show(); Toasty.error(context, context.getString(R.string.error_display_name_channel), Toast.LENGTH_LONG).show();
} }

View File

@ -47,11 +47,12 @@ public class DisplayNotificationsFragment extends Fragment {
//Peertube notification type //Peertube notification type
public static int NEW_VIDEO_FROM_SUBSCRIPTION = 1; public static int NEW_VIDEO_FROM_SUBSCRIPTION = 1;
public static int BLACKLIST_ON_MY_VIDEO = 4;
public static int UNBLACKLIST_ON_MY_VIDEO = 5; public static int UNBLACKLIST_ON_MY_VIDEO = 5;
public static int BLACKLIST_ON_MY_VIDEO = 4;
public static int MY_VIDEO_PUBLISHED = 6; public static int MY_VIDEO_PUBLISHED = 6;
public static int MY_VIDEO_IMPORT_SUCCESS = 7; public static int MY_VIDEO_IMPORT_SUCCESS = 7;
public static int MY_VIDEO_IMPORT_ERROR = 8; public static int MY_VIDEO_IMPORT_ERROR = 8;
public static int MY_VIDEO_REPPORT_SUCCESS = 15;
private boolean flag_loading; private boolean flag_loading;
private Context context; private Context context;
private PeertubeNotificationsListAdapter peertubeNotificationsListAdapter; private PeertubeNotificationsListAdapter peertubeNotificationsListAdapter;

View File

@ -0,0 +1,329 @@
package app.fedilab.fedilabtube.fragment;
/* 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;
import android.content.SharedPreferences;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import app.fedilab.fedilabtube.BuildConfig;
import app.fedilab.fedilabtube.R;
import app.fedilab.fedilabtube.client.data.VideoData;
import app.fedilab.fedilabtube.client.entities.SepiaSearch;
import app.fedilab.fedilabtube.drawer.AccountsHorizontalListAdapter;
import app.fedilab.fedilabtube.drawer.PeertubeAdapter;
import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.viewmodel.SepiaSearchVM;
import es.dmoral.toasty.Toasty;
import static app.fedilab.fedilabtube.viewmodel.TimelineVM.TimelineType.SEPIA_SEARCH;
public class DisplaySepiaSearchFragment extends Fragment implements AccountsHorizontalListAdapter.EventListener {
private LinearLayoutManager mLayoutManager;
private GridLayoutManager gLayoutManager;
private boolean flag_loading;
private Context context;
private PeertubeAdapter peertubeAdapater;
private List<VideoData.Video> peertubes;
private RelativeLayout mainLoader, nextElementLoader, textviewNoAction;
private boolean firstLoad;
private SwipeRefreshLayout swipeRefreshLayout;
private SharedPreferences sharedpreferences;
private TextView textviewNoActionText;
private View rootView;
private RecyclerView lv_status;
private SepiaSearchVM viewModelSearch;
public DisplaySepiaSearchFragment() {
}
private SepiaSearch sepiaSearchVideo;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_video, container, false);
peertubes = new ArrayList<>();
context = getContext();
Bundle bundle = this.getArguments();
if (bundle != null) {
sepiaSearchVideo = bundle.getParcelable("sepiaSearchVideo");
}
lv_status = rootView.findViewById(R.id.lv_status);
flag_loading = true;
firstLoad = true;
assert context != null;
sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
swipeRefreshLayout = rootView.findViewById(R.id.swipeContainer);
mainLoader = rootView.findViewById(R.id.loader);
nextElementLoader = rootView.findViewById(R.id.loading_next_status);
textviewNoAction = rootView.findViewById(R.id.no_action);
textviewNoActionText = rootView.findViewById(R.id.no_action_text);
mainLoader.setVisibility(View.VISIBLE);
nextElementLoader.setVisibility(View.GONE);
peertubeAdapater = new PeertubeAdapter(this.peertubes, SEPIA_SEARCH, true);
lv_status.setAdapter(peertubeAdapater);
if (!Helper.isTablet(context)) {
mLayoutManager = new LinearLayoutManager(context);
lv_status.setLayoutManager(mLayoutManager);
} else {
gLayoutManager = new GridLayoutManager(context, 2);
int spanCount = (int) Helper.convertDpToPixel(2, context);
int spacing = (int) Helper.convertDpToPixel(5, context);
lv_status.addItemDecoration(new GridSpacingItemDecoration(spanCount, spacing, true));
lv_status.setLayoutManager(gLayoutManager);
}
viewModelSearch = new ViewModelProvider(DisplaySepiaSearchFragment.this).get(SepiaSearchVM.class);
swipeRefreshLayout.setOnRefreshListener(this::pullToRefresh);
lv_status.addOnScrollListener(new RecyclerView.OnScrollListener() {
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
if (mLayoutManager != null) {
int firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
if (dy > 0) {
int visibleItemCount = mLayoutManager.getChildCount();
int totalItemCount = mLayoutManager.getItemCount();
if (firstVisibleItem + visibleItemCount == totalItemCount && context != null) {
if (!flag_loading) {
flag_loading = true;
loadTimeline();
nextElementLoader.setVisibility(View.VISIBLE);
}
} else {
nextElementLoader.setVisibility(View.GONE);
}
}
} else if (gLayoutManager != null) {
int firstVisibleItem = gLayoutManager.findFirstVisibleItemPosition();
if (dy > 0) {
int visibleItemCount = gLayoutManager.getChildCount();
int totalItemCount = gLayoutManager.getItemCount();
if (firstVisibleItem + visibleItemCount == totalItemCount && context != null) {
if (!flag_loading) {
flag_loading = true;
loadTimeline();
nextElementLoader.setVisibility(View.VISIBLE);
}
} else {
nextElementLoader.setVisibility(View.GONE);
}
}
}
}
});
loadTimeline();
return rootView;
}
@Override
public void onPause() {
super.onPause();
if (swipeRefreshLayout != null) {
swipeRefreshLayout.setEnabled(false);
swipeRefreshLayout.setRefreshing(false);
swipeRefreshLayout.clearAnimation();
}
if (getActivity() != null) {
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null && getView() != null) {
imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
}
}
}
@Override
public void onCreate(Bundle saveInstance) {
super.onCreate(saveInstance);
}
@Override
public void onAttach(@NotNull Context context) {
super.onAttach(context);
this.context = context;
}
@Override
public void onStop() {
super.onStop();
}
@Override
public void onDestroy() {
super.onDestroy();
}
private void manageVIewVideos(VideoData videoData) {
//hide loaders
mainLoader.setVisibility(View.GONE);
nextElementLoader.setVisibility(View.GONE);
//handle other API error
if (videoData == null || videoData.data == null) {
Toasty.error(context, context.getString(R.string.toast_error), Toast.LENGTH_LONG).show();
swipeRefreshLayout.setRefreshing(false);
flag_loading = false;
return;
}
int previousPosition = this.peertubes.size();
int videoPerPage = sharedpreferences.getInt(Helper.SET_VIDEOS_PER_PAGE, Helper.VIDEOS_PER_PAGE);
sepiaSearchVideo.setStart(String.valueOf(Integer.parseInt(sepiaSearchVideo.getStart())+ videoPerPage));
if(!BuildConfig.google_restriction) {
this.peertubes.addAll(videoData.data);
}else{
for(VideoData.Video video: videoData.data) {
if ( video.getName() == null || !video.getName().toLowerCase().contains("youtube") || !video.getName().toLowerCase().contains("download")) {
this.peertubes.add(video);
}
}
}
//If no item were inserted previously the adapter is created
if (previousPosition == 0) {
peertubeAdapater = new PeertubeAdapter(this.peertubes, SEPIA_SEARCH, true);
lv_status.setAdapter(peertubeAdapater);
} else
peertubeAdapater.notifyItemRangeInserted(previousPosition, videoData.data.size());
//remove handlers
swipeRefreshLayout.setRefreshing(false);
textviewNoAction.setVisibility(View.GONE);
if (firstLoad && (videoData.data== null || videoData.data.size() == 0)) {
textviewNoActionText.setText(R.string.no_video_to_display);
textviewNoAction.setVisibility(View.VISIBLE);
}
flag_loading = false;
firstLoad = false;
}
@Override
public void onDestroyView() {
if (lv_status != null) {
try {
lv_status.setAdapter(null);
} catch (Exception ignored) {
}
}
super.onDestroyView();
rootView = null;
}
@Override
public void onResume() {
super.onResume();
swipeRefreshLayout.setEnabled(true);
}
public void scrollToTop() {
if (mLayoutManager != null) {
mLayoutManager.scrollToPositionWithOffset(0, 0);
} else if (gLayoutManager != null) {
gLayoutManager.scrollToPositionWithOffset(0, 0);
}
}
public void pullToRefresh() {
int size = peertubes.size();
peertubes.clear();
peertubes = new ArrayList<>();
peertubeAdapater.notifyItemRangeRemoved(0, size);
loadTimeline();
}
@Override
public void click(String forAccount) {
pullToRefresh();
}
private void loadTimeline() {
viewModelSearch.sepiaSearch(sepiaSearchVideo).observe(this.requireActivity(), this::manageVIewVideos);
}
static class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {
private int spanCount;
private int spacing;
private boolean includeEdge;
public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) {
this.spanCount = spanCount;
this.spacing = spacing;
this.includeEdge = includeEdge;
}
@Override
public void getItemOffsets(@NotNull Rect outRect, @NotNull View view, RecyclerView parent, @NotNull RecyclerView.State state) {
int position = parent.getChildAdapterPosition(view);
int column = position % spanCount;
if (includeEdge) {
outRect.left = spacing - column * spacing / spanCount;
outRect.right = (column + 1) * spacing / spanCount;
if (position < spanCount) {
outRect.top = spacing;
}
outRect.bottom = spacing;
} else {
outRect.left = column * spacing / spanCount;
outRect.right = spacing - (column + 1) * spacing / spanCount;
if (position >= spanCount) {
outRect.top = spacing;
}
}
}
}
}

View File

@ -29,8 +29,10 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout; import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
@ -44,10 +46,12 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import app.fedilab.fedilabtube.BuildConfig;
import app.fedilab.fedilabtube.MainActivity;
import app.fedilab.fedilabtube.R; import app.fedilab.fedilabtube.R;
import app.fedilab.fedilabtube.client.APIResponse; import app.fedilab.fedilabtube.client.APIResponse;
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI; import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
import app.fedilab.fedilabtube.client.data.AccountData.Account; import app.fedilab.fedilabtube.client.data.ChannelData;
import app.fedilab.fedilabtube.client.data.VideoData; import app.fedilab.fedilabtube.client.data.VideoData;
import app.fedilab.fedilabtube.client.data.VideoPlaylistData; import app.fedilab.fedilabtube.client.data.VideoPlaylistData;
import app.fedilab.fedilabtube.client.entities.PlaylistExist; import app.fedilab.fedilabtube.client.entities.PlaylistExist;
@ -73,7 +77,7 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
private AccountsHorizontalListAdapter accountsHorizontalListAdapter; private AccountsHorizontalListAdapter accountsHorizontalListAdapter;
private String max_id, max_id_accounts; private String max_id, max_id_accounts;
private List<VideoData.Video> peertubes; private List<VideoData.Video> peertubes;
private List<Account> accounts; private List<ChannelData.Channel> channels;
private TimelineVM.TimelineType type; private TimelineVM.TimelineType type;
private RelativeLayout mainLoader, nextElementLoader, textviewNoAction; private RelativeLayout mainLoader, nextElementLoader, textviewNoAction;
private boolean firstLoad; private boolean firstLoad;
@ -93,7 +97,8 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
private Map<String, Boolean> relationship; private Map<String, Boolean> relationship;
private Map<String, List<PlaylistExist>> playlists; private Map<String, List<PlaylistExist>> playlists;
private String playlistId; private String playlistId;
private String remoteInstance;
private boolean sepiaSearch;
public DisplayVideosFragment() { public DisplayVideosFragment() {
} }
@ -104,22 +109,23 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
peertubes = new ArrayList<>(); peertubes = new ArrayList<>();
accounts = new ArrayList<>(); channels = new ArrayList<>();
context = getContext(); context = getContext();
Bundle bundle = this.getArguments(); Bundle bundle = this.getArguments();
if (bundle != null) { if (bundle != null) {
search_peertube = bundle.getString("search_peertube", null); search_peertube = bundle.getString("search_peertube", null);
channelId = bundle.getString("channelId", null); channelId = bundle.getString("channelId", null);
remoteInstance = bundle.getString("peertube_instance", null);
sepiaSearch = bundle.getBoolean("sepia_search", false);
type = (TimelineVM.TimelineType) bundle.get(Helper.TIMELINE_TYPE); type = (TimelineVM.TimelineType) bundle.get(Helper.TIMELINE_TYPE);
playlistId = bundle.getString("playlistId", null); playlistId = bundle.getString("playlistId", null);
} }
max_id = "0"; max_id = "0";
forAccount = null; forAccount = type== TimelineVM.TimelineType.ACCOUNT_VIDEOS?channelId: null;
lv_status = rootView.findViewById(R.id.lv_status); lv_status = rootView.findViewById(R.id.lv_status);
RecyclerView lv_accounts = rootView.findViewById(R.id.lv_accounts); RecyclerView lv_accounts = rootView.findViewById(R.id.lv_accounts);
Button display_all = rootView.findViewById(R.id.display_all); Button display_all = rootView.findViewById(R.id.display_all);
top_account_container = rootView.findViewById(R.id.top_account_container); top_account_container = rootView.findViewById(R.id.top_account_container);
max_id = null;
max_id_accounts = null; max_id_accounts = null;
flag_loading = true; flag_loading = true;
firstLoad = true; firstLoad = true;
@ -136,12 +142,12 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
mainLoader.setVisibility(View.VISIBLE); mainLoader.setVisibility(View.VISIBLE);
nextElementLoader.setVisibility(View.GONE); nextElementLoader.setVisibility(View.GONE);
peertubeAdapater = new PeertubeAdapter(this.peertubes, type); peertubeAdapater = new PeertubeAdapter(this.peertubes, type, sepiaSearch);
peertubeAdapater.playlistListener = this; peertubeAdapater.playlistListener = this;
peertubeAdapater.relationShipListener = this; peertubeAdapater.relationShipListener = this;
lv_status.setAdapter(peertubeAdapater); lv_status.setAdapter(peertubeAdapater);
accountsHorizontalListAdapter = new AccountsHorizontalListAdapter(this.accounts, this); accountsHorizontalListAdapter = new AccountsHorizontalListAdapter(this.channels, this);
LinearLayoutManager layoutManager LinearLayoutManager layoutManager
= new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false); = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
lv_accounts.setLayoutManager(layoutManager); lv_accounts.setLayoutManager(layoutManager);
@ -159,7 +165,7 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
viewModelAccounts = new ViewModelProvider(DisplayVideosFragment.this).get(AccountsVM.class); viewModelAccounts = new ViewModelProvider(DisplayVideosFragment.this).get(AccountsVM.class);
viewModelFeeds = new ViewModelProvider(DisplayVideosFragment.this).get(TimelineVM.class); viewModelFeeds = new ViewModelProvider(DisplayVideosFragment.this).get(TimelineVM.class);
viewModelSearch = new ViewModelProvider(DisplayVideosFragment.this).get(SearchVM.class); viewModelSearch = new ViewModelProvider(DisplayVideosFragment.this).get(SearchVM.class);
swipeRefreshLayout.setOnRefreshListener(this::pullToRefresh); swipeRefreshLayout.setOnRefreshListener(() -> pullToRefresh(true));
lv_accounts.addOnScrollListener(new RecyclerView.OnScrollListener() { lv_accounts.addOnScrollListener(new RecyclerView.OnScrollListener() {
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
@ -233,7 +239,7 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
loadTimeline(max_id); loadTimeline(max_id);
display_all.setOnClickListener(v -> { display_all.setOnClickListener(v -> {
forAccount = null; forAccount = null;
pullToRefresh(); pullToRefresh(false);
}); });
return rootView; return rootView;
} }
@ -282,13 +288,13 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
private void manageViewAccounts(APIResponse apiResponse) { private void manageViewAccounts(APIResponse apiResponse) {
if (apiResponse != null && apiResponse.getAccounts() != null && apiResponse.getAccounts().size() > 0) { if (apiResponse != null && apiResponse.getChannels() != null && apiResponse.getChannels().size() > 0) {
if (top_account_container.getVisibility() == View.GONE) { if (top_account_container.getVisibility() == View.GONE) {
top_account_container.setVisibility(View.VISIBLE); top_account_container.setVisibility(View.VISIBLE);
} }
int previousPosition = accounts.size(); int previousPosition = channels.size();
accounts.addAll(apiResponse.getAccounts()); channels.addAll(apiResponse.getChannels());
accountsHorizontalListAdapter.notifyItemRangeInserted(previousPosition, apiResponse.getAccounts().size()); accountsHorizontalListAdapter.notifyItemRangeInserted(previousPosition, apiResponse.getChannels().size());
if (max_id_accounts == null) { if (max_id_accounts == null) {
max_id_accounts = "0"; max_id_accounts = "0";
} }
@ -329,10 +335,20 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
apiResponse.getPeertubes().add(v.getVideo()); apiResponse.getPeertubes().add(v.getVideo());
} }
} }
if(!BuildConfig.google_restriction) {
this.peertubes.addAll(apiResponse.getPeertubes()); this.peertubes.addAll(apiResponse.getPeertubes());
}else{
for(VideoData.Video video: apiResponse.getPeertubes()) {
if ( video.getName() == null || !video.getName().toLowerCase().contains("youtube") || !video.getName().toLowerCase().contains("download")) {
this.peertubes.add(video);
}
}
}
//If no item were inserted previously the adapter is created //If no item were inserted previously the adapter is created
if (previousPosition == 0) { if (previousPosition == 0) {
peertubeAdapater = new PeertubeAdapter(this.peertubes, type); peertubeAdapater = new PeertubeAdapter(this.peertubes, type, sepiaSearch);
peertubeAdapater.playlistListener = DisplayVideosFragment.this; peertubeAdapater.playlistListener = DisplayVideosFragment.this;
peertubeAdapater.relationShipListener = DisplayVideosFragment.this; peertubeAdapater.relationShipListener = DisplayVideosFragment.this;
lv_status.setAdapter(peertubeAdapater); lv_status.setAdapter(peertubeAdapater);
@ -351,8 +367,10 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
if (Helper.isLoggedIn(context)) { if (Helper.isLoggedIn(context)) {
List<String> uids = new ArrayList<>(); List<String> uids = new ArrayList<>();
for (VideoData.Video video : apiResponse.getPeertubes()) { for (VideoData.Video video : apiResponse.getPeertubes()) {
if( video != null) {
uids.add(video.getChannel().getName() + "@" + video.getChannel().getHost()); uids.add(video.getChannel().getName() + "@" + video.getChannel().getHost());
} }
}
if (uids.size() > 0 && !DisplayVideosFragment.this.isDetached()) { if (uids.size() > 0 && !DisplayVideosFragment.this.isDetached()) {
try { try {
RelationshipVM viewModel = new ViewModelProvider(this).get(RelationshipVM.class); RelationshipVM viewModel = new ViewModelProvider(this).get(RelationshipVM.class);
@ -363,8 +381,10 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
List<String> videoIds = new ArrayList<>(); List<String> videoIds = new ArrayList<>();
for (VideoData.Video video : apiResponse.getPeertubes()) { for (VideoData.Video video : apiResponse.getPeertubes()) {
if( video != null) {
videoIds.add(video.getId()); videoIds.add(video.getId());
} }
}
if (videoIds.size() > 0 && !DisplayVideosFragment.this.isDetached()) { if (videoIds.size() > 0 && !DisplayVideosFragment.this.isDetached()) {
try { try {
PlaylistsVM viewModel = new ViewModelProvider(this).get(PlaylistsVM.class); PlaylistsVM viewModel = new ViewModelProvider(this).get(PlaylistsVM.class);
@ -385,8 +405,10 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
} }
playlists.putAll(apiResponse.getVideoExistPlaylist()); playlists.putAll(apiResponse.getVideoExistPlaylist());
for (VideoData.Video video : peertubes) { for (VideoData.Video video : peertubes) {
if( video != null) {
video.setPlaylistExists(playlists.get(video.getId())); video.setPlaylistExists(playlists.get(video.getId()));
} }
}
} }
@ -428,25 +450,44 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
} }
public void pullToRefresh() { public void pullToRefresh(boolean reload) {
if( type == TimelineVM.TimelineType.SUBSCRIBTIONS && reload) {
Fragment fragment = ((AppCompatActivity)context).getSupportFragmentManager().findFragmentByTag("2");
if(fragment != null) {
if( context instanceof MainActivity) {
FragmentManager fm = ((MainActivity) context).getSupportFragmentManager();
fm.beginTransaction().remove(fragment).commit();
DisplayVideosFragment subscriptionFragment = new DisplayVideosFragment();
Bundle bundle = new Bundle();
bundle.putSerializable(Helper.TIMELINE_TYPE, TimelineVM.TimelineType.SUBSCRIBTIONS);
subscriptionFragment.setArguments(bundle);
((MainActivity) context).setActive(subscriptionFragment);
((MainActivity) context).setSubscriptionFragment(subscriptionFragment);
fm.beginTransaction().add(R.id.nav_host_fragment, subscriptionFragment, "2").commit();
}
}
}else {
int size = peertubes.size(); int size = peertubes.size();
peertubes.clear(); peertubes.clear();
peertubes = new ArrayList<>(); peertubes = new ArrayList<>();
max_id = "0"; max_id = "0";
peertubeAdapater.notifyItemRangeRemoved(0, size); peertubeAdapater.notifyItemRangeRemoved(0, size);
if (forAccount == null) { if (forAccount == null) {
for (Account account : accounts) { for (ChannelData.Channel channel : channels) {
account.setSelected(false); channel.setSelected(false);
} }
accountsHorizontalListAdapter.notifyItemRangeRemoved(0, accounts.size()); accountsHorizontalListAdapter.notifyItemRangeRemoved(0, channels.size());
} }
loadTimeline("0"); loadTimeline("0");
} }
}
@Override @Override
public void click(String forAccount) { public void click(String forAccount) {
this.forAccount = forAccount; this.forAccount = forAccount;
pullToRefresh(); pullToRefresh(false);
} }
/** /**
@ -456,13 +497,12 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
*/ */
private void loadTimeline(String max_id) { private void loadTimeline(String max_id) {
if (search_peertube == null) { //Not a Peertube search if (search_peertube == null) { //Not a Peertube search
if (type == TimelineVM.TimelineType.USER_VIDEOS) { if (type == TimelineVM.TimelineType.CHANNEL_VIDEOS) {
viewModelFeeds.getVideosInChannel(channelId, max_id).observe(this.requireActivity(), this::manageVIewVideos); viewModelFeeds.getVideosInChannel(sepiaSearch?remoteInstance:null, channelId, max_id).observe(this.requireActivity(), this::manageVIewVideos);
} else if (type == TimelineVM.TimelineType.VIDEOS_IN_PLAYLIST) { } else if (type == TimelineVM.TimelineType.VIDEOS_IN_PLAYLIST) {
viewModelFeeds.loadVideosInPlaylist(playlistId, max_id).observe(this.requireActivity(), this::manageVIewVideos); viewModelFeeds.loadVideosInPlaylist(playlistId, max_id).observe(this.requireActivity(), this::manageVIewVideos);
} else { } else {
viewModelFeeds.getVideos(type, max_id).observe(this.requireActivity(), this::manageVIewVideos); viewModelFeeds.getVideos(type, max_id, forAccount).observe(this.requireActivity(), this::manageVIewVideos);
} }
} else { } else {
viewModelSearch.getVideos(max_id, search_peertube).observe(this.requireActivity(), this::manageVIewVideos); viewModelSearch.getVideos(max_id, search_peertube).observe(this.requireActivity(), this::manageVIewVideos);
@ -483,9 +523,9 @@ public class DisplayVideosFragment extends Fragment implements AccountsHorizonta
static class GridSpacingItemDecoration extends RecyclerView.ItemDecoration { static class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {
private int spanCount; private final int spanCount;
private int spacing; private final int spacing;
private boolean includeEdge; private final boolean includeEdge;
public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) { public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) {
this.spanCount = spanCount; this.spanCount = spanCount;

View File

@ -22,6 +22,7 @@ import java.util.Set;
import app.fedilab.fedilabtube.R; import app.fedilab.fedilabtube.R;
import app.fedilab.fedilabtube.helper.Helper; import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.helper.ThemeHelper;
import es.dmoral.toasty.Toasty; import es.dmoral.toasty.Toasty;
import static app.fedilab.fedilabtube.MainActivity.peertubeInformation; import static app.fedilab.fedilabtube.MainActivity.peertubeInformation;
@ -89,6 +90,25 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
} }
} }
if (key.compareTo(getString(R.string.set_theme_choice)) == 0) {
ListPreference set_theme_choice = findPreference(getString(R.string.set_theme_choice));
if (set_theme_choice != null) {
int choice;
switch (set_theme_choice.getValue()) {
case "0":
choice = Helper.LIGHT_MODE;
break;
case "1":
choice = Helper.DARK_MODE;
break;
default:
choice = Helper.DEFAULT_MODE;
}
editor.putInt(Helper.SET_THEME, choice);
editor.apply();
ThemeHelper.switchTo(choice);
}
}
if (key.compareTo(getString(R.string.set_video_quality_choice)) == 0) { if (key.compareTo(getString(R.string.set_video_quality_choice)) == 0) {
ListPreference set_video_quality_choice = findPreference(getString(R.string.set_video_quality_choice)); ListPreference set_video_quality_choice = findPreference(getString(R.string.set_video_quality_choice));
if (set_video_quality_choice != null) { if (set_video_quality_choice != null) {
@ -137,12 +157,27 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
return; return;
} }
//****** App theme *******
ListPreference set_theme_choice = findPreference(getString(R.string.set_theme_choice));
List<String> arrayTheme = Arrays.asList(getResources().getStringArray(R.array.settings_theme));
CharSequence[] entriesTheme = arrayTheme.toArray(new CharSequence[0]);
CharSequence[] entryValuesTheme = new CharSequence[3];
final SharedPreferences sharedpref = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
int currentTheme = sharedpref.getInt(Helper.SET_THEME, Helper.DEFAULT_MODE);
entryValuesTheme[0] = String.valueOf(Helper.LIGHT_MODE);
entryValuesTheme[1] = String.valueOf(Helper.DARK_MODE);
entryValuesTheme[2] = String.valueOf(Helper.DEFAULT_MODE);
if (set_theme_choice != null) {
set_theme_choice.setEntries(entriesTheme);
set_theme_choice.setEntryValues(entryValuesTheme);
set_theme_choice.setValueIndex(currentTheme);
}
//****** Video mode ******* //****** Video mode *******
ListPreference set_video_mode_choice = findPreference(getString(R.string.set_video_mode_choice)); ListPreference set_video_mode_choice = findPreference(getString(R.string.set_video_mode_choice));
List<String> array = Arrays.asList(getResources().getStringArray(R.array.settings_video_mode)); List<String> array = Arrays.asList(getResources().getStringArray(R.array.settings_video_mode));
CharSequence[] entries = array.toArray(new CharSequence[0]); CharSequence[] entries = array.toArray(new CharSequence[0]);
CharSequence[] entryValues = new CharSequence[3]; CharSequence[] entryValues = new CharSequence[3];
final SharedPreferences sharedpref = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
int video_mode = sharedpref.getInt(Helper.SET_VIDEO_MODE, Helper.VIDEO_MODE_NORMAL); int video_mode = sharedpref.getInt(Helper.SET_VIDEO_MODE, Helper.VIDEO_MODE_NORMAL);
entryValues[0] = String.valueOf(Helper.VIDEO_MODE_NORMAL); entryValues[0] = String.valueOf(Helper.VIDEO_MODE_NORMAL);
entryValues[1] = String.valueOf(Helper.VIDEO_MODE_STREAMING); entryValues[1] = String.valueOf(Helper.VIDEO_MODE_STREAMING);

View File

@ -0,0 +1,78 @@
package app.fedilab.fedilabtube.helper;
/* 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;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class EmojiHelper {
//Emoji manager
private static final Map<String, String> emoji = new HashMap<>();
private static final Pattern SHORTNAME_PATTERN = Pattern.compile(":( |)([-+\\w]+):");
/**
* Converts emojis in input to unicode
* @param input String
* @return String
*/
public static String shortnameToUnicode(String input) {
Matcher matcher = SHORTNAME_PATTERN.matcher(input);
while (matcher.find()) {
String unicode = emoji.get(matcher.group(2));
if (unicode == null) {
continue;
}
if (matcher.group(1).equals(" "))
input = input.replace(": " + matcher.group(2) + ":", unicode);
else
input = input.replace(":" + matcher.group(2) + ":", unicode);
}
return input;
}
public static void fillMapEmoji(Context context) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(context.getAssets().open("emoji.csv")));
String line;
while( (line = br.readLine()) != null) {
String[] str = line.split(",");
String unicode = null;
if(str.length == 2)
unicode = new String(new int[] {Integer.parseInt(str[1].replace("0x","").trim(), 16)}, 0, 1);
else if(str.length == 3)
unicode = new String(new int[] {Integer.parseInt(str[1].replace("0x","").trim(), 16), Integer.parseInt(str[2].replace("0x","").trim(), 16)}, 0, 2);
else if(str.length == 4)
unicode = new String(new int[] {Integer.parseInt(str[1].replace("0x","").trim(), 16), Integer.parseInt(str[2].replace("0x","").trim(), 16), Integer.parseInt(str[3].replace("0x","").trim(), 16)}, 0, 3);
else if(str.length == 5)
unicode = new String(new int[] {Integer.parseInt(str[1].replace("0x","").trim(), 16), Integer.parseInt(str[2].replace("0x","").trim(), 16), Integer.parseInt(str[3].replace("0x","").trim(), 16), Integer.parseInt(str[4].replace("0x","").trim(), 16)}, 0, 4);
if( unicode != null)
emoji.put(str[0],unicode);
}
br.close();
} catch (IOException ignored) {ignored.printStackTrace();}
}
}

View File

@ -23,6 +23,8 @@ import android.widget.Button;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.MediaController; import android.widget.MediaController;
import androidx.core.content.res.ResourcesCompat;
import app.fedilab.fedilabtube.PeertubeActivity; import app.fedilab.fedilabtube.PeertubeActivity;
import app.fedilab.fedilabtube.R; import app.fedilab.fedilabtube.R;
import app.fedilab.fedilabtube.client.data.VideoData.Video; import app.fedilab.fedilabtube.client.data.VideoData.Video;
@ -36,7 +38,7 @@ public class FullScreenMediaController extends MediaController {
private ImageButton fullScreen; private ImageButton fullScreen;
private Button resolution; private Button resolution;
private Context context; private final Context context;
private Video peertube; private Video peertube;
private String resolutionVal; private String resolutionVal;
@ -85,12 +87,11 @@ public class FullScreenMediaController extends MediaController {
if (((PeertubeActivity) getContext()).getFullscreen() == fullscreen.ON) { if (((PeertubeActivity) getContext()).getFullscreen() == fullscreen.ON) {
Resources resources = getResources(); Resources resources = getResources();
fullScreen.setImageDrawable(resources.getDrawable(R.drawable.ic_baseline_fullscreen_exit_24)); fullScreen.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_baseline_fullscreen_exit_24, null));
} else { } else {
Resources resources = getResources(); Resources resources = getResources();
fullScreen.setImageDrawable(resources.getDrawable(R.drawable.ic_baseline_fullscreen_24)); fullScreen.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_baseline_fullscreen_24, null));
} }
//add listener to image button to handle full screen and exit full screen events //add listener to image button to handle full screen and exit full screen events
fullScreen.setOnClickListener(v -> { fullScreen.setOnClickListener(v -> {
@ -115,10 +116,10 @@ public class FullScreenMediaController extends MediaController {
//fullscreen indicator from intent //fullscreen indicator from intent
if (((PeertubeActivity) getContext()).getFullscreen() == fullscreen.ON) { if (((PeertubeActivity) getContext()).getFullscreen() == fullscreen.ON) {
Resources resources = getResources(); Resources resources = getResources();
fullScreen.setImageDrawable(resources.getDrawable(R.drawable.ic_baseline_fullscreen_exit_24)); fullScreen.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_baseline_fullscreen_exit_24, null));
} else { } else {
Resources resources = getResources(); Resources resources = getResources();
fullScreen.setImageDrawable(resources.getDrawable(R.drawable.ic_baseline_fullscreen_24)); fullScreen.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_baseline_fullscreen_24, null));
} }
} }

View File

@ -58,6 +58,8 @@ import app.fedilab.fedilabtube.MainActivity;
import app.fedilab.fedilabtube.R; import app.fedilab.fedilabtube.R;
import app.fedilab.fedilabtube.WebviewActivity; import app.fedilab.fedilabtube.WebviewActivity;
import app.fedilab.fedilabtube.client.data.AccountData.Account; import app.fedilab.fedilabtube.client.data.AccountData.Account;
import app.fedilab.fedilabtube.client.data.ChannelData;
import app.fedilab.fedilabtube.client.data.VideoData;
import app.fedilab.fedilabtube.client.entities.File; import app.fedilab.fedilabtube.client.entities.File;
import app.fedilab.fedilabtube.sqlite.AccountDAO; import app.fedilab.fedilabtube.sqlite.AccountDAO;
import app.fedilab.fedilabtube.sqlite.Sqlite; import app.fedilab.fedilabtube.sqlite.Sqlite;
@ -72,7 +74,11 @@ public class Helper {
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";
public static final String TIMELINE_TYPE = Helper.TIMELINE_TYPE; public static final String SET_THEME = "set_theme";
public static final int LIGHT_MODE = 0;
public static final int DARK_MODE = 1;
public static final int DEFAULT_MODE = 2;
public static final String TIMELINE_TYPE = "timeline_type";
public static final int VIDEO_MODE_NORMAL = 0; public static final int VIDEO_MODE_NORMAL = 0;
public static final int VIDEO_MODE_STREAMING = 2; public static final int VIDEO_MODE_STREAMING = 2;
public static final int VIDEO_MODE_WEBVIEW = 1; public static final int VIDEO_MODE_WEBVIEW = 1;
@ -234,7 +240,7 @@ public class Helper {
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE); final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
String acad; String acad;
if (BuildConfig.full_instances) { if (BuildConfig.full_instances) {
return sharedpreferences.getString(Helper.PREF_INSTANCE, "peertube.social"); return sharedpreferences.getString(Helper.PREF_INSTANCE, getDefaultInstance());
} else { } else {
acad = sharedpreferences.getString(Helper.PREF_INSTANCE, "tube.ac-lyon.fr"); acad = sharedpreferences.getString(Helper.PREF_INSTANCE, "tube.ac-lyon.fr");
if (acad == null) { if (acad == null) {
@ -248,6 +254,49 @@ public class Helper {
} }
} }
/**
* Get a default instance host name depending of the device locale
* @return peertube host String
*/
private static String getDefaultInstance() {
String lang = Locale.getDefault().getLanguage();
if (lang.contains("-")) {
if (!lang.split("-")[0].trim().toLowerCase().startsWith("zh")) {
lang = lang.split("-")[0];
if(lang.split("-")[1].toLowerCase().contains("be")){
lang = "be";
}
else if(lang.split("-")[1].toLowerCase().contains("gb")){
lang = "gb";
}
} else {
lang = lang.split("-")[0] + "-" + lang.split("-")[1].toUpperCase();
}
}
switch (lang){
case "it":
return "peertube.uno";
case "be":
return "peertube.be";
case "fr":
return "video.liberta.vip";
case "de":
return "peertube.at";
case "ru":
return "peertube.su";
case "gb":
return "peertube.co.uk";
case "da":
case "sv":
case "nb":
case "fi":
case "is":
return "peertube.dk";
default:
return "peertube.social";
}
}
/** /**
* Convert a date in String -> format yyyy-MM-dd HH:mm:ss * Convert a date in String -> format yyyy-MM-dd HH:mm:ss
* *
@ -287,6 +336,11 @@ public class Helper {
} }
/**
* Convert second to String formated date
* @param pTime timestamp
* @return String formatted value
*/
public static String secondsToString(int pTime) { public static String secondsToString(int pTime) {
int hour = pTime / 3600; int hour = pTime / 3600;
@ -347,6 +401,11 @@ public class Helper {
} }
/**
* Return rounded numbers depending of the value
* @param count long
* @return String rounded value to be displayed
*/
public static String withSuffix(long count) { public static String withSuffix(long count) {
if (count < 1000) return "" + count; if (count < 1000) return "" + count;
int exp = (int) (Math.log(count) / Math.log(1000)); int exp = (int) (Math.log(count) / Math.log(1000));
@ -370,8 +429,17 @@ public class Helper {
loadGiF(context, url, imageView, 10); loadGiF(context, url, imageView, 10);
} }
public static void loadGiF(final Context context, String instance, String url, final ImageView imageView) {
loadGif(context, instance, url, imageView, 10);
}
public static void loadGiF(final Context context, String url, final ImageView imageView, int round) { public static void loadGiF(final Context context, String url, final ImageView imageView, int round) {
if (url == null || url.trim().toLowerCase().compareTo("null") == 0) { loadGif(context, null, url, imageView, round);
}
@SuppressWarnings("SameParameterValue")
private static void loadGif(final Context context, String instance, String url, final ImageView imageView, int round) {
if (url == null || url.trim().toLowerCase().compareTo("null") == 0 || url.endsWith("null")) {
Glide.with(imageView.getContext()) Glide.with(imageView.getContext())
.asDrawable() .asDrawable()
.load(R.drawable.missing_peertube) .load(R.drawable.missing_peertube)
@ -380,7 +448,7 @@ public class Helper {
return; return;
} }
if (url.startsWith("/")) { if (url.startsWith("/")) {
url = Helper.getLiveInstance(context) + url; url = instance!=null?instance+ url:Helper.getLiveInstance(context) + url;
} }
if (!url.startsWith("http")) { if (!url.startsWith("http")) {
url = "https://" + url; url = "https://" + url;
@ -405,6 +473,13 @@ public class Helper {
} }
/**
* Initialize the webview
* @param activity Current Activity
* @param webviewId int id of the webview layout
* @param rootView View the root view
* @return CustomWebview
*/
@SuppressLint("SetJavaScriptEnabled") @SuppressLint("SetJavaScriptEnabled")
public static CustomWebview initializeWebview(Activity activity, int webviewId, View rootView) { public static CustomWebview initializeWebview(Activity activity, int webviewId, View rootView) {
@ -564,7 +639,7 @@ public class Helper {
} }
public static int getColorAccent() { public static int getColorAccent() {
return BuildConfig.full_instances ? R.color.colorAccent_full : R.color.colorAccent; return R.color.colorAccent;
} }
@ -579,6 +654,21 @@ public class Helper {
} }
} }
public static boolean isVideoOwner(Context context, VideoData.Video video) {
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
String userName = sharedpreferences.getString(Helper.PREF_KEY_NAME, "");
String instance = sharedpreferences.getString(Helper.PREF_INSTANCE, "");
Account account = video.getAccount();
ChannelData.Channel channel = video.getChannel();
if (account != null && instance != null && userName != null) {
return account.getUsername().compareTo(userName) == 0 && account.getHost().compareTo(instance) == 0;
} else if (channel != null && instance != null && userName != null) {
return channel.getName().compareTo(userName) == 0 && channel.getHost().compareTo(instance) == 0;
} else {
return false;
}
}
/*** /***
* Return a File depending of the requested quality * Return a File depending of the requested quality
* @param context Context * @param context Context

View File

@ -12,8 +12,8 @@ import app.fedilab.fedilabtube.R;
public class RoundedBackgroundSpan extends ReplacementSpan { public class RoundedBackgroundSpan extends ReplacementSpan {
private int backgroundColor; private final int backgroundColor;
private int textColor; private final int textColor;
public RoundedBackgroundSpan(Context context) { public RoundedBackgroundSpan(Context context) {
super(); super();

View File

@ -0,0 +1,46 @@
package app.fedilab.fedilabtube.helper;
/* 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.os.Build;
import androidx.appcompat.app.AppCompatDelegate;
import static app.fedilab.fedilabtube.helper.Helper.DARK_MODE;
import static app.fedilab.fedilabtube.helper.Helper.LIGHT_MODE;
public class ThemeHelper {
public static void switchTo(int themePref) {
switch (themePref) {
case LIGHT_MODE: {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
break;
}
case DARK_MODE: {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
break;
}
default: {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY);
}
break;
}
}
}
}

View File

@ -33,6 +33,7 @@ import java.util.Objects;
import app.fedilab.fedilabtube.R; import app.fedilab.fedilabtube.R;
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI; import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
import app.fedilab.fedilabtube.client.entities.PeertubeInformation; import app.fedilab.fedilabtube.client.entities.PeertubeInformation;
import app.fedilab.fedilabtube.helper.EmojiHelper;
import app.fedilab.fedilabtube.helper.NetworkStateReceiver; import app.fedilab.fedilabtube.helper.NetworkStateReceiver;
import static app.fedilab.fedilabtube.MainActivity.peertubeInformation; import static app.fedilab.fedilabtube.MainActivity.peertubeInformation;
@ -55,8 +56,6 @@ public class RetrieveInfoService extends Service implements NetworkStateReceiver
@Override @Override
public int onStartCommand(Intent intent, int flags, int startId) { public int onStartCommand(Intent intent, int flags, int startId) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
getString(R.string.notification_channel_name), getString(R.string.notification_channel_name),
@ -88,6 +87,7 @@ public class RetrieveInfoService extends Service implements NetworkStateReceiver
@Override @Override
public void run() { public void run() {
EmojiHelper.fillMapEmoji(getApplicationContext());
peertubeInformation = new PeertubeInformation(); peertubeInformation = new PeertubeInformation();
peertubeInformation.setCategories(new LinkedHashMap<>()); peertubeInformation.setCategories(new LinkedHashMap<>());
peertubeInformation.setLanguages(new LinkedHashMap<>()); peertubeInformation.setLanguages(new LinkedHashMap<>());
@ -97,11 +97,9 @@ public class RetrieveInfoService extends Service implements NetworkStateReceiver
peertubeInformation.setTranslations(new LinkedHashMap<>()); peertubeInformation.setTranslations(new LinkedHashMap<>());
peertubeInformation = new RetrofitPeertubeAPI(RetrieveInfoService.this).getPeertubeInformation(); peertubeInformation = new RetrofitPeertubeAPI(RetrieveInfoService.this).getPeertubeInformation();
stopForeground(true); stopForeground(true);
} }
}; };
thread.start(); thread.start();
return START_NOT_STICKY; return START_NOT_STICKY;
} }
@ -128,6 +126,7 @@ public class RetrieveInfoService extends Service implements NetworkStateReceiver
@Override @Override
public void run() { public void run() {
EmojiHelper.fillMapEmoji(getApplicationContext());
peertubeInformation = new PeertubeInformation(); peertubeInformation = new PeertubeInformation();
peertubeInformation.setCategories(new LinkedHashMap<>()); peertubeInformation.setCategories(new LinkedHashMap<>());
peertubeInformation.setLanguages(new LinkedHashMap<>()); peertubeInformation.setLanguages(new LinkedHashMap<>());

View File

@ -34,7 +34,7 @@ import app.fedilab.fedilabtube.helper.Helper;
public class AccountDAO { public class AccountDAO {
public Context context; public Context context;
private SQLiteDatabase db; private final SQLiteDatabase db;
public AccountDAO(Context context, SQLiteDatabase db) { public AccountDAO(Context context, SQLiteDatabase db) {

View File

@ -41,6 +41,12 @@ public class AccountsVM extends AndroidViewModel {
return apiResponseMutableLiveData; return apiResponseMutableLiveData;
} }
public LiveData<APIResponse> getAccount(String acct) {
apiResponseMutableLiveData = new MutableLiveData<>();
loadAccount(acct);
return apiResponseMutableLiveData;
}
private void loadAccounts(RetrofitPeertubeAPI.DataType dataType, String element) { private void loadAccounts(RetrofitPeertubeAPI.DataType dataType, String element) {
Context _mContext = getApplication().getApplicationContext(); Context _mContext = getApplication().getApplicationContext();
new Thread(() -> { new Thread(() -> {
@ -62,4 +68,18 @@ public class AccountsVM extends AndroidViewModel {
}).start(); }).start();
} }
private void loadAccount(String acct) {
Context _mContext = getApplication().getApplicationContext();
new Thread(() -> {
try {
RetrofitPeertubeAPI retrofitPeertubeAPI = new RetrofitPeertubeAPI(_mContext);
APIResponse apiResponse = retrofitPeertubeAPI.getAccount(acct);
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse);
mainHandler.post(myRunnable);
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
} }

View File

@ -35,18 +35,23 @@ public class CaptionsVM extends AndroidViewModel {
super(application); super(application);
} }
public LiveData<APIResponse> getCaptions(String videoId) { public LiveData<APIResponse> getCaptions(String instance, String videoId) {
apiResponseMutableLiveData = new MutableLiveData<>(); apiResponseMutableLiveData = new MutableLiveData<>();
loadCaptions(videoId); loadCaptions(instance, videoId);
return apiResponseMutableLiveData; return apiResponseMutableLiveData;
} }
private void loadCaptions(String videoId) { private void loadCaptions(String instance, String videoId) {
Context _mContext = getApplication().getApplicationContext(); Context _mContext = getApplication().getApplicationContext();
new Thread(() -> { new Thread(() -> {
try { try {
RetrofitPeertubeAPI peertubeAPI = new RetrofitPeertubeAPI(_mContext); RetrofitPeertubeAPI retrofitPeertubeAPI;
APIResponse apiResponse = peertubeAPI.getCaptions(videoId); if( instance == null) {
retrofitPeertubeAPI = new RetrofitPeertubeAPI(_mContext);
}else{
retrofitPeertubeAPI = new RetrofitPeertubeAPI(_mContext, instance, null);
}
APIResponse apiResponse = retrofitPeertubeAPI.getCaptions(videoId);
Handler mainHandler = new Handler(Looper.getMainLooper()); Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse); Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse);
mainHandler.post(myRunnable); mainHandler.post(myRunnable);

View File

@ -43,13 +43,19 @@ public class ChannelsVM extends AndroidViewModel {
super(application); super(application);
} }
public LiveData<APIResponse> get(RetrofitPeertubeAPI.DataType type, String element) { public LiveData<APIResponse> get(String instance, RetrofitPeertubeAPI.DataType type, String element) {
apiResponseMutableLiveData = new MutableLiveData<>(); apiResponseMutableLiveData = new MutableLiveData<>();
getChannels(type, element); getChannels(instance, type, element);
return apiResponseMutableLiveData; return apiResponseMutableLiveData;
} }
private void getChannels(RetrofitPeertubeAPI.DataType type, String element) { public LiveData<APIResponse> get(RetrofitPeertubeAPI.DataType type, String element) {
apiResponseMutableLiveData = new MutableLiveData<>();
getChannels(null, type, element);
return apiResponseMutableLiveData;
}
private void getChannels(String instance, RetrofitPeertubeAPI.DataType type, String element) {
Context _mContext = getApplication().getApplicationContext(); Context _mContext = getApplication().getApplicationContext();
new Thread(() -> { new Thread(() -> {
String finalElement = element; String finalElement = element;
@ -61,7 +67,12 @@ public class ChannelsVM extends AndroidViewModel {
AccountData.Account account = new AccountDAO(_mContext, db).getAccountByToken(token); AccountData.Account account = new AccountDAO(_mContext, db).getAccountByToken(token);
finalElement = account.getUsername() + "@" + account.getHost(); finalElement = account.getUsername() + "@" + account.getHost();
} }
RetrofitPeertubeAPI retrofitPeertubeAPI = new RetrofitPeertubeAPI(_mContext); RetrofitPeertubeAPI retrofitPeertubeAPI;
if( instance == null ) {
retrofitPeertubeAPI = new RetrofitPeertubeAPI(_mContext);
} else {
retrofitPeertubeAPI = new RetrofitPeertubeAPI(_mContext, instance, null);
}
APIResponse apiResponse = retrofitPeertubeAPI.getChannelData(type, finalElement); APIResponse apiResponse = retrofitPeertubeAPI.getChannelData(type, finalElement);
Handler mainHandler = new Handler(Looper.getMainLooper()); Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse); Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse);

View File

@ -35,9 +35,9 @@ public class CommentVM extends AndroidViewModel {
super(application); super(application);
} }
public LiveData<APIResponse> getThread(String videoId, String max_Id) { public LiveData<APIResponse> getThread(String instance, String videoId, String max_Id) {
apiResponseMutableLiveData = new MutableLiveData<>(); apiResponseMutableLiveData = new MutableLiveData<>();
getThreadComments(videoId, max_Id); getThreadComments(instance, videoId, max_Id);
return apiResponseMutableLiveData; return apiResponseMutableLiveData;
} }
@ -48,12 +48,17 @@ public class CommentVM extends AndroidViewModel {
} }
private void getThreadComments(String videoId, String max_id) { private void getThreadComments(String instance, String videoId, String max_id) {
Context _mContext = getApplication().getApplicationContext(); Context _mContext = getApplication().getApplicationContext();
new Thread(() -> { new Thread(() -> {
try { try {
RetrofitPeertubeAPI api = new RetrofitPeertubeAPI(_mContext); RetrofitPeertubeAPI retrofitPeertubeAPI;
APIResponse apiResponse = api.getComments(CommentVM.action.GET_THREAD, videoId, null, max_id); if( instance == null) {
retrofitPeertubeAPI = new RetrofitPeertubeAPI(_mContext);
}else{
retrofitPeertubeAPI = new RetrofitPeertubeAPI(_mContext, instance, null);
}
APIResponse apiResponse = retrofitPeertubeAPI.getComments(CommentVM.action.GET_THREAD, videoId, null, max_id);
Handler mainHandler = new Handler(Looper.getMainLooper()); Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse); Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse);
mainHandler.post(myRunnable); mainHandler.post(myRunnable);
@ -69,7 +74,7 @@ public class CommentVM extends AndroidViewModel {
new Thread(() -> { new Thread(() -> {
try { try {
RetrofitPeertubeAPI api = new RetrofitPeertubeAPI(_mContext); RetrofitPeertubeAPI api = new RetrofitPeertubeAPI(_mContext);
APIResponse apiResponse = api.getComments(action.GET_REPLIES, videoId, null, null); APIResponse apiResponse = api.getComments(action.GET_REPLIES, videoId, commentId, null);
Handler mainHandler = new Handler(Looper.getMainLooper()); Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse); Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse);
mainHandler.post(myRunnable); mainHandler.post(myRunnable);

View File

@ -0,0 +1,56 @@
package app.fedilab.fedilabtube.viewmodel;
/* 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.Application;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import app.fedilab.fedilabtube.client.RetrofitSepiaSearchAPI;
import app.fedilab.fedilabtube.client.data.VideoData;
import app.fedilab.fedilabtube.client.entities.SepiaSearch;
public class SepiaSearchVM extends AndroidViewModel {
private MutableLiveData<VideoData> apiResponseMutableLiveData;
public SepiaSearchVM(@NonNull Application application) {
super(application);
}
public LiveData<VideoData> sepiaSearch(SepiaSearch sepiaSearch) {
apiResponseMutableLiveData = new MutableLiveData<>();
getVideos(sepiaSearch);
return apiResponseMutableLiveData;
}
private void getVideos(SepiaSearch sepiaSearch) {
new Thread(() -> {
try {
VideoData videoData = new RetrofitSepiaSearchAPI().getVideos(sepiaSearch);
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(videoData);
mainHandler.post(myRunnable);
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
}

View File

@ -38,9 +38,9 @@ public class TimelineVM extends AndroidViewModel {
super(application); super(application);
} }
public LiveData<APIResponse> getVideos(TimelineType action, String max_id) { public LiveData<APIResponse> getVideos(TimelineType action, String max_id, String forAccount) {
apiResponseMutableLiveData = new MutableLiveData<>(); apiResponseMutableLiveData = new MutableLiveData<>();
loadVideos(action, max_id); loadVideos(action, max_id, forAccount);
return apiResponseMutableLiveData; return apiResponseMutableLiveData;
} }
@ -51,9 +51,9 @@ public class TimelineVM extends AndroidViewModel {
} }
public LiveData<APIResponse> getVideo(String videoId, boolean isMyVideo) { public LiveData<APIResponse> getVideo(String instance, String videoId, boolean isMyVideo) {
apiResponseMutableLiveData = new MutableLiveData<>(); apiResponseMutableLiveData = new MutableLiveData<>();
getSingle(videoId, isMyVideo); getSingle(instance, videoId, isMyVideo);
return apiResponseMutableLiveData; return apiResponseMutableLiveData;
} }
@ -63,23 +63,35 @@ public class TimelineVM extends AndroidViewModel {
return apiResponseMutableLiveData; return apiResponseMutableLiveData;
} }
public LiveData<APIResponse> getMyVideo(String videoId) { public LiveData<APIResponse> getMyVideo(String instance, String videoId) {
apiResponseMutableLiveData = new MutableLiveData<>(); apiResponseMutableLiveData = new MutableLiveData<>();
getSingle(videoId, true); getSingle(instance, videoId, true);
return apiResponseMutableLiveData; return apiResponseMutableLiveData;
} }
public LiveData<APIResponse> getVideosInChannel(String channelId, String max_id) { public LiveData<APIResponse> getVideosInChannel(String channelId, String max_id) {
apiResponseMutableLiveData = new MutableLiveData<>(); apiResponseMutableLiveData = new MutableLiveData<>();
loadVideosForChannel(channelId, max_id); loadVideosForChannel(null, channelId, max_id);
return apiResponseMutableLiveData; return apiResponseMutableLiveData;
} }
private void loadVideosForChannel(String channelId, String max_id) {
public LiveData<APIResponse> getVideosInChannel(String instance, String channelId, String max_id) {
apiResponseMutableLiveData = new MutableLiveData<>();
loadVideosForChannel(instance, channelId, max_id);
return apiResponseMutableLiveData;
}
private void loadVideosForChannel(String instance, String channelId, String max_id) {
Context _mContext = getApplication().getApplicationContext(); Context _mContext = getApplication().getApplicationContext();
new Thread(() -> { new Thread(() -> {
try { try {
RetrofitPeertubeAPI retrofitPeertubeAPI = new RetrofitPeertubeAPI(_mContext); RetrofitPeertubeAPI retrofitPeertubeAPI;
if( instance == null) {
retrofitPeertubeAPI = new RetrofitPeertubeAPI(_mContext);
}else {
retrofitPeertubeAPI = new RetrofitPeertubeAPI(_mContext, instance, null);
}
APIResponse apiResponse = retrofitPeertubeAPI.getVideosForChannel(channelId, max_id); APIResponse apiResponse = retrofitPeertubeAPI.getVideosForChannel(channelId, max_id);
Handler mainHandler = new Handler(Looper.getMainLooper()); Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse); Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse);
@ -90,13 +102,18 @@ public class TimelineVM extends AndroidViewModel {
}).start(); }).start();
} }
private void getSingle(String videoId, boolean myVideo) { private void getSingle(String instance, String videoId, boolean myVideo) {
Context _mContext = getApplication().getApplicationContext(); Context _mContext = getApplication().getApplicationContext();
new Thread(() -> { new Thread(() -> {
try { try {
RetrofitPeertubeAPI retrofitPeertubeAPI = new RetrofitPeertubeAPI(_mContext); RetrofitPeertubeAPI retrofitPeertubeAPI;
if( instance == null) {
retrofitPeertubeAPI = new RetrofitPeertubeAPI(_mContext);
}else{
retrofitPeertubeAPI = new RetrofitPeertubeAPI(_mContext, instance, null);
}
APIResponse apiResponse = retrofitPeertubeAPI.getVideos(videoId, myVideo); APIResponse apiResponse = retrofitPeertubeAPI.getVideos(videoId, myVideo);
if (Helper.isLoggedIn(_mContext) && !myVideo) { if (Helper.isLoggedIn(_mContext) && !myVideo && instance == null) {
if (apiResponse.getPeertubes() != null && apiResponse.getPeertubes().size() > 0 && apiResponse.getPeertubes().get(0) != null) { if (apiResponse.getPeertubes() != null && apiResponse.getPeertubes().size() > 0 && apiResponse.getPeertubes().get(0) != null) {
APIResponse response = new RetrofitPeertubeAPI(_mContext).getRating(videoId); APIResponse response = new RetrofitPeertubeAPI(_mContext).getRating(videoId);
if (response != null) if (response != null)
@ -128,7 +145,7 @@ public class TimelineVM extends AndroidViewModel {
}).start(); }).start();
} }
private void loadVideos(TimelineType timeline, String max_id) { private void loadVideos(TimelineType timeline, String max_id, String forAccount) {
Context _mContext = getApplication().getApplicationContext(); Context _mContext = getApplication().getApplicationContext();
new Thread(() -> { new Thread(() -> {
try { try {
@ -136,7 +153,7 @@ public class TimelineVM extends AndroidViewModel {
if (timeline == null) if (timeline == null)
return; return;
APIResponse apiResponse; APIResponse apiResponse;
apiResponse = retrofitPeertubeAPI.getTL(timeline, max_id); apiResponse = retrofitPeertubeAPI.getTL(timeline, max_id, forAccount);
Handler mainHandler = new Handler(Looper.getMainLooper()); Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse); Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse);
mainHandler.post(myRunnable); mainHandler.post(myRunnable);
@ -164,7 +181,8 @@ public class TimelineVM extends AndroidViewModel {
public enum TimelineType { public enum TimelineType {
USER_VIDEOS, CHANNEL_VIDEOS,
ACCOUNT_VIDEOS,
SUBSCRIBTIONS, SUBSCRIBTIONS,
MY_VIDEOS, MY_VIDEOS,
LOCAL, LOCAL,
@ -172,6 +190,7 @@ public class TimelineVM extends AndroidViewModel {
MOST_LIKED, MOST_LIKED,
HISTORY, HISTORY,
RECENT, RECENT,
VIDEOS_IN_PLAYLIST VIDEOS_IN_PLAYLIST,
SEPIA_SEARCH
} }
} }

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="@color/white">
<path
android:fillColor="@android:color/white"
android:pathData="M7,10l5,5 5,-5z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,3c-4.97,0 -9,4.03 -9,9s4.03,9 9,9c0.83,0 1.5,-0.67 1.5,-1.5 0,-0.39 -0.15,-0.74 -0.39,-1.01 -0.23,-0.26 -0.38,-0.61 -0.38,-0.99 0,-0.83 0.67,-1.5 1.5,-1.5L16,16c2.76,0 5,-2.24 5,-5 0,-4.42 -4.03,-8 -9,-8zM6.5,12c-0.83,0 -1.5,-0.67 -1.5,-1.5S5.67,9 6.5,9 8,9.67 8,10.5 7.33,12 6.5,12zM9.5,8C8.67,8 8,7.33 8,6.5S8.67,5 9.5,5s1.5,0.67 1.5,1.5S10.33,8 9.5,8zM14.5,8c-0.83,0 -1.5,-0.67 -1.5,-1.5S13.67,5 14.5,5s1.5,0.67 1.5,1.5S15.33,8 14.5,8zM17.5,12c-0.83,0 -1.5,-0.67 -1.5,-1.5S16.67,9 17.5,9s1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
</vector>

View File

@ -33,15 +33,14 @@
android:id="@+id/appBar" android:id="@+id/appBar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
> >
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar" android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:background="?colorPrimary" android:background="?colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark" android:theme="@style/theme"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" app:popupTheme="@style/popupTheme"
app:layout_scrollFlags="scroll|enterAlways" app:layout_scrollFlags="scroll|enterAlways"
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
/> />

View File

@ -47,6 +47,7 @@
<com.google.android.exoplayer2.ui.PlayerView <com.google.android.exoplayer2.ui.PlayerView
android:id="@+id/media_video" android:id="@+id/media_video"
android:animateLayoutChanges="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:gravity="center" /> android:gravity="center" />
@ -75,14 +76,21 @@
</RelativeLayout> </RelativeLayout>
</RelativeLayout> </RelativeLayout>
<ScrollView <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/peertube_information_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_weight="2"
android:layout_marginStart="@dimen/video_comment_margin" android:layout_marginStart="@dimen/video_comment_margin"
android:layout_marginEnd="@dimen/video_comment_margin" android:layout_marginEnd="@dimen/video_comment_margin"
android:layout_weight="2"> >
<androidx.core.widget.NestedScrollView
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:id="@+id/peertube_information_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -203,74 +211,86 @@
<TextView <TextView
android:id="@+id/peertube_description" android:id="@+id/peertube_description"
android:textIsSelectable="true"
android:autoLink="web"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp" /> android:layout_marginTop="10dp" />
<LinearLayout
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/write_comment_container" android:id="@+id/write_comment_container"
android:layout_margin="10dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content">
android:layout_gravity="center_vertical" <View
android:layout_marginTop="10dp" android:id="@+id/separator_top"
android:baselineAligned="false" android:layout_margin="5dp"
android:orientation="horizontal" app:layout_constraintTop_toTopOf="parent"
android:visibility="gone"> app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
<LinearLayout app:layout_constraintBottom_toTopOf="@+id/write_container"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="1px"
android:orientation="vertical"> android:background="@android:color/darker_gray"/>
<androidx.constraintlayout.widget.ConstraintLayout
app:layout_constraintTop_toBottomOf="@+id/separator_top"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@+id/separator_bottom"
android:id="@+id/write_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView <ImageView
android:id="@+id/my_pp" android:id="@+id/my_pp"
android:layout_width="40dp" app:layout_constraintTop_toTopOf="parent"
android:layout_height="40dp" android:layout_marginEnd="5dp"
android:contentDescription="@string/profile_picture" /> app:layout_constraintStart_toStartOf="parent"
<ImageView
android:id="@+id/send"
android:layout_width="30dp" android:layout_width="30dp"
android:layout_height="30dp" android:layout_height="30dp"
android:layout_marginTop="5dp" android:contentDescription="@string/profile_picture" />
android:contentDescription="@string/send_comment" <studio.carbonylgroup.textfieldboxes.TextFieldBoxes
android:src="@drawable/ic_baseline_send_24" android:id="@+id/text_field_boxes"
android:visibility="gone" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="10dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/add_comment_read"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/add_public_comment" /> app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@+id/my_pp"
<EditText app:layout_constraintEnd_toStartOf="@+id/send"
app:labelText="@string/add_public_comment"
app:secondaryColor="?attr/colorAccent"
app:primaryColor="?attr/colorAccent"
>
<studio.carbonylgroup.textfieldboxes.ExtendedEditText
android:id="@+id/add_comment_write" android:id="@+id/add_comment_write"
android:layout_width="match_parent" app:alwaysShowHint="false"
app:useDenseSpacing="false"
android:textSize="14sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:focusable="true" />
android:focusableInTouchMode="true" </studio.carbonylgroup.textfieldboxes.TextFieldBoxes>
android:hint="@string/add_public_comment" <ImageView
android:importantForAutofill="no" android:layout_marginStart="5dp"
android:inputType="textMultiLine" app:layout_constraintBottom_toBottomOf="parent"
android:maxLines="4" app:layout_constraintEnd_toEndOf="parent"
android:overScrollMode="always" android:id="@+id/send"
android:scrollbarStyle="insideInset" android:layout_width="wrap_content"
android:scrollbars="vertical" android:layout_height="wrap_content"
android:visibility="gone" /> android:contentDescription="@string/send_comment"
</LinearLayout> android:src="@drawable/ic_baseline_send_24" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout> <View
android:id="@+id/separator_bottom"
android:layout_margin="5dp"
app:layout_constraintTop_toBottomOf="@+id/write_container"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@android:color/darker_gray"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/peertube_comments" android:id="@+id/peertube_comments"
@ -294,7 +314,176 @@
android:textSize="25sp" /> android:textSize="25sp" />
</RelativeLayout> </RelativeLayout>
</LinearLayout> </LinearLayout>
</ScrollView> </androidx.core.widget.NestedScrollView>
<androidx.core.widget.NestedScrollView
android:background="?android:colorBackground"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:id="@+id/reply_thread"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp"
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="?android:dividerHorizontal"
android:orientation="vertical"
android:showDividers="end">
<ImageView
android:layout_gravity="end|center_vertical"
android:id="@+id/close_reply"
android:layout_width="24dp"
android:layout_height="24dp"
android:contentDescription="@string/close"
android:src="@drawable/ic_close_black_48dp"/>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/comment_account_profile"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginTop="5dp"
android:contentDescription="@string/profile_picture"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/comment_account_displayname"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:singleLine="true"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@+id/comment_date"
app:layout_constraintStart_toEndOf="@+id/comment_account_profile"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/comment_account_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:layout_marginStart="5dp"
android:ellipsize="end"
android:singleLine="true"
android:textSize="12sp"
app:layout_constraintStart_toEndOf="@+id/comment_account_profile"
app:layout_constraintTop_toBottomOf="@+id/comment_account_displayname" />
<TextView
android:id="@+id/comment_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginStart="2dp"
android:layout_weight="0"
android:gravity="end"
android:maxLines="1"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/comment_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textIsSelectable="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/comment_account_profile" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/write_comment_container_reply"
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="@+id/separator_top_reply"
android:layout_margin="5dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@+id/write_container_reply"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@android:color/darker_gray"/>
<androidx.constraintlayout.widget.ConstraintLayout
app:layout_constraintTop_toBottomOf="@+id/separator_top_reply"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@+id/separator_bottom_reply"
android:id="@+id/write_container_reply"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/my_pp_reply"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_width="30dp"
android:layout_height="30dp"
android:contentDescription="@string/profile_picture" />
<studio.carbonylgroup.textfieldboxes.TextFieldBoxes
android:id="@+id/text_field_boxes_reply"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@+id/my_pp_reply"
app:layout_constraintEnd_toStartOf="@+id/send_reply"
app:labelText="@string/add_public_reply"
app:secondaryColor="?attr/colorAccent"
app:primaryColor="?attr/colorAccent"
>
<studio.carbonylgroup.textfieldboxes.ExtendedEditText
android:id="@+id/add_comment_write_reply"
app:alwaysShowHint="false"
app:useDenseSpacing="false"
android:textSize="14sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</studio.carbonylgroup.textfieldboxes.TextFieldBoxes>
<ImageView
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:id="@+id/send_reply"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/send_comment"
android:src="@drawable/ic_baseline_send_24"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:id="@+id/separator_bottom_reply"
android:layout_margin="5dp"
app:layout_constraintTop_toBottomOf="@+id/write_container_reply"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@android:color/darker_gray"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.recyclerview.widget.RecyclerView
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:id="@+id/peertube_reply"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- View where the video will be shown when video goes fullscreen --> <!-- View where the video will be shown when video goes fullscreen -->
<RelativeLayout <RelativeLayout
android:id="@+id/videoLayout" android:id="@+id/videoLayout"

View File

@ -0,0 +1,370 @@
<?xml version="1.0" encoding="utf-8"?><!--
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>.
-->
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:TagsEditText="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".SepiaSearchActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:theme="@style/ThemeOverlay.AppCompat.Light">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
android:background="@color/white"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_marginStart="@dimen/fab_margin"
android:layout_marginEnd="@dimen/fab_margin"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
android:id="@+id/header"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<com.mancj.materialsearchbar.MaterialSearchBar
style="@style/MaterialSearchBarLight"
app:mt_speechMode="false"
app:mt_hint="@string/sepia_search_hint"
app:mt_maxSuggestionsCount="10"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:animateLayoutChanges="false"
android:id="@+id/searchBar" />
<TextView
android:layout_marginTop="5dp"
app:layout_constraintTop_toBottomOf="@+id/searchBar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="?attr/colorAccent"
android:id="@+id/explanations"
android:text="@string/sepia_indication"
/>
<Button
android:id="@+id/filter"
style="@style/Base.Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/filter"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/explanations"
android:drawableEnd="@drawable/ic_baseline_arrow_drop_down_24"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/explanations"
app:layout_constraintEnd_toStartOf="@+id/sort_by"
android:text="@string/sort_by"
android:labelFor="@+id/sort_by"/>
<Spinner
android:id="@+id/sort_by"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/explanations"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/filter_elements"
android:visibility="gone"
android:animateLayoutChanges="true"
app:layout_constraintTop_toBottomOf="@+id/header"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:labelFor="@+id/sepia_element_nsfw"
android:text="@string/sepia_element_nsfw"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:id="@+id/sepia_element_nsfw_label"
/>
<RadioGroup
android:id="@+id/sepia_element_nsfw"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="@+id/sepia_element_nsfw_label"
app:layout_constraintStart_toStartOf="parent"
>
<RadioButton
android:id="@+id/sepia_element_nsfw_yes"
android:text="@string/yes"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<RadioButton
android:id="@+id/sepia_element_nsfw_no"
android:text="@string/no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RadioGroup>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:labelFor="@+id/sepia_element_published_date"
android:text="@string/sepia_element_published_date"
app:layout_constraintTop_toBottomOf="@+id/sepia_element_nsfw"
app:layout_constraintStart_toStartOf="parent"
android:id="@+id/sepia_element_published_date_label"
/>
<HorizontalScrollView
android:layout_width="wrap_content"
android:id="@+id/sepia_element_published_date"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp"
app:layout_constraintTop_toBottomOf="@+id/sepia_element_published_date_label"
app:layout_constraintStart_toStartOf="parent">
<RadioGroup
android:id="@+id/radio_date"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<RadioButton
android:id="@+id/sepia_element_published_date_any"
android:text="@string/any"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<RadioButton
android:id="@+id/sepia_element_published_date_today"
android:text="@string/today"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<RadioButton
android:id="@+id/sepia_element_published_date_last_7_days"
android:text="@string/last_7_days"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<RadioButton
android:id="@+id/sepia_element_published_date_last_30_days"
android:text="@string/last_30_days"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<RadioButton
android:id="@+id/sepia_element_published_date_last_365_days"
android:text="@string/last_365_days"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RadioGroup>
</HorizontalScrollView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:labelFor="@+id/sepia_element_duration"
android:text="@string/sepia_element_duration"
app:layout_constraintTop_toBottomOf="@+id/sepia_element_published_date"
app:layout_constraintStart_toStartOf="parent"
android:id="@+id/sepia_element_duration_label"
/>
<HorizontalScrollView
android:layout_width="wrap_content"
android:id="@+id/sepia_element_duration"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp"
app:layout_constraintTop_toBottomOf="@+id/sepia_element_duration_label"
app:layout_constraintStart_toStartOf="parent">
<RadioGroup
android:id="@+id/duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<RadioButton
android:id="@+id/sepia_element_duration_any"
android:text="@string/any"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<RadioButton
android:id="@+id/sepia_element_duration_short"
android:text="@string/duration_short"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<RadioButton
android:id="@+id/sepia_element_duration_medium"
android:text="@string/duration_medium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<RadioButton
android:id="@+id/sepia_element_duration_long"
android:text="@string/duration_long"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RadioGroup>
</HorizontalScrollView>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:labelFor="@+id/sepia_element_category"
android:text="@string/category"
app:layout_constraintTop_toBottomOf="@+id/sepia_element_duration"
app:layout_constraintStart_toStartOf="parent"
android:id="@+id/sepia_element_category_label"
/>
<Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@+id/sepia_element_category_label"
app:layout_constraintStart_toStartOf="@+id/sepia_element_category_label"
android:id="@+id/sepia_element_category"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:labelFor="@+id/sepia_element_license"
android:text="@string/license"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sepia_element_category"
android:id="@+id/sepia_element_license_label"
/>
<Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/category"
app:layout_constraintTop_toBottomOf="@+id/sepia_element_license_label"
app:layout_constraintStart_toStartOf="@+id/sepia_element_license_label"
android:id="@+id/sepia_element_license"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:labelFor="@+id/sepia_element_language"
android:text="@string/language"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sepia_element_license"
android:id="@+id/sepia_element_language_label"
/>
<Spinner
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/category"
app:layout_constraintTop_toBottomOf="@+id/sepia_element_language_label"
app:layout_constraintStart_toStartOf="@+id/sepia_element_language_label"
android:id="@+id/sepia_element_language"
/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:labelFor="@+id/sepia_element_all_of_tags"
android:text="@string/all_of_these_tags"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sepia_element_language"
app:layout_constraintEnd_toEndOf="parent"
android:id="@+id/sepia_element_all_of_tags_label"
/>
<mabbas007.tagsedittext.TagsEditText
android:id="@+id/sepia_element_all_of_tags"
app:layout_constraintTop_toBottomOf="@+id/sepia_element_all_of_tags_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textMultiLine"
android:lines="2"
android:minLines="2"
TagsEditText:allowSpaceInTag="true"
TagsEditText:tagsCloseImagePadding="@dimen/defaultTagsCloseImagePadding"
TagsEditText:tagsCloseImageRight="@drawable/tag_close"
TagsEditText:tagsTextColor="?colorAccent"
TagsEditText:tagsTextSize="@dimen/defaultTagsTextSize" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:labelFor="@+id/sepia_element_one_of_tags"
android:text="@string/one_of_these_tags"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sepia_element_all_of_tags"
app:layout_constraintEnd_toEndOf="parent"
android:id="@+id/sepia_element_one_of_tags_label"
/>
<mabbas007.tagsedittext.TagsEditText
android:id="@+id/sepia_element_one_of_tags"
app:layout_constraintTop_toBottomOf="@+id/sepia_element_one_of_tags_label"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textMultiLine"
android:lines="2"
android:minLines="2"
TagsEditText:allowSpaceInTag="true"
TagsEditText:tagsCloseImagePadding="@dimen/defaultTagsCloseImagePadding"
TagsEditText:tagsCloseImageRight="@drawable/tag_close"
TagsEditText:tagsTextColor="?colorAccent"
TagsEditText:tagsTextSize="@dimen/defaultTagsTextSize" />
<Button
android:id="@+id/apply_filter"
style="@style/Base.Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/apply_filter"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sepia_element_one_of_tags"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<FrameLayout
android:layout_marginStart="@dimen/fab_margin"
android:layout_marginEnd="@dimen/fab_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -83,34 +83,10 @@
android:textAppearance="@style/TextAppearance.AppCompat.Body1" android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:visibility="invisible" android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="@id/account_follow" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/account_pp" app:layout_constraintStart_toEndOf="@+id/account_pp"
app:layout_constraintTop_toBottomOf="@id/account_dn" /> app:layout_constraintTop_toBottomOf="@id/account_dn" />
<Button
android:id="@+id/account_follow"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:contentDescription="@string/make_an_action"
android:scaleType="fitCenter"
android:visibility="gone"
app:layout_constraintStart_toEndOf="@id/subscriber_count"
app:layout_constraintTop_toBottomOf="@id/account_dn" />
<Button
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:contentDescription="@string/edit_profile"
android:scaleType="fitCenter"
android:src="@drawable/ic_baseline_edit_24"
android:visibility="gone"
app:layout_constraintStart_toEndOf="@id/subscriber_count"
app:layout_constraintTop_toBottomOf="@id/account_dn" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
@ -135,11 +111,8 @@
android:visibility="gone" /> android:visibility="gone" />
</LinearLayout> </LinearLayout>
</RelativeLayout> </RelativeLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout> </com.google.android.material.appbar.CollapsingToolbarLayout>
<com.google.android.material.tabs.TabLayout <com.google.android.material.tabs.TabLayout
android:id="@+id/account_tabLayout" android:id="@+id/account_tabLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -157,14 +130,4 @@
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior" /> app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/action_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin_button"
android:src="@drawable/ic_baseline_add_24"
android:tint="@android:color/white"
android:visibility="gone" />
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?><!--
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>.
-->
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".ShowChannelActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/top_banner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp">
<ImageView
android:id="@+id/account_pp"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_margin="10dp"
android:layout_marginTop="10dp"
android:background="@drawable/account_pp_border"
android:contentDescription="@string/profile_picture"
android:padding="2dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/account_dn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textColor="@android:color/white"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="@+id/subscriber_count"
app:layout_constraintStart_toEndOf="@+id/account_pp"
app:layout_constraintTop_toTopOf="@+id/account_pp" />
<TextView
android:id="@+id/subscriber_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
android:textColor="@android:color/white"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="@id/account_follow"
app:layout_constraintStart_toEndOf="@+id/account_pp"
app:layout_constraintTop_toBottomOf="@id/account_dn" />
<Button
android:id="@+id/account_follow"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:contentDescription="@string/make_an_action"
android:scaleType="fitCenter"
android:visibility="gone"
app:layout_constraintStart_toEndOf="@id/subscriber_count"
app:layout_constraintTop_toBottomOf="@id/account_dn" />
<Button
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:contentDescription="@string/edit_profile"
android:scaleType="fitCenter"
android:src="@drawable/ic_baseline_edit_24"
android:visibility="gone"
app:layout_constraintStart_toEndOf="@id/subscriber_count"
app:layout_constraintTop_toBottomOf="@id/account_dn" />
</androidx.constraintlayout.widget.ConstraintLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/top_banner"
android:gravity="center"
android:orientation="vertical"
android:paddingTop="8dp"
app:layout_scrollFlags="scroll|enterAlways">
<TextView
android:id="@+id/account_note"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:gravity="center"
android:padding="10dp"
android:textColor="@android:color/white"
android:textIsSelectable="true"
android:visibility="gone" />
</LinearLayout>
</RelativeLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
<com.google.android.material.tabs.TabLayout
android:id="@+id/account_tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabGravity="fill"
app:tabMode="fixed"
app:tabSelectedTextColor="?colorAccent"
app:tabTextColor="@android:color/white" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/account_viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/action_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin_button"
android:src="@drawable/ic_baseline_add_24"
android:tint="@android:color/white"
android:visibility="gone" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -21,7 +21,9 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:divider="?android:dividerHorizontal" android:divider="?android:dividerHorizontal"
android:orientation="vertical" android:orientation="vertical"
android:showDividers="end"> android:clickable="true"
android:showDividers="end"
android:focusable="true">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"
@ -47,6 +49,18 @@
app:layout_constraintStart_toEndOf="@+id/comment_account_profile" app:layout_constraintStart_toEndOf="@+id/comment_account_profile"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/comment_account_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:layout_marginStart="5dp"
android:ellipsize="end"
android:singleLine="true"
android:textSize="12sp"
app:layout_constraintStart_toEndOf="@+id/comment_account_profile"
app:layout_constraintTop_toBottomOf="@+id/comment_account_displayname" />
<TextView <TextView
android:id="@+id/comment_date" android:id="@+id/comment_date"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -71,28 +85,103 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/comment_date" /> app:layout_constraintTop_toBottomOf="@+id/comment_date" />
<TextView
android:id="@+id/comment_account_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:ellipsize="end"
android:singleLine="true"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="@+id/comment_account_profile"
app:layout_constraintStart_toEndOf="@+id/comment_account_profile"
app:layout_constraintTop_toBottomOf="@+id/comment_account_displayname" />
<TextView <TextView
android:id="@+id/comment_content" android:id="@+id/comment_content"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp" android:layout_marginTop="5dp"
android:textIsSelectable="true" android:textIsSelectable="true"
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/comment_account_profile" /> app:layout_constraintTop_toBottomOf="@+id/comment_account_profile" />
<TextView
android:id="@+id/number_of_replies"
app:layout_constraintTop_toBottomOf="@+id/comment_content"
app:layout_constraintStart_toStartOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?attr/colorAccent"/>
<TextView
app:layout_constraintTop_toBottomOf="@+id/comment_content"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:id="@+id/replyButton"
android:text="@string/reply"
android:textColor="?attr/colorAccent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<androidx.constraintlayout.widget.ConstraintLayout
app:layout_constraintTop_toBottomOf="@+id/replyButton"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:id="@+id/write_comment_container_reply"
android:layout_margin="10dp"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="@+id/separator_top_reply"
android:layout_margin="5dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@+id/write_container_reply"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@android:color/darker_gray"/>
<androidx.constraintlayout.widget.ConstraintLayout
app:layout_constraintTop_toBottomOf="@+id/separator_top_reply"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@+id/separator_bottom_reply"
android:id="@+id/write_container_reply"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<studio.carbonylgroup.textfieldboxes.TextFieldBoxes
android:id="@+id/text_field_boxes_reply"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/send_reply"
app:labelText="@string/add_public_reply"
app:secondaryColor="?attr/colorAccent"
app:primaryColor="?attr/colorAccent"
>
<studio.carbonylgroup.textfieldboxes.ExtendedEditText
android:id="@+id/add_comment_write_reply"
app:alwaysShowHint="false"
app:useDenseSpacing="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</studio.carbonylgroup.textfieldboxes.TextFieldBoxes>
<ImageView
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:id="@+id/send_reply"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/send_comment"
android:src="@drawable/ic_baseline_send_24"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:id="@+id/separator_bottom_reply"
android:layout_margin="5dp"
app:layout_constraintTop_toBottomOf="@+id/write_container_reply"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@android:color/darker_gray"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout> </LinearLayout>

View File

@ -19,19 +19,7 @@
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<LinearLayout <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginLeft="5dp"
android:layout_marginEnd="5dp"
android:layout_marginRight="5dp"
android:divider="?android:dividerHorizontal"
android:gravity="center_vertical"
android:orientation="vertical"
android:paddingTop="10dp" android:paddingTop="10dp"
android:showDividers="end">
<LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:orientation="horizontal">
@ -40,7 +28,8 @@
android:id="@+id/peertube_notif_pp" android:id="@+id/peertube_notif_pp"
android:layout_width="50dp" android:layout_width="50dp"
android:layout_height="50dp" android:layout_height="50dp"
android:layout_gravity="top" /> android:layout_gravity="top"
android:contentDescription="@string/profile_picture" />
<LinearLayout <LinearLayout
android:layout_width="0dp" android:layout_width="0dp"
@ -67,9 +56,6 @@
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout>
<RelativeLayout <RelativeLayout
android:id="@+id/container_trans" android:id="@+id/container_trans"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -15,6 +15,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:background="#CC000000" android:background="#CC000000"
android:animateLayoutChanges="true"
android:layoutDirection="ltr" android:layoutDirection="ltr"
android:orientation="vertical" android:orientation="vertical"
tools:targetApi="28"> tools:targetApi="28">
@ -34,13 +35,6 @@
android:id="@id/exo_rew" android:id="@id/exo_rew"
style="@style/ExoMediaButton.Rewind" /> style="@style/ExoMediaButton.Rewind" />
<ImageButton
android:id="@id/exo_shuffle"
style="@style/ExoMediaButton.VR" />
<ImageButton
android:id="@id/exo_repeat_toggle"
style="@style/ExoMediaButton" />
<ImageButton <ImageButton
android:id="@id/exo_play" android:id="@id/exo_play"

View File

@ -6,6 +6,16 @@
android:icon="@drawable/ic_baseline_delete_24" android:icon="@drawable/ic_baseline_delete_24"
android:title="@string/delete" android:title="@string/delete"
app:showAsAction="ifRoom" /> app:showAsAction="ifRoom" />
<item
android:id="@+id/action_mute"
android:icon="@drawable/ic_baseline_volume_mute_24"
android:title="@string/action_mute"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_remove_comments"
android:icon="@drawable/ic_baseline_delete_24"
android:title="@string/delete_account_comment"
app:showAsAction="ifRoom" />
<item <item
android:id="@+id/action_report" android:id="@+id/action_report"
android:icon="@drawable/ic_baseline_report_24" android:icon="@drawable/ic_baseline_report_24"

View File

@ -50,6 +50,11 @@
android:icon="@drawable/ic_baseline_settings_24" android:icon="@drawable/ic_baseline_settings_24"
android:title="@string/settings" android:title="@string/settings"
app:showAsAction="ifRoom" /> app:showAsAction="ifRoom" />
<item
android:id="@+id/action_sepia_search"
android:icon="@drawable/ic_baseline_search_24"
android:title="@string/sepia_search"
app:showAsAction="ifRoom" />
<item <item
android:id="@+id/action_about" android:id="@+id/action_about"
android:icon="@drawable/ic_baseline_info_24" android:icon="@drawable/ic_baseline_info_24"

View File

@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_report"
android:icon="@drawable/ic_baseline_report_24"
android:title="@string/report"
app:showAsAction="ifRoom" />
</menu>

View File

@ -16,4 +16,9 @@
android:icon="@drawable/ic_baseline_subtitles_24" android:icon="@drawable/ic_baseline_subtitles_24"
android:title="@string/captions" android:title="@string/captions"
app:showAsAction="ifRoom" /> app:showAsAction="ifRoom" />
<item
android:id="@+id/action_report"
android:icon="@drawable/ic_baseline_report_24"
android:title="@string/report"
app:showAsAction="ifRoom" />
</menu> </menu>

View File

@ -0,0 +1,28 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.DayNight.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:textColor">?attr/colorOnBackground</item>
</style>
<style name="AppThemeNoActionBar" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:textColor">?attr/colorOnBackground</item>
</style>
<style name="theme" parent="@style/ThemeOverlay.AppCompat.Dark"/>
<style name="popupTheme" parent="@style/ThemeOverlay.AppCompat.Dark"/>
<style name="progress" parent="SpinKitView.Circle" />
<style name="progressBottom" parent="SpinKitView.ThreeBounce" />
</resources>

View File

@ -7,6 +7,7 @@
<item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item> <item name="colorAccent">@color/colorAccent</item>
<item name="android:textColor">?attr/colorOnBackground</item>
</style> </style>
<style name="AppThemeNoActionBar" parent="Theme.AppCompat.Light.NoActionBar"> <style name="AppThemeNoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
@ -14,8 +15,13 @@
<item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item> <item name="colorAccent">@color/colorAccent</item>
<item name="android:textColor">?attr/colorOnBackground</item>
</style> </style>
<style name="theme" parent="@style/ThemeOverlay.AppCompat.Dark"/>
<style name="popupTheme" parent="@style/ThemeOverlay.AppCompat.Light"/>
<style name="progress" parent="SpinKitView.Circle" /> <style name="progress" parent="SpinKitView.Circle" />
<style name="progressBottom" parent="SpinKitView.ThreeBounce" /> <style name="progressBottom" parent="SpinKitView.ThreeBounce" />
</resources> </resources>

View File

@ -31,6 +31,11 @@
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="@string/app_interface"> <PreferenceCategory android:title="@string/app_interface">
<androidx.preference.ListPreference
android:icon="@drawable/ic_baseline_color_lens_24"
android:key="@string/set_theme_choice"
android:summary="@string/set_theme_description"
android:title="@string/set_theme" />
<androidx.preference.MultiSelectListPreference <androidx.preference.MultiSelectListPreference
android:icon="@drawable/ic_baseline_language_24" android:icon="@drawable/ic_baseline_language_24"
android:key="@string/set_video_language_choice" android:key="@string/set_video_language_choice"

View File

@ -3,9 +3,10 @@ buildscript {
repositories { repositories {
google() google()
jcenter() jcenter()
mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:4.0.1' classpath 'com.android.tools.build:gradle:4.1.0'
def nav_version = "2.3.0" def nav_version = "2.3.0"
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
@ -17,6 +18,8 @@ allprojects {
repositories { repositories {
google() google()
jcenter() jcenter()
mavenCentral()
mavenLocal()
} }
} }

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