some changes

This commit is contained in:
Thomas 2020-06-26 14:34:39 +02:00
parent 84eb7184c9
commit 67417bd65c
44 changed files with 2297 additions and 1300 deletions

View File

@ -6,7 +6,7 @@ android {
defaultConfig {
applicationId "app.fedilab.fedilabtube"
minSdkVersion 16
minSdkVersion 19
targetSdkVersion 29
versionCode 1
versionName "1.0"
@ -20,6 +20,17 @@ android {
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
allprojects {
repositories {
maven { url "https://jitpack.io" }
maven { url "https://maven.google.com"}
}
}
dependencies {
@ -28,11 +39,22 @@ dependencies {
implementation 'com.google.android.material:material:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
implementation 'androidx.navigation:navigation-fragment:2.1.0'
implementation 'androidx.navigation:navigation-ui:2.1.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
testImplementation 'junit:junit:4.12'
implementation 'androidx.navigation:navigation-fragment:2.3.0'
implementation 'androidx.navigation:navigation-ui:2.3.0'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'org.jetbrains:annotations-java5:15.0'
implementation 'androidx.browser:browser:1.2.0'
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.github.GrenderG:Toasty:1.4.2'
implementation 'com.google.android.exoplayer:exoplayer:2.10.6'
implementation "com.github.mabbas007:TagsEditText:1.0.5"
implementation "com.github.bumptech.glide:glide:4.11.0"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation 'org.apache.poi:poi:3.16'
implementation "net.gotev:uploadservice:3.5.2"
implementation "net.gotev:uploadservice-okhttp:3.5.2"
implementation "com.google.code.gson:gson:2.8.6"
}

View File

@ -6,13 +6,11 @@ import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
@ -54,12 +52,10 @@ import com.google.android.exoplayer2.ui.PlayerControlView;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory;
import com.google.android.exoplayer2.util.Util;
import org.jetbrains.annotations.NotNull;
import java.lang.ref.WeakReference;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
@ -71,13 +67,20 @@ import javax.net.ssl.HttpsURLConnection;
import app.fedilab.fedilabtube.asynctasks.ManagePlaylistsAsyncTask;
import app.fedilab.fedilabtube.asynctasks.PostActionAsyncTask;
import app.fedilab.fedilabtube.asynctasks.RetrieveFeedsAsyncTask;
import app.fedilab.fedilabtube.asynctasks.RetrievePeertubeSingleAsyncTask;
import app.fedilab.fedilabtube.asynctasks.RetrievePeertubeSingleCommentsAsyncTask;
import app.fedilab.fedilabtube.client.APIResponse;
import app.fedilab.fedilabtube.client.PeertubeAPI;
import app.fedilab.fedilabtube.client.TLSSocketFactory;
import app.fedilab.fedilabtube.client.entities.Account;
import app.fedilab.fedilabtube.client.entities.Error;
import app.fedilab.fedilabtube.client.entities.Peertube;
import app.fedilab.fedilabtube.client.entities.Playlist;
import app.fedilab.fedilabtube.client.entities.Status;
import app.fedilab.fedilabtube.client.entities.StatusDrawerParams;
import app.fedilab.fedilabtube.drawer.StatusListAdapter;
import app.fedilab.fedilabtube.helper.CacheDataSourceFactory;
import app.fedilab.fedilabtube.helper.FullScreenMediaController;
import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.interfaces.OnPlaylistActionInterface;
@ -91,7 +94,9 @@ import app.fedilab.fedilabtube.webview.MastalabWebChromeClient;
import app.fedilab.fedilabtube.webview.MastalabWebViewClient;
import es.dmoral.toasty.Toasty;
import static app.fedilab.fedilabtube.asynctasks.ManagePlaylistsAsyncTask.action.GET_PLAYLIST;
import static app.fedilab.fedilabtube.asynctasks.ManagePlaylistsAsyncTask.action.GET_PLAYLIST_FOR_VIDEO;
import static app.fedilab.fedilabtube.helper.Helper.changeDrawableColor;
public class PeertubeActivity extends AppCompatActivity implements OnRetrievePeertubeInterface, OnPostActionInterface, OnPlaylistActionInterface {
@ -195,7 +200,6 @@ public class PeertubeActivity extends AppCompatActivity implements OnRetrievePee
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
assert inflater != null;
View view = inflater.inflate(R.layout.simple_bar, new LinearLayout(PeertubeActivity.this), false);
view.setBackground(new ColorDrawable(ContextCompat.getColor(PeertubeActivity.this, R.color.cyanea_primary)));
actionBar.setCustomView(view, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
ImageView toolbar_close = actionBar.getCustomView().findViewById(R.id.toolbar_close);
@ -259,9 +263,7 @@ public class PeertubeActivity extends AppCompatActivity implements OnRetrievePee
initFullscreenButton();
}
if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE) {
new ManagePlaylistsAsyncTask(PeertubeActivity.this, GET_PLAYLIST, null, null, null, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
new ManagePlaylistsAsyncTask(PeertubeActivity.this, GET_PLAYLIST, null, null, null, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new RetrievePeertubeSingleAsyncTask(PeertubeActivity.this, peertubeInstance, videoId, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@ -306,64 +308,16 @@ public class PeertubeActivity extends AppCompatActivity implements OnRetrievePee
public boolean onCreateOptionsMenu(@NotNull Menu menu) {
getMenuInflater().inflate(R.menu.main_webview, menu);
menu.findItem(R.id.action_go).setVisible(false);
menu.findItem(R.id.action_block).setVisible(false);
menu.findItem(R.id.action_comment).setVisible(true);
if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE) {
MenuItem item = menu.findItem(R.id.action_comment);
if (item != null)
item.setVisible(false);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
case R.id.action_comment:
if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PLEROMA) {
Toasty.info(PeertubeActivity.this, getString(R.string.retrieve_remote_status), Toast.LENGTH_LONG).show();
new commentTask(new WeakReference<>(PeertubeActivity.this), peertube).execute();
} else if (MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE) {
if (!peertube.isCommentsEnabled()) {
Toasty.info(PeertubeActivity.this, getString(R.string.comment_no_allowed_peertube), Toast.LENGTH_LONG).show();
return true;
}
int style;
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
if (theme == Helper.THEME_DARK) {
style = R.style.DialogDark;
} else if (theme == Helper.THEME_BLACK) {
style = R.style.DialogBlack;
} else {
style = R.style.Dialog;
}
AlertDialog.Builder builderInner;
builderInner = new AlertDialog.Builder(PeertubeActivity.this, style);
builderInner.setTitle(R.string.comment);
EditText input = new EditText(PeertubeActivity.this);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
input.setLayoutParams(lp);
builderInner.setView(input);
builderInner.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
builderInner.setPositiveButton(R.string.validate, (dialog, which) -> {
String comment = input.getText().toString();
if (comment.trim().length() > 0) {
new PostActionAsyncTask(PeertubeActivity.this, API.StatusAction.PEERTUBECOMMENT, peertube.getId(), null, comment, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
dialog.dismiss();
}
});
builderInner.show();
}
return true;
default:
return super.onOptionsItemSelected(item);
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
public FullScreenMediaController.fullscreen getFullscreen() {
@ -524,9 +478,9 @@ public class PeertubeActivity extends AppCompatActivity implements OnRetrievePee
Drawable img;
if (peertubes == null || peertubes.size() == 0)
img = ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_bookmark_peertube_border);
img = ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_bookmark_border_24);
else
img = ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_bookmark_peertube);
img = ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_bookmark_24);
peertube_bookmark.setCompoundDrawablesWithIntrinsicBounds(null, img, null, null);
peertube_bookmark.setOnClickListener(v -> {
@ -539,9 +493,9 @@ public class PeertubeActivity extends AppCompatActivity implements OnRetrievePee
Toasty.success(PeertubeActivity.this, getString(R.string.bookmark_remove_peertube), Toast.LENGTH_SHORT).show();
}
if (peertubes1 != null && peertubes1.size() > 0) //Was initially in cache
peertube_bookmark.setCompoundDrawablesWithIntrinsicBounds(null, ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_bookmark_peertube_border), null, null);
peertube_bookmark.setCompoundDrawablesWithIntrinsicBounds(null, ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_bookmark_border_24), null, null);
else
peertube_bookmark.setCompoundDrawablesWithIntrinsicBounds(null, ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_bookmark_peertube), null, null);
peertube_bookmark.setCompoundDrawablesWithIntrinsicBounds(null, ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_bookmark_24), null, null);
});
peertube_share.setOnClickListener(v -> {
@ -600,21 +554,13 @@ public class PeertubeActivity extends AppCompatActivity implements OnRetrievePee
}
List<Status> statuses = apiResponse.getStatuses();
RecyclerView lv_comments = findViewById(R.id.peertube_comments);
if (statuses == null || statuses.size() == 0) {
if (MainActivity.social != UpdateAccountInfoAsyncTask.SOCIAL.PEERTUBE) {
RelativeLayout no_action = findViewById(R.id.no_action);
no_action.setVisibility(View.VISIBLE);
lv_comments.setVisibility(View.GONE);
}
} else {
if (statuses != null && statuses.size() > 0) {
lv_comments.setVisibility(View.VISIBLE);
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
boolean isOnWifi = Helper.isOnWIFI(PeertubeActivity.this);
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
StatusDrawerParams statusDrawerParams = new StatusDrawerParams();
statusDrawerParams.setType(RetrieveFeedsAsyncTask.Type.REMOTE_INSTANCE);
statusDrawerParams.setTargetedId(userId);
statusDrawerParams.setOnWifi(isOnWifi);
statusDrawerParams.setStatuses(statuses);
StatusListAdapter statusListAdapter = new StatusListAdapter(statusDrawerParams);
LinearLayoutManager mLayoutManager = new LinearLayoutManager(PeertubeActivity.this);
@ -655,16 +601,8 @@ public class PeertubeActivity extends AppCompatActivity implements OnRetrievePee
public void displayResolution() {
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
int style;
if (theme == Helper.THEME_DARK) {
style = R.style.DialogDark;
} else if (theme == Helper.THEME_BLACK) {
style = R.style.DialogBlack;
} else {
style = R.style.Dialog;
}
AlertDialog.Builder builderSingle = new AlertDialog.Builder(PeertubeActivity.this, style);
AlertDialog.Builder builderSingle = new AlertDialog.Builder(PeertubeActivity.this);
builderSingle.setTitle(R.string.pickup_resolution);
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(PeertubeActivity.this, android.R.layout.select_dialog_item);
for (String resolution : peertube.getResolution())
@ -709,9 +647,9 @@ public class PeertubeActivity extends AppCompatActivity implements OnRetrievePee
}
@Override
public void onPostAction(int statusCode, API.StatusAction statusAction, String userId, Error error) {
public void onPostAction(int statusCode, PeertubeAPI.StatusAction statusAction, String userId, Error error) {
if (peertube.isCommentsEnabled() && statusAction == API.StatusAction.PEERTUBECOMMENT)
if (peertube.isCommentsEnabled() && statusAction == PeertubeAPI.StatusAction.PEERTUBECOMMENT)
new RetrievePeertubeSingleCommentsAsyncTask(PeertubeActivity.this, peertubeInstance, videoId, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@ -731,7 +669,7 @@ public class PeertubeActivity extends AppCompatActivity implements OnRetrievePee
((ViewGroup) playerView.getParent()).removeView(playerView);
fullScreenDialog.addContentView(playerView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
fullScreenIcon.setImageDrawable(ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_fullscreen_exit));
fullScreenIcon.setImageDrawable(ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_fullscreen_exit_24));
fullScreenMode = true;
fullScreenDialog.show();
}
@ -742,7 +680,7 @@ public class PeertubeActivity extends AppCompatActivity implements OnRetrievePee
((FrameLayout) findViewById(R.id.main_media_frame)).addView(playerView);
fullScreenMode = false;
fullScreenDialog.dismiss();
fullScreenIcon.setImageDrawable(ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_fullscreen));
fullScreenIcon.setImageDrawable(ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_fullscreen_24));
}
private void initFullscreenButton() {
@ -767,12 +705,12 @@ public class PeertubeActivity extends AppCompatActivity implements OnRetrievePee
private void changeColor() {
if (peertube.getMyRating() != null && peertube.getMyRating().equals("like")) {
changeDrawableColor(PeertubeActivity.this, R.drawable.ic_thumb_up_peertube, R.color.positive_thumbs);
Drawable thumbUp = ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_thumb_up_peertube);
changeDrawableColor(PeertubeActivity.this, R.drawable.ic_baseline_thumb_up_alt_24, R.color.positive_thumbs);
Drawable thumbUp = ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_thumb_up_alt_24);
peertube_like_count.setCompoundDrawablesWithIntrinsicBounds(null, thumbUp, null, null);
} else if (peertube.getMyRating() != null && peertube.getMyRating().equals("dislike")) {
changeDrawableColor(PeertubeActivity.this, R.drawable.ic_thumb_down_peertube, R.color.negative_thumbs);
Drawable thumbDown = ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_thumb_down_peertube);
changeDrawableColor(PeertubeActivity.this, R.drawable.ic_baseline_thumb_down_alt_24, R.color.negative_thumbs);
Drawable thumbDown = ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_thumb_down_alt_24);
peertube_dislike_count.setCompoundDrawablesWithIntrinsicBounds(null, thumbDown, null, null);
}
}
@ -787,48 +725,4 @@ public class PeertubeActivity extends AppCompatActivity implements OnRetrievePee
}
}
private static class commentTask extends AsyncTask<Void, Void, app.fedilab.android.client.Entities.Status> {
private WeakReference<Context> contextReference;
private Peertube peertube;
commentTask(WeakReference<Context> contextReference, Peertube peertube) {
this.peertube = peertube;
this.contextReference = contextReference;
}
@Override
protected app.fedilab.android.client.Entities.Status doInBackground(Void... voids) {
List<app.fedilab.android.client.Entities.Status> remoteStatuses = null;
if (peertube != null) {
APIResponse search = new API(contextReference.get()).search("https://" + peertube.getAccount().getHost() + "/videos/watch/" + peertube.getUuid());
if (search != null && search.getResults() != null) {
remoteStatuses = search.getResults().getStatuses();
}
}
if (remoteStatuses != null && remoteStatuses.size() > 0) {
return remoteStatuses.get(0);
} else {
return null;
}
}
@Override
protected void onPostExecute(app.fedilab.android.client.Entities.Status remoteStatuses) {
Intent intent = new Intent(contextReference.get(), TootActivity.class);
Bundle b = new Bundle();
if (remoteStatuses == null) {
Toasty.error(contextReference.get(), contextReference.get().getString(R.string.toast_error), Toast.LENGTH_SHORT).show();
return;
}
if (remoteStatuses.getReblog() != null) {
b.putParcelable("tootReply", remoteStatuses.getReblog());
} else {
b.putParcelable("tootReply", remoteStatuses);
}
intent.putExtras(b);
contextReference.get().startActivity(intent);
}
}
}

