package app.fedilab.fedilabtube; import android.Manifest; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; 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.Drawable; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.text.Html; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; import android.widget.ScrollView; import android.widget.TextView; import android.widget.Toast; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.AppCompatImageView; import androidx.appcompat.widget.PopupMenu; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.google.android.exoplayer2.ExoPlayerFactory; import com.google.android.exoplayer2.SimpleExoPlayer; import com.google.android.exoplayer2.source.ProgressiveMediaSource; import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; 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.util.Util; import org.jetbrains.annotations.NotNull; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; import java.util.Objects; import javax.net.ssl.HttpsURLConnection; import app.fedilab.fedilabtube.asynctasks.ManagePlaylistsAsyncTask; import app.fedilab.fedilabtube.asynctasks.PostActionAsyncTask; 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; import app.fedilab.fedilabtube.interfaces.OnPostActionInterface; import app.fedilab.fedilabtube.interfaces.OnRetrievePeertubeInterface; import app.fedilab.fedilabtube.sqlite.AccountDAO; import app.fedilab.fedilabtube.sqlite.PeertubeFavoritesDAO; import app.fedilab.fedilabtube.sqlite.Sqlite; import app.fedilab.fedilabtube.webview.CustomWebview; 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 { public static String video_id; private String peertubeInstance, videoId; private FullScreenMediaController.fullscreen fullscreen; private RelativeLayout loader; private TextView peertube_view_count, peertube_playlist, peertube_bookmark, peertube_like_count, peertube_dislike_count, peertube_share, peertube_download, peertube_description, peertube_title; private ScrollView peertube_information_container; private Peertube peertube; private TextView toolbar_title; private PlayerView playerView; private SimpleExoPlayer player; private boolean fullScreenMode; private Dialog fullScreenDialog; private AppCompatImageView fullScreenIcon; private TextView resolution; private int mode; private LinearLayout write_comment_container; private ImageView send; private TextView add_comment_read; private EditText add_comment_write; private String instance; private List playlistForVideo; private List playlists; public static void hideKeyboard(Activity activity) { if (activity != null && activity.getWindow() != null) { activity.getWindow().getDecorView(); InputMethodManager imm = (InputMethodManager) activity.getSystemService(INPUT_METHOD_SERVICE); assert imm != null; imm.hideSoftInputFromWindow(activity.getWindow().getDecorView().getWindowToken(), 0); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE); fullscreen = FullScreenMediaController.fullscreen.OFF; fullScreenMode = false; playlistForVideo = new ArrayList<>(); setContentView(R.layout.activity_peertube); loader = findViewById(R.id.loader); peertube_view_count = findViewById(R.id.peertube_view_count); peertube_bookmark = findViewById(R.id.peertube_bookmark); peertube_like_count = findViewById(R.id.peertube_like_count); peertube_dislike_count = findViewById(R.id.peertube_dislike_count); peertube_share = findViewById(R.id.peertube_share); peertube_download = findViewById(R.id.peertube_download); peertube_description = findViewById(R.id.peertube_description); peertube_title = findViewById(R.id.peertube_title); peertube_information_container = findViewById(R.id.peertube_information_container); CustomWebview webview_video = findViewById(R.id.webview_video); playerView = findViewById(R.id.media_video); write_comment_container = findViewById(R.id.write_comment_container); ImageView my_pp = findViewById(R.id.my_pp); add_comment_read = findViewById(R.id.add_comment_read); add_comment_write = findViewById(R.id.add_comment_write); peertube_playlist = findViewById(R.id.peertube_playlist); send = findViewById(R.id.send); add_comment_read.setOnClickListener(v -> { add_comment_read.setVisibility(View.GONE); add_comment_write.setVisibility(View.VISIBLE); send.setVisibility(View.VISIBLE); add_comment_write.requestFocus(); add_comment_write.setSelection(add_comment_write.getText().length()); }); peertube_playlist.setVisibility(View.VISIBLE); peertube_bookmark.setVisibility(View.GONE); send.setOnClickListener(v -> { String comment = add_comment_write.getText().toString(); if (comment.trim().length() > 0) { new PostActionAsyncTask(PeertubeActivity.this, PeertubeAPI.StatusAction.PEERTUBECOMMENT, peertube.getId(), null, comment, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); add_comment_write.setText(""); add_comment_read.setVisibility(View.VISIBLE); add_comment_write.setVisibility(View.GONE); send.setVisibility(View.GONE); add_comment_read.requestFocus(); } }); SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); instance = sharedpreferences.getString(Helper.PREF_INSTANCE, Helper.getLiveInstance(PeertubeActivity.this)); Account account = new AccountDAO(PeertubeActivity.this, db).getUniqAccount(userId, instance); Helper.loadGiF(PeertubeActivity.this, account, my_pp); Bundle b = getIntent().getExtras(); if (b != null) { peertubeInstance = b.getString("peertube_instance", null); videoId = b.getString("video_id", null); } if (getSupportActionBar() != null) getSupportActionBar().setDisplayHomeAsUpEnabled(true); ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE); assert inflater != null; View view = inflater.inflate(R.layout.simple_bar, new LinearLayout(PeertubeActivity.this), false); 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); toolbar_title = actionBar.getCustomView().findViewById(R.id.toolbar_title); toolbar_close.setOnClickListener(v -> finish()); } mode = sharedpreferences.getInt(Helper.SET_VIDEO_MODE, Helper.VIDEO_MODE_DIRECT); if (mode != Helper.VIDEO_MODE_WEBVIEW && mode != Helper.VIDEO_MODE_DIRECT) mode = Helper.VIDEO_MODE_DIRECT; if (mode == Helper.VIDEO_MODE_WEBVIEW) { webview_video.setVisibility(View.VISIBLE); playerView.setVisibility(View.GONE); webview_video = Helper.initializeWebview(PeertubeActivity.this, R.id.webview_video, null); FrameLayout webview_container = findViewById(R.id.main_media_frame); final ViewGroup videoLayout = findViewById(R.id.videoLayout); MastalabWebChromeClient mastalabWebChromeClient = new MastalabWebChromeClient(PeertubeActivity.this, webview_video, 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); peertube_information_container.setVisibility(View.GONE); } 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); peertube_information_container.setVisibility(View.VISIBLE); } }); String user_agent = sharedpreferences.getString(Helper.SET_CUSTOM_USER_AGENT, Helper.USER_AGENT); webview_video.getSettings().setUserAgentString(user_agent); webview_video.getSettings().setAllowFileAccess(true); webview_video.setWebChromeClient(mastalabWebChromeClient); webview_video.getSettings().setDomStorageEnabled(true); webview_video.getSettings().setAppCacheEnabled(true); webview_video.getSettings().setMediaPlaybackRequiresUserGesture(false); webview_video.setWebViewClient(new MastalabWebViewClient(PeertubeActivity.this)); webview_video.loadUrl("https://" + peertubeInstance + "/videos/embed/" + videoId); } else { webview_video.setVisibility(View.GONE); playerView.setVisibility(View.VISIBLE); loader.setVisibility(View.VISIBLE); } if (mode != Helper.VIDEO_MODE_WEBVIEW) { playerView.setControllerShowTimeoutMs(1000); playerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIT); initFullscreenDialog(); initFullscreenButton(); } 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); } public void change() { if (fullscreen == FullScreenMediaController.fullscreen.ON) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); Objects.requireNonNull(getSupportActionBar()).hide(); peertube_information_container.setVisibility(View.GONE); } else { getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN, WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN); Objects.requireNonNull(getSupportActionBar()).show(); peertube_information_container.setVisibility(View.VISIBLE); } } @Override public boolean dispatchTouchEvent(MotionEvent ev) { View v = getCurrentFocus(); if ((ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE) && v instanceof EditText && v.getId() == R.id.add_comment_write) { int[] scrcoords = new int[2]; v.getLocationOnScreen(scrcoords); float x = ev.getRawX() + v.getLeft() - scrcoords[0]; float y = ev.getRawY() + v.getTop() - scrcoords[1]; if (x < v.getLeft() || x > v.getRight() || y < v.getTop() || y > v.getBottom()) { add_comment_read.setVisibility(View.VISIBLE); add_comment_write.setVisibility(View.GONE); send.setVisibility(View.GONE); hideKeyboard(PeertubeActivity.this); } } return super.dispatchTouchEvent(ev); } @Override public boolean onCreateOptionsMenu(@NotNull Menu menu) { getMenuInflater().inflate(R.menu.main_webview, menu); menu.findItem(R.id.action_go).setVisible(false); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { finish(); return true; } return super.onOptionsItemSelected(item); } public FullScreenMediaController.fullscreen getFullscreen() { return fullscreen; } public void setFullscreen(FullScreenMediaController.fullscreen fullscreen) { this.fullscreen = fullscreen; } @Override public void onRetrievePeertube(APIResponse apiResponse) { if (apiResponse == null || (apiResponse.getError() != null) || apiResponse.getPeertubes() == null || apiResponse.getPeertubes().size() == 0) { Toasty.error(PeertubeActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show(); loader.setVisibility(View.GONE); return; } if (apiResponse.getPeertubes() == null || apiResponse.getPeertubes().get(0) == null || apiResponse.getPeertubes().get(0).getFileUrl(null, apiResponse.getPeertubes().get(0).isStreamService()) == null) { Toasty.error(PeertubeActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show(); loader.setVisibility(View.GONE); return; } peertube = apiResponse.getPeertubes().get(0); new ManagePlaylistsAsyncTask(PeertubeActivity.this, GET_PLAYLIST_FOR_VIDEO, null, peertube.getId(), null, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); peertube_playlist.setOnClickListener(v -> { if (playlists != null && peertube.getId() != null) { PopupMenu popup = new PopupMenu(PeertubeActivity.this, peertube_playlist); for (Playlist playlist : playlists) { String title = null; for (String id : playlistForVideo) { if (playlist.getId().equals(id)) { title = "✔ " + playlist.getDisplayName(); break; } } if (title == null) { title = playlist.getDisplayName(); } MenuItem item = popup.getMenu().add(0, 0, Menu.NONE, title); item.setOnMenuItemClickListener(item1 -> { item1.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW); item1.setActionView(new View(PeertubeActivity.this)); item1.setOnActionExpandListener(new MenuItem.OnActionExpandListener() { @Override public boolean onMenuItemActionExpand(MenuItem item1) { return false; } @Override public boolean onMenuItemActionCollapse(MenuItem item1) { return false; } }); if (playlistForVideo.contains(playlist.getId())) { item1.setTitle(playlist.getDisplayName()); new ManagePlaylistsAsyncTask(PeertubeActivity.this, ManagePlaylistsAsyncTask.action.DELETE_VIDEOS, playlist, peertube.getId(), null, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); playlistForVideo.remove(playlist.getId()); } else { item1.setTitle("✔ " + playlist.getDisplayName()); new ManagePlaylistsAsyncTask(PeertubeActivity.this, ManagePlaylistsAsyncTask.action.ADD_VIDEOS, playlist, peertube.getId(), null, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); playlistForVideo.add(playlist.getId()); } return false; }); popup.show(); } } }); if (peertube.isCommentsEnabled()) { new RetrievePeertubeSingleCommentsAsyncTask(PeertubeActivity.this, peertubeInstance, videoId, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); write_comment_container.setVisibility(View.VISIBLE); } else { RelativeLayout no_action = findViewById(R.id.no_action); TextView no_action_text = findViewById(R.id.no_action_text); no_action_text.setText(getString(R.string.comment_no_allowed_peertube)); no_action.setVisibility(View.VISIBLE); write_comment_container.setVisibility(View.GONE); } SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE); toolbar_title.setText(peertube.getName()); peertube_description.setText(peertube.getDescription()); peertube_title.setText(peertube.getName()); peertube_dislike_count.setText(String.valueOf(peertube.getDislike())); peertube_like_count.setText(String.valueOf(peertube.getLike())); peertube_view_count.setText(String.valueOf(peertube.getView())); video_id = peertube.getId(); changeColor(); initResolution(); peertube_like_count.setOnClickListener(v -> { String newState = peertube.getMyRating().equals("like") ? "none" : "like"; new PostActionAsyncTask(PeertubeActivity.this, PeertubeAPI.StatusAction.RATEVIDEO, peertube.getId(), null, newState, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); peertube.setMyRating(newState); changeColor(); }); peertube_dislike_count.setOnClickListener(v -> { String newState = peertube.getMyRating().equals("dislike") ? "none" : "dislike"; new PostActionAsyncTask(PeertubeActivity.this, PeertubeAPI.StatusAction.RATEVIDEO, peertube.getId(), null, newState, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); peertube.setMyRating(newState); changeColor(); }); try { HttpsURLConnection.setDefaultSSLSocketFactory(new TLSSocketFactory(instance)); } catch (KeyManagementException | NoSuchAlgorithmException e) { e.printStackTrace(); } if (mode == Helper.VIDEO_MODE_DIRECT) { String userAgent = sharedpreferences.getString(Helper.SET_CUSTOM_USER_AGENT, Helper.USER_AGENT); int video_cache = sharedpreferences.getInt(Helper.SET_VIDEO_CACHE, Helper.DEFAULT_VIDEO_CACHE_MB); ProgressiveMediaSource videoSource; if (video_cache == 0) { DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(PeertubeActivity.this, Util.getUserAgent(PeertubeActivity.this, userAgent), null); videoSource = new ProgressiveMediaSource.Factory(dataSourceFactory) .createMediaSource(Uri.parse(apiResponse.getPeertubes().get(0).getFileUrl(null, apiResponse.getPeertubes().get(0).isStreamService()))); } else { CacheDataSourceFactory cacheDataSourceFactory = new CacheDataSourceFactory(PeertubeActivity.this); videoSource = new ProgressiveMediaSource.Factory(cacheDataSourceFactory) .createMediaSource(Uri.parse(apiResponse.getPeertubes().get(0).getFileUrl(null, apiResponse.getPeertubes().get(0).isStreamService()))); } player = ExoPlayerFactory.newSimpleInstance(PeertubeActivity.this); playerView.setPlayer(player); loader.setVisibility(View.GONE); player.prepare(videoSource); player.setPlayWhenReady(true); } peertube_download.setOnClickListener(v -> { if (Build.VERSION.SDK_INT >= 23) { if (ContextCompat.checkSelfPermission(PeertubeActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(PeertubeActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(PeertubeActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, Helper.EXTERNAL_STORAGE_REQUEST_CODE); } else { Helper.manageDownloads(PeertubeActivity.this, peertube.getFileDownloadUrl(null, peertube.isStreamService())); } } else { Helper.manageDownloads(PeertubeActivity.this, peertube.getFileDownloadUrl(null, peertube.isStreamService())); } }); SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); List peertubes = new PeertubeFavoritesDAO(PeertubeActivity.this, db).getSinglePeertube(peertube); Drawable img; if (peertubes == null || peertubes.size() == 0) img = ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_bookmark_border_24); else img = ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_bookmark_24); peertube_bookmark.setCompoundDrawablesWithIntrinsicBounds(null, img, null, null); peertube_bookmark.setOnClickListener(v -> { List peertubes1 = new PeertubeFavoritesDAO(PeertubeActivity.this, db).getSinglePeertube(peertube); if (peertubes1 == null || peertubes1.size() == 0) { new PeertubeFavoritesDAO(PeertubeActivity.this, db).insert(peertube); Toasty.success(PeertubeActivity.this, getString(R.string.bookmark_add_peertube), Toast.LENGTH_SHORT).show(); } else { new PeertubeFavoritesDAO(PeertubeActivity.this, db).remove(peertube); 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_baseline_bookmark_border_24), null, null); else peertube_bookmark.setCompoundDrawablesWithIntrinsicBounds(null, ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_bookmark_24), null, null); }); peertube_share.setOnClickListener(v -> { Intent sendIntent = new Intent(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.shared_via)); String url; url = "https://" + peertube.getInstance() + "/videos/watch/" + peertube.getUuid(); boolean share_details = sharedpreferences.getBoolean(Helper.SET_SHARE_DETAILS, true); String extra_text; if (share_details) { extra_text = "@" + peertube.getAccount().getAcct(); extra_text += "\r\n\r\n" + peertube.getName(); extra_text += "\n\n\uD83D\uDD17 " + url + "\r\n-\n"; final String contentToot; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) contentToot = Html.fromHtml(peertube.getDescription(), Html.FROM_HTML_MODE_LEGACY).toString(); else contentToot = Html.fromHtml(peertube.getDescription()).toString(); extra_text += contentToot; } else { extra_text = url; } sendIntent.putExtra(Intent.EXTRA_TEXT, extra_text); sendIntent.setType("text/plain"); startActivity(Intent.createChooser(sendIntent, getString(R.string.share_with))); }); } @Override public void onConfigurationChanged(@NotNull Configuration newConfig) { super.onConfigurationChanged(newConfig); if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { if (mode != Helper.VIDEO_MODE_WEBVIEW) { openFullscreenDialog(); } setFullscreen(FullScreenMediaController.fullscreen.ON); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) { if (mode != Helper.VIDEO_MODE_WEBVIEW) { closeFullscreenDialog(); } setFullscreen(FullScreenMediaController.fullscreen.OFF); } change(); } @Override public void onRetrievePeertubeComments(APIResponse apiResponse) { if (apiResponse == null || (apiResponse.getError() != null && apiResponse.getError().getStatusCode() != 404 && apiResponse.getError() != null && apiResponse.getError().getStatusCode() != 501)) { if (apiResponse == null) Toasty.error(PeertubeActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show(); else Toasty.error(PeertubeActivity.this, apiResponse.getError().getError(), Toast.LENGTH_LONG).show(); return; } List statuses = apiResponse.getStatuses(); RecyclerView lv_comments = findViewById(R.id.peertube_comments); if (statuses != null && statuses.size() > 0) { lv_comments.setVisibility(View.VISIBLE); SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE); String userId = sharedpreferences.getString(Helper.PREF_KEY_ID, null); StatusDrawerParams statusDrawerParams = new StatusDrawerParams(); statusDrawerParams.setTargetedId(userId); statusDrawerParams.setStatuses(statuses); StatusListAdapter statusListAdapter = new StatusListAdapter(statusDrawerParams); LinearLayoutManager mLayoutManager = new LinearLayoutManager(PeertubeActivity.this); lv_comments.setLayoutManager(mLayoutManager); lv_comments.setNestedScrollingEnabled(false); lv_comments.setAdapter(statusListAdapter); } } @Override public void onRetrievePeertubeChannels(APIResponse apiResponse) { } @Override public void onDestroy() { super.onDestroy(); if (player != null) player.release(); } @Override protected void onPause() { super.onPause(); if (player != null) { player.setPlayWhenReady(false); } } @Override public void onResume() { super.onResume(); if (player != null) { player.setPlayWhenReady(true); } } public void displayResolution() { SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE); AlertDialog.Builder builderSingle = new AlertDialog.Builder(PeertubeActivity.this); builderSingle.setTitle(R.string.pickup_resolution); final ArrayAdapter arrayAdapter = new ArrayAdapter<>(PeertubeActivity.this, android.R.layout.select_dialog_item); for (String resolution : peertube.getResolution()) arrayAdapter.add(resolution + "p"); builderSingle.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss()); builderSingle.setAdapter(arrayAdapter, (dialog, which) -> { String res = Objects.requireNonNull(arrayAdapter.getItem(which)).substring(0, Objects.requireNonNull(arrayAdapter.getItem(which)).length() - 1); if (playerView != null) { loader.setVisibility(View.VISIBLE); long position = player.getCurrentPosition(); PlayerControlView controlView = playerView.findViewById(R.id.exo_controller); resolution = controlView.findViewById(R.id.resolution); resolution.setText(String.format("%sp", res)); if (mode == Helper.VIDEO_MODE_DIRECT) { if (player != null) player.release(); player = ExoPlayerFactory.newSimpleInstance(PeertubeActivity.this); playerView.setPlayer(player); loader.setVisibility(View.GONE); String userAgent = sharedpreferences.getString(Helper.SET_CUSTOM_USER_AGENT, Helper.USER_AGENT); int video_cache = sharedpreferences.getInt(Helper.SET_VIDEO_CACHE, Helper.DEFAULT_VIDEO_CACHE_MB); ProgressiveMediaSource videoSource; if (video_cache == 0) { DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(PeertubeActivity.this, Util.getUserAgent(PeertubeActivity.this, userAgent), null); videoSource = new ProgressiveMediaSource.Factory(dataSourceFactory) .createMediaSource(Uri.parse(peertube.getFileUrl(res, peertube.isStreamService()))); } else { CacheDataSourceFactory cacheDataSourceFactory = new CacheDataSourceFactory(PeertubeActivity.this); videoSource = new ProgressiveMediaSource.Factory(cacheDataSourceFactory) .createMediaSource(Uri.parse(peertube.getFileUrl(res, peertube.isStreamService()))); } player.prepare(videoSource); player.seekTo(0, position); player.setPlayWhenReady(true); } } }); builderSingle.show(); } @Override public void onPostAction(int statusCode, PeertubeAPI.StatusAction statusAction, String userId, Error error) { if (peertube.isCommentsEnabled() && statusAction == PeertubeAPI.StatusAction.PEERTUBECOMMENT) new RetrievePeertubeSingleCommentsAsyncTask(PeertubeActivity.this, peertubeInstance, videoId, PeertubeActivity.this).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } private void initFullscreenDialog() { fullScreenDialog = new Dialog(this, android.R.style.Theme_Black_NoTitleBar_Fullscreen) { public void onBackPressed() { if (fullScreenMode) closeFullscreenDialog(); super.onBackPressed(); } }; } private void openFullscreenDialog() { ((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_baseline_fullscreen_exit_24)); fullScreenMode = true; fullScreenDialog.show(); } private void closeFullscreenDialog() { ((ViewGroup) playerView.getParent()).removeView(playerView); ((FrameLayout) findViewById(R.id.main_media_frame)).addView(playerView); fullScreenMode = false; fullScreenDialog.dismiss(); fullScreenIcon.setImageDrawable(ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_fullscreen_24)); } private void initFullscreenButton() { PlayerControlView controlView = playerView.findViewById(R.id.exo_controller); fullScreenIcon = controlView.findViewById(R.id.exo_fullscreen_icon); View fullScreenButton = controlView.findViewById(R.id.exo_fullscreen_button); fullScreenButton.setOnClickListener(v -> { if (!fullScreenMode) openFullscreenDialog(); else closeFullscreenDialog(); }); } private void initResolution() { PlayerControlView controlView = playerView.findViewById(R.id.exo_controller); resolution = controlView.findViewById(R.id.resolution); resolution.setText(String.format("%sp", peertube.getResolution().get(0))); resolution.setOnClickListener(v -> displayResolution()); } private void changeColor() { if (peertube.getMyRating() != null && peertube.getMyRating().equals("like")) { 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_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); } } @Override public void onActionDone(ManagePlaylistsAsyncTask.action actionType, APIResponse apiResponse, int statusCode) { if (actionType == GET_PLAYLIST_FOR_VIDEO && apiResponse != null) { playlistForVideo = apiResponse.getPlaylistForVideos(); } else if (actionType == GET_PLAYLIST && apiResponse != null) { playlists = apiResponse.getPlaylists(); } } }