View File

@ -4,7 +4,6 @@ package app.fedilab.fedilabtube;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
@ -23,7 +22,7 @@ import android.widget.Toast;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.appcompat.app.AppCompatActivity;
import java.util.HashMap;
import java.util.Iterator;
@ -31,24 +30,26 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import app.fedilab.android.asynctasks.PostActionAsyncTask;
import app.fedilab.android.asynctasks.PostPeertubeAsyncTask;
import app.fedilab.android.asynctasks.RetrievePeertubeChannelsAsyncTask;
import app.fedilab.android.asynctasks.RetrievePeertubeSingleAsyncTask;
import app.fedilab.android.client.API;
import app.fedilab.android.client.APIResponse;
import app.fedilab.android.client.Entities.Account;
import app.fedilab.android.client.Entities.Peertube;
import app.fedilab.android.helper.Helper;
import app.fedilab.android.interfaces.OnPostActionInterface;
import app.fedilab.android.interfaces.OnRetrievePeertubeInterface;
import app.fedilab.fedilabtube.asynctasks.PostActionAsyncTask;
import app.fedilab.fedilabtube.asynctasks.PostPeertubeAsyncTask;
import app.fedilab.fedilabtube.asynctasks.RetrievePeertubeChannelsAsyncTask;
import app.fedilab.fedilabtube.asynctasks.RetrievePeertubeSingleAsyncTask;
import app.fedilab.fedilabtube.client.APIResponse;
import app.fedilab.fedilabtube.client.PeertubeAPI;
import app.fedilab.fedilabtube.client.entities.Account;
import app.fedilab.fedilabtube.client.entities.Error;
import app.fedilab.fedilabtube.client.entities.Peertube;
import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.interfaces.OnPostActionInterface;
import app.fedilab.fedilabtube.interfaces.OnRetrievePeertubeInterface;
import es.dmoral.toasty.Toasty;
import mabbas007.tagsedittext.TagsEditText;
import static android.os.AsyncTask.THREAD_POOL_EXECUTOR;
import static app.fedilab.android.asynctasks.RetrievePeertubeInformationAsyncTask.peertubeInformation;
import static app.fedilab.fedilabtube.asynctasks.RetrievePeertubeInformationAsyncTask.peertubeInformation;
public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrievePeertubeInterface, OnPostActionInterface {
public class PeertubeEditUploadActivity extends AppCompatActivity implements OnRetrievePeertubeInterface, OnPostActionInterface {
HashMap<Integer, String> categoryToSend;
@ -70,17 +71,7 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
super.onCreate(savedInstanceState);
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
switch (theme) {
case Helper.THEME_LIGHT:
setTheme(R.style.AppTheme_Fedilab);
break;
case Helper.THEME_BLACK:
setTheme(R.style.AppThemeBlack);
break;
default:
setTheme(R.style.AppThemeDark);
}
Bundle b = getIntent().getExtras();
if (b != null) {
@ -96,7 +87,6 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
assert inflater != null;
View view = inflater.inflate(R.layout.simple_bar, new LinearLayout(PeertubeEditUploadActivity.this), false);
view.setBackground(new ColorDrawable(ContextCompat.getColor(PeertubeEditUploadActivity.this, R.color.cyanea_primary)));
actionBar.setCustomView(view, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
ImageView toolbar_close = actionBar.getCustomView().findViewById(R.id.toolbar_close);
@ -123,21 +113,11 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
set_upload_delete.setOnClickListener(v -> {
AlertDialog.Builder builderInner;
SharedPreferences sharedpreferences1 = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
int theme1 = sharedpreferences1.getInt(Helper.SET_THEME, Helper.THEME_DARK);
int style;
if (theme1 == Helper.THEME_DARK) {
style = R.style.DialogDark;
} else if (theme1 == Helper.THEME_BLACK) {
style = R.style.DialogBlack;
} else {
style = R.style.Dialog;
}
builderInner = new AlertDialog.Builder(PeertubeEditUploadActivity.this, style);
builderInner = new AlertDialog.Builder(PeertubeEditUploadActivity.this);
builderInner.setMessage(getString(R.string.delete_video_confirmation));
builderInner.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
builderInner.setPositiveButton(R.string.yes, (dialog, which) -> {
new PostActionAsyncTask(PeertubeEditUploadActivity.this, API.StatusAction.PEERTUBEDELETEVIDEO, videoId, PeertubeEditUploadActivity.this).executeOnExecutor(THREAD_POOL_EXECUTOR);
new PostActionAsyncTask(PeertubeEditUploadActivity.this, PeertubeAPI.StatusAction.PEERTUBEDELETEVIDEO, videoId, PeertubeEditUploadActivity.this).executeOnExecutor(THREAD_POOL_EXECUTOR);
dialog.dismiss();
});
builderInner.show();
@ -579,7 +559,7 @@ public class PeertubeEditUploadActivity extends BaseActivity implements OnRetrie
}
@Override
public void onPostAction(int statusCode, API.StatusAction statusAction, String userId, Error error) {
public void onPostAction(int statusCode, PeertubeAPI.StatusAction statusAction, String userId, Error error) {
Intent intent = new Intent(PeertubeEditUploadActivity.this, MainActivity.class);
intent.putExtra(Helper.INTENT_ACTION, Helper.RELOAD_MYVIDEOS);
startActivity(intent);

View File

@ -10,7 +10,6 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
@ -54,10 +53,14 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import app.fedilab.fedilabtube.asynctasks.RetrievePeertubeChannelsAsyncTask;
import app.fedilab.fedilabtube.client.APIResponse;
import app.fedilab.fedilabtube.client.entities.Account;
import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.interfaces.OnRetrievePeertubeInterface;
import es.dmoral.toasty.Toasty;
import static app.fedilab.fedilabtube.asynctasks.RetrievePeertubeInformationAsyncTask.peertubeInformation;
public class PeertubeUploadActivity extends AppCompatActivity implements OnRetrievePeertubeInterface, UploadStatusDelegate {
@ -80,7 +83,6 @@ public class PeertubeUploadActivity extends AppCompatActivity implements OnRetri
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
if (getSupportActionBar() != null)
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ActionBar actionBar = getSupportActionBar();
@ -88,7 +90,6 @@ public class PeertubeUploadActivity extends AppCompatActivity implements OnRetri
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
assert inflater != null;
View view = inflater.inflate(R.layout.simple_bar, new LinearLayout(PeertubeUploadActivity.this), false);
view.setBackground(new ColorDrawable(ContextCompat.getColor(PeertubeUploadActivity.this, R.color.cyanea_primary)));
actionBar.setCustomView(view, new ActionBar.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
ImageView toolbar_close = actionBar.getCustomView().findViewById(R.id.toolbar_close);
@ -322,7 +323,7 @@ public class PeertubeUploadActivity extends AppCompatActivity implements OnRetri
uploadConfig.getCompleted().message = getString(R.string.upload_video_success);
uploadConfig.getError().message = getString(R.string.toast_error);
uploadConfig.getCancelled().message = getString(R.string.toast_cancelled);
uploadConfig.getCompleted().actions.add(new UploadNotificationAction(R.drawable.ic_check, getString(R.string.video_uploaded_action), clickIntent));
uploadConfig.getCompleted().actions.add(new UploadNotificationAction(R.drawable.ic_baseline_check_24, getString(R.string.video_uploaded_action), clickIntent));
if (video_title != null && video_title.getText() != null && video_title.getText().toString().trim().length() > 0) {
filename = video_title.getText().toString().trim();

View File

@ -0,0 +1,171 @@
package app.fedilab.fedilabtube;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import org.jetbrains.annotations.NotNull;
import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.webview.CustomWebview;
import app.fedilab.fedilabtube.webview.MastalabWebChromeClient;
import app.fedilab.fedilabtube.webview.MastalabWebViewClient;
import es.dmoral.toasty.Toasty;
public class WebviewActivity extends AppCompatActivity {
private String url;
private boolean peertubeLink;
private CustomWebview webView;
@SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_webview);
Bundle b = getIntent().getExtras();
if (b != null) {
url = b.getString("url", null);
peertubeLink = b.getBoolean("peertubeLink", false);
}
if (url == null)
finish();
if (getSupportActionBar() != null)
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
webView = Helper.initializeWebview(WebviewActivity.this, R.id.webview, null);
setTitle("");
FrameLayout webview_container = findViewById(R.id.webview_container);
final ViewGroup videoLayout = findViewById(R.id.videoLayout); // Your own view, read class comments
webView.getSettings().setJavaScriptEnabled(true);
MastalabWebChromeClient mastalabWebChromeClient = new MastalabWebChromeClient(WebviewActivity.this, webView, webview_container, videoLayout);
mastalabWebChromeClient.setOnToggledFullscreen(fullscreen -> {
if (fullscreen) {
videoLayout.setVisibility(View.VISIBLE);
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
attrs.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
getWindow().setAttributes(attrs);
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE);
} else {
WindowManager.LayoutParams attrs = getWindow().getAttributes();
attrs.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN;
attrs.flags &= ~WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
getWindow().setAttributes(attrs);
getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
videoLayout.setVisibility(View.GONE);
}
});
webView.setWebChromeClient(mastalabWebChromeClient);
MastalabWebViewClient mastalabWebViewClient = new MastalabWebViewClient(WebviewActivity.this);
webView.setWebViewClient(mastalabWebViewClient);
webView.setDownloadListener((url, userAgent, contentDisposition, mimetype, contentLength) -> {
if (Build.VERSION.SDK_INT >= 23) {
if (ContextCompat.checkSelfPermission(WebviewActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(WebviewActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(WebviewActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, Helper.EXTERNAL_STORAGE_REQUEST_CODE);
} else {
Helper.manageDownloads(WebviewActivity.this, url);
}
} else {
Helper.manageDownloads(WebviewActivity.this, url);
}
});
if (!url.toLowerCase().startsWith("http://") && !url.toLowerCase().startsWith("https://"))
url = "http://" + url;
webView.loadUrl(url);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onCreateOptionsMenu(@NotNull Menu menu) {
getMenuInflater().inflate(R.menu.main_webview, menu);
if (peertubeLink) {
menu.findItem(R.id.action_go).setVisible(false);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
case R.id.action_go:
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
try {
startActivity(browserIntent);
} catch (Exception e) {
Toasty.error(WebviewActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show();
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void setUrl(String newUrl) {
this.url = newUrl;
}
@Override
public void onPause() {
super.onPause();
if (webView != null)
webView.onPause();
}
@Override
public void onResume() {
super.onResume();
if (webView != null)
webView.onResume();
}
@Override
public void onBackPressed() {
if (webView.canGoBack()) {
webView.goBack();
} else {
super.onBackPressed();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (webView != null)
webView.destroy();
}
}

View File

@ -32,6 +32,13 @@ public class PostActionAsyncTask extends AsyncTask<Void, Void, Void> {
this.account = account;
}
public PostActionAsyncTask(Context context, PeertubeAPI.StatusAction apiAction, String targetedId, OnPostActionInterface onPostActionInterface) {
this.contextReference = new WeakReference<>(context);
this.listener = onPostActionInterface;
this.apiAction = apiAction;
this.targetedId = targetedId;
}
public PostActionAsyncTask(Context context, String targetedId, String comment, String targetedComment, OnPostActionInterface onPostActionInterface) {
this.contextReference = new WeakReference<>(context);
this.listener = onPostActionInterface;

View File

@ -0,0 +1,44 @@
package app.fedilab.fedilabtube.asynctasks;
import android.content.Context;
import android.os.AsyncTask;
import java.lang.ref.WeakReference;
import app.fedilab.fedilabtube.client.APIResponse;
import app.fedilab.fedilabtube.client.PeertubeAPI;
import app.fedilab.fedilabtube.client.entities.Peertube;
import app.fedilab.fedilabtube.interfaces.OnRetrievePeertubeInterface;
public class PostPeertubeAsyncTask extends AsyncTask<Void, Void, Void> {
private APIResponse apiResponse;
private OnRetrievePeertubeInterface listener;
private WeakReference<Context> contextReference;
private Peertube peertube;
public PostPeertubeAsyncTask(Context context, Peertube peertube, OnRetrievePeertubeInterface onRetrievePeertubeInterface) {
this.contextReference = new WeakReference<>(context);
this.listener = onRetrievePeertubeInterface;
this.peertube = peertube;
}
@Override
protected Void doInBackground(Void... params) {
PeertubeAPI peertubeAPI = new PeertubeAPI(this.contextReference.get());
apiResponse = peertubeAPI.updateVideo(peertube);
if (apiResponse != null && apiResponse.getPeertubes() != null && apiResponse.getPeertubes().size() > 0)
apiResponse.getPeertubes().get(0).setUpdate(true);
return null;
}
@Override
protected void onPostExecute(Void result) {
listener.onRetrievePeertube(apiResponse);
}
}

View File

@ -6,13 +6,13 @@ import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import app.fedilab.fedilabtube.client.APIResponse;
import app.fedilab.fedilabtube.client.PeertubeAPI;
import app.fedilab.fedilabtube.client.entities.Peertube;
import app.fedilab.fedilabtube.interfaces.OnRetrieveFeedsInterface;
import app.fedilab.fedilabtube.sqlite.PeertubeFavoritesDAO;
import app.fedilab.fedilabtube.sqlite.Sqlite;
@ -36,6 +36,13 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
private String social;
public RetrieveFeedsAsyncTask(Context context, Type action, String max_id, OnRetrieveFeedsInterface onRetrieveFeedsInterface) {
this.contextReference = new WeakReference<>(context);
this.action = action;
this.max_id = max_id;
this.listener = onRetrieveFeedsInterface;
this.search = null;
}
public RetrieveFeedsAsyncTask(Context context, Type action, String max_id, String search, OnRetrieveFeedsInterface onRetrieveFeedsInterface) {
this.contextReference = new WeakReference<>(context);
@ -49,7 +56,7 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
PeertubeAPI peertubeAPI = new PeertubeAPI(this.contextReference.get());
SQLiteDatabase db = Sqlite.getInstance(this.contextReference.get().getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
if (action == null)
return null;
switch (action) {
@ -74,7 +81,7 @@ public class RetrieveFeedsAsyncTask extends AsyncTask<Void, Void, Void> {
case CACHE_BOOKMARKS_PEERTUBE:
apiResponse = new APIResponse();
db = Sqlite.getInstance(contextReference.get().getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
SQLiteDatabase db = Sqlite.getInstance(contextReference.get().getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
List<Peertube> peertubes = new PeertubeFavoritesDAO(contextReference.get(), db).getAllPeertube();
apiResponse.setPeertubes(peertubes);
break;

View File

@ -0,0 +1,46 @@
package app.fedilab.fedilabtube.client.entities;
import java.util.List;
import app.fedilab.fedilabtube.asynctasks.RetrieveFeedsAsyncTask;
public class StatusDrawerParams {
private List<Status> statuses;
private RetrieveFeedsAsyncTask.Type type;
private String targetedId;
private int position;
public List<Status> getStatuses() {
return statuses;
}
public void setStatuses(List<Status> statuses) {
this.statuses = statuses;
}
public RetrieveFeedsAsyncTask.Type getType() {
return type;
}
public void setType(RetrieveFeedsAsyncTask.Type type) {
this.type = type;
}
public String getTargetedId() {
return targetedId;
}
public void setTargetedId(String targetedId) {
this.targetedId = targetedId;
}
public int getPosition() {
return position;
}
public void setPosition(int position) {
this.position = position;
}
}

View File

@ -1,4 +1,4 @@
package app.fedilab.fedilabtube.ui.video;
package app.fedilab.fedilabtube.drawer;
@ -36,12 +36,10 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
private List<Peertube> peertubes;
private Context context;
private String instance;
public PeertubeAdapter(String instance, List<Peertube> peertubes) {
public PeertubeAdapter(List<Peertube> peertubes) {
this.peertubes = peertubes;
this.instance = instance;
}
@ -102,8 +100,7 @@ public class PeertubeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
holder.peertube_video_image.setOnClickListener(v -> {
Intent intent = new Intent(context, PeertubeActivity.class);
Bundle b = new Bundle();
if ((instance == null || instance.trim().length() == 0) )
instance = Helper.getLiveInstance(context);
String instance = Helper.getLiveInstance(context);
String finalUrl = "https://" + instance + peertube.getEmbedPath();
Pattern link = Pattern.compile("(https?://[\\da-z.-]+\\.[a-z.]{2,10})/videos/embed/(\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12})$");
Matcher matcherLink = link.matcher(finalUrl);

View File

@ -0,0 +1,219 @@
package app.fedilab.fedilabtube.drawer;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ForegroundColorSpan;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import app.fedilab.fedilabtube.PeertubeActivity;
import app.fedilab.fedilabtube.R;
import app.fedilab.fedilabtube.asynctasks.PostActionAsyncTask;
import app.fedilab.fedilabtube.client.PeertubeAPI;
import app.fedilab.fedilabtube.client.entities.Account;
import app.fedilab.fedilabtube.client.entities.Error;
import app.fedilab.fedilabtube.client.entities.Status;
import app.fedilab.fedilabtube.client.entities.StatusDrawerParams;
import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.interfaces.OnPostActionInterface;
import es.dmoral.toasty.Toasty;
import static android.content.Context.MODE_PRIVATE;
public class StatusListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> implements OnPostActionInterface {
private Context context;
private List<Status> statuses;
private StatusListAdapter statusListAdapter;
public StatusListAdapter(StatusDrawerParams statusDrawerParams) {
statuses = statusDrawerParams.getStatuses();
statusListAdapter = this;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemCount() {
return statuses.size();
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
context = parent.getContext();
LayoutInflater layoutInflater = LayoutInflater.from(this.context);
return new ViewHolder(layoutInflater.inflate(R.layout.drawer_status_compact, parent, false));
}
@SuppressLint({"SetJavaScriptEnabled", "ClickableViewAccessibility"})
@Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int i) {
context = viewHolder.itemView.getContext();
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
final String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
final ViewHolder holder = (ViewHolder) viewHolder;
final Status status = statuses.get(i);
if (status == null)
return;
if (status.getVisibility() == null) {
status.setVisibility("public");
}
if (status.getAccount().getId().equals(userId))
holder.status_peertube_delete.setVisibility(View.VISIBLE);
else
holder.status_peertube_delete.setVisibility(View.GONE);
holder.status_peertube_delete.setOnClickListener(v -> {
AlertDialog.Builder builderInner;
builderInner = new AlertDialog.Builder(context);
builderInner.setTitle(R.string.delete_comment);
builderInner.setMessage(R.string.delete_comment_confirm);
builderInner.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
builderInner.setPositiveButton(R.string.yes, (dialog, which) -> {
new PostActionAsyncTask(context, PeertubeAPI.StatusAction.PEERTUBEDELETECOMMENT, PeertubeActivity.video_id, null, status.getId(), StatusListAdapter.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
dialog.dismiss();
});
builderInner.show();
});
holder.status_content.setOnTouchListener((view, motionEvent) -> {
if (motionEvent.getAction() == MotionEvent.ACTION_UP && !view.hasFocus()) {
try {
view.requestFocus();
} catch (Exception ignored) {
}
}
return false;
});
//Click on a conversation
holder.status_content.setText(status.getContentSpan(), TextView.BufferType.SPANNABLE);
holder.status_content.setMovementMethod(LinkMovementMethod.getInstance());
final Account accountForUrl;
accountForUrl = status.getAccount();
holder.status_account_displayname.setVisibility(View.GONE);
holder.status_account_displayname_owner.setText(status.getAccount().getUsername().replace("@", ""), TextView.BufferType.SPANNABLE);
Spannable wordtoSpan;
Pattern hashAcct;
wordtoSpan = new SpannableString("@" + status.getAccount().getAcct());
hashAcct = Pattern.compile("(@" + status.getAccount().getAcct() + ")");
Matcher matcherAcct = hashAcct.matcher(wordtoSpan);
while (matcherAcct.find()) {
int matchStart = matcherAcct.start(1);
int matchEnd = matcherAcct.end();
if (wordtoSpan.length() >= matchEnd && matchStart < matchEnd) {
wordtoSpan.setSpan(new ForegroundColorSpan(ContextCompat.getColor(context, android.R.color.darker_gray)), matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
holder.status_account_username.setText(wordtoSpan);
holder.status_toot_date.setText(Helper.dateDiff(context, status.getCreated_at()));
Helper.loadGiF(context, accountForUrl, holder.status_account_profile);
}
@Override
public void onPostAction(int statusCode, PeertubeAPI.StatusAction statusAction, String targetedId, Error error) {
if (error != null) {
Toasty.error(context, error.getError(), Toast.LENGTH_LONG).show();
return;
}
if (statusAction == PeertubeAPI.StatusAction.PEERTUBEDELETECOMMENT) {
int position = 0;
for (Status status : statuses) {
if (status.getId().equals(targetedId)) {
statuses.remove(status);
statusListAdapter.notifyItemRemoved(position);
break;
}
position++;
}
}
}
static class ViewHolder extends RecyclerView.ViewHolder {
TextView status_content;
TextView status_account_username;
TextView status_account_displayname, status_account_displayname_owner;
ImageView status_account_profile;
TextView status_toot_date;
LinearLayout main_container;
LinearLayout status_content_container;
TextView status_peertube_delete;
@SuppressLint("SetJavaScriptEnabled")
ViewHolder(View itemView) {
super(itemView);
status_content = itemView.findViewById(R.id.status_content);
status_account_username = itemView.findViewById(R.id.status_account_username);
status_account_displayname = itemView.findViewById(R.id.status_account_displayname);
status_account_displayname_owner = itemView.findViewById(R.id.status_account_displayname_owner);
status_account_profile = itemView.findViewById(R.id.status_account_profile);
status_toot_date = itemView.findViewById(R.id.status_toot_date);
main_container = itemView.findViewById(R.id.main_container);
status_content_container = itemView.findViewById(R.id.status_content_container);
status_peertube_delete = itemView.findViewById(R.id.status_peertube_delete);
}
public View getView() {
return itemView;
}
}
}

View File

@ -0,0 +1,306 @@
package app.fedilab.fedilabtube.fragment;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
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.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.R;
import app.fedilab.fedilabtube.asynctasks.RetrieveFeedsAsyncTask;
import app.fedilab.fedilabtube.asynctasks.RetrievePeertubeSearchAsyncTask;
import app.fedilab.fedilabtube.client.APIResponse;
import app.fedilab.fedilabtube.client.PeertubeAPI;
import app.fedilab.fedilabtube.client.entities.Error;
import app.fedilab.fedilabtube.client.entities.Peertube;
import app.fedilab.fedilabtube.drawer.PeertubeAdapter;
import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.interfaces.OnPostActionInterface;
import app.fedilab.fedilabtube.interfaces.OnRetrieveFeedsInterface;
import app.fedilab.fedilabtube.sqlite.Sqlite;
import es.dmoral.toasty.Toasty;
public class DisplayStatusFragment extends Fragment implements OnPostActionInterface, OnRetrieveFeedsInterface {
private LinearLayoutManager mLayoutManager;
private boolean flag_loading;
private Context context;
private AsyncTask<Void, Void, Void> asyncTask;
private PeertubeAdapter peertubeAdapater;
private String max_id;
private List<Peertube> peertubes;
private RetrieveFeedsAsyncTask.Type type;
private RelativeLayout mainLoader, nextElementLoader, textviewNoAction;
private boolean firstLoad;
private SwipeRefreshLayout swipeRefreshLayout;
private SharedPreferences sharedpreferences;
private boolean isSwipped;
private String search_peertube;
private TextView textviewNoActionText;
private boolean ischannel;
private boolean ownVideos;
private View rootView;
private RecyclerView lv_status;
public DisplayStatusFragment() {
}
@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) {
type = (RetrieveFeedsAsyncTask.Type) bundle.get("type");
String targetedId = bundle.getString("targetedid", null);
String tag = bundle.getString("tag", null);
search_peertube = bundle.getString("search_peertube", null);
String remote_channel_name = bundle.getString("remote_channel_name", null);
String instanceType = bundle.getString("instanceType", "MASTODON");
ischannel = bundle.getBoolean("ischannel", false);
int timelineId = bundle.getInt("timelineId");
}
if (ischannel) {
type = RetrieveFeedsAsyncTask.Type.CHANNEL;
}
assert context != null;
SQLiteDatabase db = Sqlite.getInstance(context.getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
lv_status = rootView.findViewById(R.id.lv_status);
isSwipped = false;
max_id = null;
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);
String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null);
String instance = sharedpreferences.getString(Helper.PREF_INSTANCE, context != null ? Helper.getLiveInstance(context) : null);
peertubeAdapater = new PeertubeAdapter(this.peertubes);
lv_status.setAdapter(peertubeAdapater);
mLayoutManager = new LinearLayoutManager(context);
lv_status.setLayoutManager(mLayoutManager);
swipeRefreshLayout.setOnRefreshListener(this::pullToRefresh);
if (context != null) {
//Load data depending of the value
if (search_peertube == null) { //Not a Peertube search
asyncTask = new RetrieveFeedsAsyncTask(context, type, "0", DisplayStatusFragment.this).execute();
} else {
asyncTask = new RetrievePeertubeSearchAsyncTask(context, "0", search_peertube, DisplayStatusFragment.this).execute();
}
} else {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
if (context != null) {
if (search_peertube == null) { //Not a Peertube search
asyncTask = new RetrieveFeedsAsyncTask(context, type, "0", DisplayStatusFragment.this).execute();
} else {
asyncTask = new RetrievePeertubeSearchAsyncTask(context, "0", search_peertube, DisplayStatusFragment.this).execute();
}
}
}, 500);
}
lv_status.addOnScrollListener(new RecyclerView.OnScrollListener() {
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
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;
if (search_peertube == null) { //Not a Peertube search
asyncTask = new RetrieveFeedsAsyncTask(context, type, max_id, DisplayStatusFragment.this).execute();
} else {
asyncTask = new RetrievePeertubeSearchAsyncTask(context, max_id, search_peertube, DisplayStatusFragment.this).execute();
}
nextElementLoader.setVisibility(View.VISIBLE);
}
} else {
nextElementLoader.setVisibility(View.GONE);
}
}
}
});
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();
if (asyncTask != null && asyncTask.getStatus() == AsyncTask.Status.RUNNING)
asyncTask.cancel(true);
}
@Override
public void onRetrieveFeeds(APIResponse apiResponse) {
//hide loaders
mainLoader.setVisibility(View.GONE);
nextElementLoader.setVisibility(View.GONE);
//handle other API error but discards 404 - error which can often happen due to toots which have been deleted
if (this.peertubes == null || apiResponse == null || (apiResponse.getError() != null && apiResponse.getError().getStatusCode() != 404 && apiResponse.getError().getStatusCode() != 501)) {
if (apiResponse == null)
Toasty.error(context, context.getString(R.string.toast_error), Toast.LENGTH_LONG).show();
else {
Toasty.error(context, apiResponse.getError().getError(), Toast.LENGTH_LONG).show();
}
swipeRefreshLayout.setRefreshing(false);
flag_loading = false;
return;
}
int previousPosition = this.peertubes.size();
if (max_id == null)
max_id = "0";
//max_id needs to work like an offset
int tootPerPage = sharedpreferences.getInt(Helper.SET_VIDEOS_PER_PAGE, Helper.VIDEOS_PER_PAGE);
max_id = String.valueOf(Integer.parseInt(max_id) + tootPerPage);
if (apiResponse.getPeertubes() == null) {
return;
}
this.peertubes.addAll(apiResponse.getPeertubes());
//If no item were inserted previously the adapter is created
if (previousPosition == 0) {
peertubeAdapater = new PeertubeAdapter(this.peertubes);
lv_status.setAdapter(peertubeAdapater);
} else
peertubeAdapater.notifyItemRangeInserted(previousPosition, apiResponse.getPeertubes().size());
//remove handlers
swipeRefreshLayout.setRefreshing(false);
textviewNoAction.setVisibility(View.GONE);
if (firstLoad && (apiResponse.getPeertubes() == null || apiResponse.getPeertubes().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);
}
}
public void pullToRefresh() {
if (peertubes.size() > 0) {
int size = peertubes.size();
isSwipped = true;
peertubes.clear();
peertubes = new ArrayList<>();
max_id = "0";
peertubeAdapater.notifyItemRangeRemoved(0, size);
if (search_peertube == null) { //Not a Peertube search
asyncTask = new RetrieveFeedsAsyncTask(context, type, "0", DisplayStatusFragment.this).execute();
} else {
asyncTask = new RetrievePeertubeSearchAsyncTask(context, "0", search_peertube, DisplayStatusFragment.this).execute();
}
}
}
@Override
public void onPostAction(int statusCode, PeertubeAPI.StatusAction statusAction, String userId, Error error) {
}
}

View File

@ -0,0 +1,56 @@
package app.fedilab.fedilabtube.helper;
import android.content.Context;
import android.content.SharedPreferences;
import com.google.android.exoplayer2.database.ExoDatabaseProvider;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.google.android.exoplayer2.upstream.FileDataSource;
import com.google.android.exoplayer2.upstream.cache.CacheDataSink;
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor;
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
import java.io.File;
public class CacheDataSourceFactory implements DataSource.Factory {
private static SimpleCache sDownloadCache;
private final Context context;
private final DefaultDataSourceFactory defaultDatasourceFactory;
private final long maxFileSize;
public CacheDataSourceFactory(Context context) {
super();
this.context = context;
this.maxFileSize = 5 * 1024 * 1024;
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
String userAgent = sharedpreferences.getString(Helper.SET_CUSTOM_USER_AGENT, Helper.USER_AGENT);
DefaultBandwidthMeter.Builder bandwidthMeterBuilder = new DefaultBandwidthMeter.Builder(context);
DefaultBandwidthMeter bandwidthMeter = bandwidthMeterBuilder.build();
defaultDatasourceFactory = new DefaultDataSourceFactory(this.context,
bandwidthMeter,
new DefaultHttpDataSourceFactory(userAgent, bandwidthMeter));
}
public static SimpleCache getInstance(Context context) {
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
int video_cache = sharedpreferences.getInt(Helper.SET_VIDEO_CACHE, Helper.DEFAULT_VIDEO_CACHE_MB);
LeastRecentlyUsedCacheEvictor evictor = new LeastRecentlyUsedCacheEvictor(video_cache * 1024 * 1024);
ExoDatabaseProvider exoDatabaseProvider = new ExoDatabaseProvider(context);
if (sDownloadCache == null)
sDownloadCache = new SimpleCache(new File(context.getCacheDir(), "media"), evictor, exoDatabaseProvider);
return sDownloadCache;
}
@Override
public DataSource createDataSource() {
SimpleCache simpleCache = getInstance(context);
return new CacheDataSource(simpleCache, defaultDatasourceFactory.createDataSource(),
new FileDataSource(), new CacheDataSink(simpleCache, maxFileSize),
CacheDataSource.FLAG_BLOCK_ON_CACHE | CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR, null);
}
}

View File

@ -0,0 +1,54 @@
package app.fedilab.fedilabtube.helper;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.text.Layout;
import android.text.style.LeadingMarginSpan;
import android.text.style.LineBackgroundSpan;
import org.jetbrains.annotations.NotNull;
/**
* Original work from @heath-borders: https://stackoverflow.com/a/29114976/3197259
*/
public class CustomQuoteSpan implements LeadingMarginSpan, LineBackgroundSpan {
private final int backgroundColor;
private final int stripeColor;
private final float stripeWidth;
private final float gap;
public CustomQuoteSpan(int backgroundColor, int stripeColor, float stripeWidth, float gap) {
this.backgroundColor = backgroundColor;
this.stripeColor = stripeColor;
this.stripeWidth = stripeWidth;
this.gap = gap;
}
@Override
public int getLeadingMargin(boolean first) {
return (int) (stripeWidth + gap);
}
@Override
public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom,
CharSequence text, int start, int end, boolean first, Layout layout) {
Paint.Style style = p.getStyle();
int paintColor = p.getColor();
p.setStyle(Paint.Style.FILL);
p.setColor(stripeColor);
c.drawRect(x, top, x + dir * stripeWidth, bottom, p);
p.setStyle(style);
p.setColor(paintColor);
}
@Override
public void drawBackground(@NotNull Canvas c, @NotNull Paint p, int left, int right, int top, int baseline, int bottom, @NotNull CharSequence text, int start, int end, int lnum) {
int paintColor = p.getColor();
p.setColor(backgroundColor);
c.drawRect(left, top, right, bottom, p);
p.setColor(paintColor);
}
}

View File

@ -1,22 +1,33 @@
package app.fedilab.fedilabtube.helper;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.DownloadManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.TypedValue;
import android.view.View;
import android.view.WindowManager;
import android.webkit.CookieManager;
import android.webkit.URLUtil;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.browser.customtabs.CustomTabsIntent;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
@ -35,7 +46,10 @@ import java.util.TimeZone;
import java.util.regex.Pattern;
import app.fedilab.fedilabtube.R;
import app.fedilab.fedilabtube.WebviewActivity;
import app.fedilab.fedilabtube.client.entities.Account;
import app.fedilab.fedilabtube.webview.CustomWebview;
import app.fedilab.fedilabtube.webview.ProxyHelper;
import es.dmoral.toasty.Toasty;
import static android.content.Context.DOWNLOAD_SERVICE;
@ -77,6 +91,17 @@ public class Helper {
));
public static final int RELOAD_MYVIDEOS = 10;
public static final String SET_VIDEO_MODE = "set_video_mode";
public static final int VIDEO_MODE_TORRENT = 0;
public static final int VIDEO_MODE_WEBVIEW = 1;
public static final int VIDEO_MODE_DIRECT = 2;
public static final String SET_SHARE_DETAILS = "set_share_details";
public static final int DEFAULT_VIDEO_CACHE_MB = 100;
public static final String TAG = "mastodon_etalab";
public static final String CLIENT_NAME_VALUE = "Fedilab";
public static final String OAUTH_SCOPES = "read write follow";
@ -88,7 +113,7 @@ public class Helper {
"(?i)\\b((?:[a-z][\\w-]+:(?:/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,10}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:'\".,<>?«»“”‘’]))",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
public static final Pattern hashtagPattern = Pattern.compile("(#[\\w_A-zÀ-ÿ]+)");
public static final String SET_ALLOW_STREAM = "set_allow_stream";
public static final String SET_CUSTOM_USER_AGENT = "set_custom_user_agent";
public static final String SET_VIDEO_CACHE = "set_video_cache";
@ -101,6 +126,8 @@ public class Helper {
public static final String SET_PROXY_LOGIN = "set_proxy_login";
public static final String SET_PROXY_PASSWORD = "set_proxy_password";
public static final String INTENT_ACTION = "intent_action";
public static final String PREF_KEY_ID = "userID";
public static final String PREF_IS_MODERATOR = "is_moderator";
public static final String PREF_IS_ADMINISTRATOR = "is_administrator";
@ -108,8 +135,9 @@ public class Helper {
public static final String REDIRECT_CONTENT = "urn:ietf:wg:oauth:2.0:oob";
public static final String REDIRECT_CONTENT_WEB = "mastalab://backtomastalab";
public static final int EXTERNAL_STORAGE_REQUEST_CODE = 84;
public static final String SET_VIDEOS_PER_PAGE = "set_videos_per_page";
public static final String VIDEO_ID = "video_id_update";
public static final String CLIENT_NAME = "client_name";
public static final String APP_PREFS = "app_prefs";
public static final String ID = "id";
@ -128,6 +156,9 @@ public class Helper {
public static final String LAST_NOTIFICATION_MAX_ID = "last_notification_max_id";
public static final int VIDEOS_PER_PAGE = 40;
public static final String SET_VIDEO_NSFW = "set_video_nsfw";
public static final String SET_EMBEDDED_BROWSER = "set_embedded_browser";
public static final String SET_CUSTOM_TABS = "set_custom_tabs";
public static final String SET_DISPLAY_CONFIRM = "set_display_confirm";
/**
* Returns the peertube URL depending of the academic domain name
@ -374,7 +405,7 @@ public class Helper {
if (custom_tabs) {
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
CustomTabsIntent customTabsIntent = builder.build();
builder.setToolbarColor(ContextCompat.getColor(context, R.color.mastodonC1));
builder.setToolbarColor(ContextCompat.getColor(context, R.color.colorPrimary));
try {
customTabsIntent.launchUrl(context, Uri.parse(url));
} catch (Exception ignored) {
@ -395,6 +426,53 @@ public class Helper {
}
public static CustomWebview initializeWebview(Activity activity, int webviewId, View rootView) {
CustomWebview webView;
if (rootView == null) {
webView = activity.findViewById(webviewId);
} else {
webView = rootView.findViewById(webviewId);
}
final SharedPreferences sharedpreferences = activity.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setUseWideViewPort(true);
webView.getSettings().setLoadWithOverviewMode(true);
webView.getSettings().setSupportZoom(true);
webView.getSettings().setDisplayZoomControls(false);
webView.getSettings().setBuiltInZoomControls(true);
webView.getSettings().setAllowContentAccess(true);
webView.getSettings().setLoadsImagesAutomatically(true);
webView.getSettings().setSupportMultipleWindows(false);
webView.getSettings().setMediaPlaybackRequiresUserGesture(true);
String user_agent = sharedpreferences.getString(Helper.SET_CUSTOM_USER_AGENT, Helper.USER_AGENT);
webView.getSettings().setUserAgentString(user_agent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptThirdPartyCookies(webView, false);
}
webView.setBackgroundColor(Color.TRANSPARENT);
webView.getSettings().setAppCacheEnabled(true);
webView.getSettings().setDatabaseEnabled(true);
webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
webView.setWebChromeClient(new WebChromeClient() {
@Override
public Bitmap getDefaultVideoPoster() {
return Bitmap.createBitmap(50, 50, Bitmap.Config.ARGB_8888);
}
});
boolean proxyEnabled = sharedpreferences.getBoolean(Helper.SET_PROXY_ENABLED, false);
if (proxyEnabled) {
String host = sharedpreferences.getString(Helper.SET_PROXY_HOST, "127.0.0.1");
int port = sharedpreferences.getInt(Helper.SET_PROXY_PORT, 8118);
ProxyHelper.setProxy(activity, webView, host, port, WebviewActivity.class.getName());
}
return webView;
}
/**
* Manage downloads with URLs
*
@ -431,4 +509,31 @@ public class Helper {
alert.show();
}
/**
* change color of a drawable
*
* @param drawable int the drawable
* @param hexaColor example 0xffff00
*/
public static Drawable changeDrawableColor(Context context, int drawable, int hexaColor) {
Drawable mDrawable = ContextCompat.getDrawable(context, drawable);
int color;
try {
color = Color.parseColor(context.getString(hexaColor));
} catch (Resources.NotFoundException e) {
try {
TypedValue typedValue = new TypedValue();
Resources.Theme theme = context.getTheme();
theme.resolveAttribute(hexaColor, typedValue, true);
color = typedValue.data;
} catch (Resources.NotFoundException ed) {
color = hexaColor;
}
}
assert mDrawable != null;
mDrawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
DrawableCompat.setTint(mDrawable, color);
return mDrawable;
}
}

View File

@ -1,35 +0,0 @@
package app.fedilab.fedilabtube.ui.dashboard;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import app.fedilab.fedilabtube.R;
public class DashboardFragment extends Fragment {
private DashboardViewModel dashboardViewModel;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
dashboardViewModel =
ViewModelProviders.of(this).get(DashboardViewModel.class);
View root = inflater.inflate(R.layout.fragment_dashboard, container, false);
final TextView textView = root.findViewById(R.id.text_dashboard);
dashboardViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
textView.setText(s);
}
});
return root;
}
}

View File

@ -1,19 +0,0 @@
package app.fedilab.fedilabtube.ui.dashboard;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class DashboardViewModel extends ViewModel {
private MutableLiveData<String> mText;
public DashboardViewModel() {
mText = new MutableLiveData<>();
mText.setValue("This is dashboard fragment");
}
public LiveData<String> getText() {
return mText;
}
}

View File

@ -1,35 +0,0 @@
package app.fedilab.fedilabtube.ui.notifications;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import app.fedilab.fedilabtube.R;
public class NotificationsFragment extends Fragment {
private NotificationsViewModel notificationsViewModel;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
notificationsViewModel =
ViewModelProviders.of(this).get(NotificationsViewModel.class);
View root = inflater.inflate(R.layout.fragment_notifications, container, false);
final TextView textView = root.findViewById(R.id.text_notifications);
notificationsViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
textView.setText(s);
}
});
return root;
}
}

View File

@ -1,19 +0,0 @@
package app.fedilab.fedilabtube.ui.notifications;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class NotificationsViewModel extends ViewModel {
private MutableLiveData<String> mText;
public NotificationsViewModel() {
mText = new MutableLiveData<>();
mText.setValue("This is notifications fragment");
}
public LiveData<String> getText() {
return mText;
}
}

View File

@ -1,87 +0,0 @@
package app.fedilab.fedilabtube.ui.video;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import app.fedilab.fedilabtube.R;
import app.fedilab.fedilabtube.asynctasks.RetrieveFeedsAsyncTask;
import app.fedilab.fedilabtube.client.entities.Peertube;
public class VideoListFragment extends Fragment {
private VideoListModel videoListModel;
private LinearLayoutManager mLayoutManager;
private boolean flag_loading;
private Context context;
private AsyncTask<Void, Void, Void> asyncTask;
private PeertubeAdapter peertubeAdapater;
private String max_id;
private List<Peertube> peertubes;
private RetrieveFeedsAsyncTask.Type type;
private RelativeLayout mainLoader, nextElementLoader, textviewNoAction;
private boolean firstLoad;
private SwipeRefreshLayout swipeRefreshLayout;
private String targetedId;
private String tag;
private RecyclerView lv_status;
private boolean showMediaOnly, showPinned, showReply;
private Intent streamingFederatedIntent, streamingLocalIntent;
private boolean firstTootsLoaded;
private String userId, instance;
private SharedPreferences sharedpreferences;
private boolean isSwipped;
private String remoteInstance;
private String instanceType;
private String search_peertube, remote_channel_name;
private String initialBookMark;
private String updatedBookMark;
private String lastReadToot;
private TextView textviewNoActionText;
private boolean ischannel;
private boolean ownVideos;
private BroadcastReceiver receive_action;
private BroadcastReceiver receive_data;
private Date lastReadTootDate, initialBookMarkDate, updatedBookMarkDate;
private int timelineId;
private String currentfilter;
private View rootView;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
videoListModel =
ViewModelProviders.of(this).get(VideoListModel.class);
View root = inflater.inflate(R.layout.fragment_video, container, false);
final TextView textView = root.findViewById(R.id.text_home);
peertubes = new ArrayList<>();
videoListModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
textView.setText(s);
}
});
return root;
}
}

View File

@ -1,19 +0,0 @@
package app.fedilab.fedilabtube.ui.video;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class VideoListModel extends ViewModel {
private MutableLiveData<String> mText;
public VideoListModel() {
mText = new MutableLiveData<>();
mText.setValue("This is home fragment");
}
public LiveData<String> getText() {
return mText;
}
}

View File

@ -14,18 +14,14 @@ import android.widget.TextView;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.List;
import app.fedilab.fedilabtube.R;
public class MastalabWebViewClient extends WebViewClient {
public List<String> domains = new ArrayList<>();
private Activity activity;
private int count = 0;
public MastalabWebViewClient(Activity activity) {
this.activity = activity;
@ -37,11 +33,6 @@ public class MastalabWebViewClient extends WebViewClient {
}
public List<String> getDomains() {
return this.domains;
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (URLUtil.isNetworkUrl(url)) {
@ -56,9 +47,6 @@ public class MastalabWebViewClient extends WebViewClient {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
count = 0;
domains = new ArrayList<>();
domains.clear();
ActionBar actionBar = ((AppCompatActivity) activity).getSupportActionBar();
LayoutInflater mInflater = LayoutInflater.from(activity);
if (actionBar != null) {

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="M17,3H7c-1.1,0 -1.99,0.9 -1.99,2L5,21l7,-3 7,3V5c0,-1.1 -0.9,-2 -2,-2z"/>
</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="M17,3L7,3c-1.1,0 -1.99,0.9 -1.99,2L5,21l7,-3 7,3L19,5c0,-1.1 -0.9,-2 -2,-2zM17,18l-5,-2.18L7,18L7,5h10v13z"/>
</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="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
</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="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
</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="M7,14L5,14v5h5v-2L7,17v-3zM5,10h2L7,7h3L10,5L5,5v5zM17,17h-3v2h5v-5h-2v3zM14,5v2h3v3h2L19,5h-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="M5,16h3v3h2v-5L5,14v2zM8,8L5,8v2h5L10,5L8,5v3zM14,19h2v-3h3v-2h-5v5zM16,8L16,5h-2v5h5L19,8h-3z"/>
</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="M22,4h-2c-0.55,0 -1,0.45 -1,1v9c0,0.55 0.45,1 1,1h2V4zM2.17,11.12c-0.11,0.25 -0.17,0.52 -0.17,0.8V13c0,1.1 0.9,2 2,2h5.5l-0.92,4.65c-0.05,0.22 -0.02,0.46 0.08,0.66 0.23,0.45 0.52,0.86 0.88,1.22L10,22l6.41,-6.41c0.38,-0.38 0.59,-0.89 0.59,-1.42V6.34C17,5.05 15.95,4 14.66,4h-8.1c-0.71,0 -1.36,0.37 -1.72,0.97l-2.67,6.15z"/>
</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="M2,20h2c0.55,0 1,-0.45 1,-1v-9c0,-0.55 -0.45,-1 -1,-1L2,9v11zM21.83,12.88c0.11,-0.25 0.17,-0.52 0.17,-0.8L22,11c0,-1.1 -0.9,-2 -2,-2h-5.5l0.92,-4.65c0.05,-0.22 0.02,-0.46 -0.08,-0.66 -0.23,-0.45 -0.52,-0.86 -0.88,-1.22L14,2 7.59,8.41C7.21,8.79 7,9.3 7,9.83v7.84C7,18.95 8.05,20 9.34,20h8.11c0.7,0 1.36,-0.37 1.72,-0.97l2.66,-6.15z"/>
</vector>

View File

@ -0,0 +1,302 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:keepScreenOn="true"
tools:context=".PeertubeActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<FrameLayout
android:id="@+id/main_media_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:background="#000000"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.exoplayer2.ui.PlayerView
android:id="@+id/media_video"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" />
<app.fedilab.android.webview.CustomWebview
android:id="@+id/webview_video"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
</FrameLayout>
<!-- Main Loader -->
<RelativeLayout
android:id="@+id/loader"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:visibility="gone">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
</RelativeLayout>
</RelativeLayout>
<ScrollView
android:id="@+id/peertube_information_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp"
android:orientation="vertical">
<TextView
android:id="@+id/peertube_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:orientation="horizontal">
<TextView
android:id="@+id/peertube_view_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:drawableTop="@drawable/ic_visibility_peertube"
android:drawablePadding="5dp"
android:gravity="center_horizontal"
android:text="0"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/peertube_like_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginStart="20dp"
android:layout_marginLeft="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:drawableTop="@drawable/ic_thumb_up_peertube"
android:drawablePadding="5dp"
android:gravity="center_horizontal"
android:text="0"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/peertube_dislike_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:drawableTop="@drawable/ic_thumb_down_peertube"
android:drawablePadding="5dp"
android:gravity="center_horizontal"
android:text="0"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/peertube_bookmark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:drawableTop="@drawable/ic_bookmark_peertube_border"
android:drawablePadding="5dp"
android:gravity="center_horizontal"
android:text="" />
<TextView
android:id="@+id/peertube_playlist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:drawableTop="@drawable/ic_list_peertube_activity"
android:drawablePadding="5dp"
android:gravity="center_horizontal"
android:text=""
android:visibility="gone" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
tools:ignore="UselessLeaf" />
<TextView
android:id="@+id/peertube_share"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:drawableTop="@drawable/ic_share_peertube"
android:drawablePadding="5dp"
android:gravity="center_horizontal"
android:text="@string/more_action_6"
android:textSize="12sp" />
<TextView
android:id="@+id/peertube_download"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginStart="10dp"
android:layout_marginLeft="10dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:drawableTop="@drawable/ic_cloud_download_peertube"
android:drawablePadding="5dp"
android:gravity="center_horizontal"
android:text="@string/download"
android:textSize="12sp" />
</LinearLayout>
<TextView
android:id="@+id/peertube_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp" />
<LinearLayout
android:id="@+id/write_comment_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="10dp"
android:orientation="horizontal"
android:visibility="gone">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/my_pp"
android:layout_width="40dp"
android:layout_height="40dp"
android:contentDescription="@string/profile_picture" />
<ImageView
android:id="@+id/send"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginTop="5dp"
android:contentDescription="@string/send_comment"
android:src="@drawable/ic_send"
android:visibility="gone" />
</LinearLayout>
<LinearLayout
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:text="@string/add_public_comment" />
<EditText
android:id="@+id/add_comment_write"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:hint="@string/add_public_comment"
android:inputType="textMultiLine"
android:maxLines="4"
android:overScrollMode="always"
android:scrollbarStyle="insideInset"
android:scrollbars="vertical"
android:visibility="gone" />
</LinearLayout>
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/peertube_comments"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<RelativeLayout
android:id="@+id/no_action"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone">
<TextView
android:id="@+id/no_action_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:padding="10dp"
android:text="@string/no_comments"
android:textSize="25sp"
android:textStyle="italic|bold"
android:typeface="serif" />
</RelativeLayout>
</LinearLayout>
</ScrollView>
<!-- View where the video will be shown when video goes fullscreen -->
<RelativeLayout
android:id="@+id/videoLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
android:visibility="gone" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,258 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:TagsEditText="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:layout_marginStart="@dimen/fab_margin"
android:layout_marginLeft="@dimen/fab_margin"
android:layout_marginEnd="@dimen/fab_margin"
android:layout_marginRight="@dimen/fab_margin"
tools:context=".PeertubeUploadActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- Video title -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:labelFor="@+id/p_video_title"
android:text="@string/title" />
<EditText
android:id="@+id/p_video_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text" />
</LinearLayout>
<!-- Video tags -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:labelFor="@+id/p_video_tags"
android:text="@string/tags" />
<mabbas007.tagsedittext.TagsEditText
android:id="@+id/p_video_tags"
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" />
</LinearLayout>
<!-- video description -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:labelFor="@+id/p_video_description"
android:text="@string/description" />
<EditText
android:id="@+id/p_video_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textMultiLine"
android:lines="5"
android:maxLines="5"
android:scrollbars="vertical" />
</LinearLayout>
<!-- Videos channels -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/channel" />
<Spinner
android:id="@+id/set_upload_channel"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<!-- Videos categories -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/category" />
<Spinner
android:id="@+id/set_upload_categories"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<!-- Videos licences -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/license" />
<Spinner
android:id="@+id/set_upload_licenses"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<!-- Videos languages -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/language" />
<Spinner
android:id="@+id/set_upload_languages"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<!-- Videos Privacy -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/action_privacy" />
<Spinner
android:id="@+id/set_upload_privacy"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<!-- More options -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="20dp"
android:gravity="center_vertical"
android:orientation="vertical">
<CheckBox
android:id="@+id/set_upload_nsfw"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/peertube_nsfw" />
<CheckBox
android:id="@+id/set_upload_enable_comments"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/peertube_enable_comments" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="40dp"
android:orientation="horizontal">
<!-- Videos upload edit submit -->
<Button
android:id="@+id/set_upload_delete"
style="@style/Base.Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="10dp"
android:backgroundTint="@color/unfollow"
android:gravity="center"
android:text="@string/delete_video" />
<!-- Videos upload edit submit -->
<Button
android:id="@+id/set_upload_submit"
style="@style/Base.Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="10dp"
android:enabled="false"
android:gravity="center"
android:text="@string/update_video" />
</LinearLayout>
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".PeertubeUploadActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<Button
android:id="@+id/set_upload_file"
style="@style/Base.Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:enabled="false"
android:gravity="center"
android:text="@string/file_to_upload"
android:textSize="16sp" />
<TextView
android:id="@+id/set_upload_file_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:gravity="center"
android:visibility="gone" />
<!-- Videos channels -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/channel"
android:textSize="16sp" />
<Spinner
android:id="@+id/set_upload_channel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp" />
</LinearLayout>
<!-- Videos Privacy -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:gravity="center_horizontal"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="@string/action_privacy"
android:textSize="16sp" />
<Spinner
android:id="@+id/set_upload_privacy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp" />
</LinearLayout>
<EditText
android:id="@+id/video_title"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:hint="@string/title_video_peertube"
android:inputType="text"
android:singleLine="true" />
<!-- Videos upload submit -->
<Button
android:id="@+id/set_upload_submit"
style="@style/Base.Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="40dp"
android:enabled="false"
android:gravity="center"
android:text="@string/upload_video"
android:textSize="18sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="10dp"
android:padding="1dp" />
<FrameLayout
android:id="@+id/webview_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<app.fedilab.fedilabtube.webview.CustomWebview
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white" />
</FrameLayout>
<!-- View where the video will be shown when video goes fullscreen -->
<RelativeLayout
android:id="@+id/videoLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/black"
android:visibility="gone" />
</LinearLayout>
</androidx.drawerlayout.widget.DrawerLayout>

View File

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/main_container"
android:paddingTop="10dp"
android:divider="?android:dividerHorizontal"
android:showDividers="end"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="10dp"
android:baselineAligned="false">
<ImageView
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_marginTop="5dp"
android:id="@+id/status_account_profile"
android:contentDescription="@string/profile_picture" />
<LinearLayout
android:layout_marginStart="10dp"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/status_account_displayname"
android:maxLines="1"
android:drawablePadding="2dp"
android:layout_marginTop="-2dp"
android:layout_marginStart="-2dp"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/status_account_displayname_owner"
android:maxLines="1"
android:drawablePadding="2dp"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_marginStart="5dp"
android:textSize="12sp"
android:maxLines="1"
android:ellipsize="end"
android:layout_width="0dp"
android:layout_weight="1"
android:id="@+id/status_account_username"
android:layout_height="wrap_content" />
<TextView
android:layout_marginStart="2dp"
android:id="@+id/status_toot_date"
android:layout_width="wrap_content"
android:layout_weight="0"
android:maxLines="1"
android:textSize="12sp"
android:layout_gravity="end"
android:gravity="end"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/status_content_container"
android:layout_width="match_parent"
android:layout_marginBottom="5dp"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:id="@+id/status_content"
android:textIsSelectable="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<TextView
android:id="@+id/status_peertube_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="15dp"
android:drawablePadding="2dp"
android:gravity="center_vertical"
android:text="@string/delete"
android:textColor="?colorAccent"
android:visibility="gone" />
</LinearLayout>

View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#CC000000"
android:layoutDirection="ltr"
android:orientation="vertical"
tools:targetApi="28">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:paddingTop="4dp">
<ImageButton
android:id="@id/exo_prev"
style="@style/ExoMediaButton.Previous" />
<ImageButton
android:id="@id/exo_rew"
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
android:id="@id/exo_play"
style="@style/ExoMediaButton.Play" />
<ImageButton
android:id="@id/exo_pause"
style="@style/ExoMediaButton.Pause" />
<ImageButton
android:id="@id/exo_ffwd"
style="@style/ExoMediaButton.FastForward" />
<ImageButton
android:id="@id/exo_next"
style="@style/ExoMediaButton.Next" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/resolution"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:textColor="#FFBEBEBE"
android:textSize="12sp" />
<TextView
android:id="@id/exo_position"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:textColor="#FFBEBEBE"
android:textSize="14sp"
android:textStyle="bold" />
<com.google.android.exoplayer2.ui.DefaultTimeBar
android:id="@id/exo_progress"
android:layout_width="0dp"
android:layout_height="26dp"
android:layout_weight="1" />
<TextView
android:id="@id/exo_duration"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:paddingLeft="4dp"
android:paddingRight="4dp"
android:textColor="#FFBEBEBE"
android:textSize="14sp"
android:textStyle="bold" />
<FrameLayout
android:id="@+id/exo_fullscreen_button"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="end">
<ImageView
android:id="@+id/exo_fullscreen_icon"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_gravity="center"
android:adjustViewBounds="true"
android:contentDescription="@string/fullscreen"
android:scaleType="fitCenter"
android:src="@drawable/ic_baseline_fullscreen_24" />
</FrameLayout>
</LinearLayout>
</LinearLayout>

View File

@ -3,7 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.video.VideoListFragment">
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar 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:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?colorPrimary"
android:contentInsetStart="0dp"
android:contentInsetLeft="0dp"
android:contentInsetEnd="0dp"
android:contentInsetRight="0dp"
app:contentInsetEnd="0dp"
app:contentInsetLeft="0dp"
app:contentInsetRight="0dp"
app:contentInsetStart="0dp"
tools:ignore="UnusedAttribute">
<ImageView
android:id="@+id/toolbar_close"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginEnd="10dp"
android:contentDescription="@string/close"
android:gravity="center_vertical"
android:src="@drawable/ic_baseline_close_24"
/>
<TextView
android:id="@+id/toolbar_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:ellipsize="end"
android:scrollHorizontally="true"
android:singleLine="true"
android:textSize="16sp" />
</androidx.appcompat.widget.Toolbar>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
tools:ignore="UseCompoundDrawables">
<ImageView
android:id="@+id/webview_favicon"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center_vertical"
android:contentDescription="@string/favicon" />
<TextView
android:id="@+id/webview_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="5dp"
android:layout_weight="1"
android:singleLine="true"
android:textSize="12sp" />
</LinearLayout>

View File

@ -0,0 +1,31 @@
<?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_open_browser"
android:icon="@drawable/ic_open_with"
android:title="@string/action_open_in_web"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_mute"
android:icon="@drawable/ic_volume_mute"
android:title="@string/more_action_1"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_block"
android:icon="@drawable/ic_block"
android:title="@string/more_action_2"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_report"
android:icon="@drawable/ic_block"
android:title="@string/more_action_3"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_block_instance"
android:icon="@drawable/ic_block"
android:title="@string/block_domain"
app:showAsAction="ifRoom" />
</menu>

View File

@ -0,0 +1,9 @@
<?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_go"
android:icon="@drawable/ic_open_with"
android:title="@string/open_with"
app:showAsAction="always" />
</menu>

View File

@ -3,4 +3,8 @@
<color name="colorPrimary">#6200EE</color>
<color name="colorPrimaryDark">#3700B3</color>
<color name="colorAccent">#03DAC5</color>
<color name="positive_thumbs">#2b90d9</color>
<color name="negative_thumbs">#F44336</color>
</resources>

View File

@ -11,7 +11,7 @@
<string name="toast_error">Une erreur s\'est produite !</string>
<string name="no_videos">Aucune vidéo !</string>
<string name="favicon">Favicon</string>
<string name="open_with">Ouvrir avec</string>
<string name="close">Fermer</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>
@ -20,7 +20,13 @@
<string name="channel">Chaîne</string>
<string name="videos">Vidéos</string>
<string name="channels">Chaînes</string>
<string name="yes">Oui</string>
<string name="no">Non</string>
<string name="cancel">Annuler</string>
<string name="download">Télécharger</string>
<string name="profile_picture">Photo du profil</string>
<string name="update_video">Mettre à jour la vidéo</string>
<!-- Date -->
<string name="date_seconds">%d s</string>
<string name="date_minutes">%d min</string>
@ -29,4 +35,42 @@
<string name="number_view_video">%s vues</string>
<string name="duration_video">Durée : %s</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="upload_video_success">La vidéo a été transférée !</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="toot_select_image">Sélectionnez un média</string>
<string name="download_file">Télécharger %1$s</string>
<string name="delete_video_confirmation">Êtes-vous sûr de vouloir supprimer cette vidéo ?</string>
<string name="toast_peertube_video_updated">La vidéo a été mise à jour !</string>
<string name="comment_no_allowed_peertube">Les commentaires sur cette vidéos ont été désactivés !</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="shared_via">Partagé via Fedilab Tube</string>
<string name="share_with">Partager avec</string>
<string name="pickup_resolution">Choisissez une résolution</string>
<string name="fullscreen">Vidéo plein écran</string>
<string name="comment">Commenter</string>
<string name="validate">Valider</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="toot_sent">Le message a été envoyé !</string>
<string name="reply">Répondre</string>
<string name="delete">Supprimer</string>
<string name="no_video_to_display">Aucune vidéo nest disponible !</string>
</resources>