1
0
mirror of https://framagit.org/tom79/fedilab-tube synced 2025-02-23 15:27:37 +01:00

Support Emoji and replies

This commit is contained in:
Thomas 2020-10-15 15:16:41 +02:00
parent dc2a252dd5
commit 7a197993c9
16 changed files with 3104 additions and 158 deletions

View File

@ -6,6 +6,7 @@ android {
compileSdkVersion 30
buildToolsVersion "30.0.2"
defaultConfig {
minSdkVersion 21
@ -30,6 +31,10 @@ android {
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
viewBinding = true
}
lintOptions {
disable 'MissingTranslation'
checkReleaseBuilds false

View File

@ -184,6 +184,7 @@
<string name="peertube_video_unblacklist"><![CDATA[Votre vidéo <b>%1$s</b> nest plus blacklisté]]></string>
<string name="peertube_video_abuse"><![CDATA[Nouveau signalement pour la vidéo : <b>%1$s</b>]]></string>
<string name="add_public_comment">Ajouter un commentaire public</string>
<string name="add_public_reply">Répondre publiquement</string>
<string name="send_comment">Envoyer un commentaire</string>
<string name="all">Tout</string>
<!-- end languages -->

View File

@ -7,6 +7,7 @@
<string name="set_video_cache_choice" translatable="false">set_video_cache_choice</string>
<string name="set_theme_choice" translatable="false">set_theme_choice</string>
<string name="add_public_reply">Add a public reply</string>
<plurals name="number_of_replies">
<item quantity="one">%d reply</item>

File diff suppressed because it is too large Load Diff

View File

@ -32,20 +32,21 @@ import android.os.Bundle;
import android.os.Handler;
import android.support.v4.media.session.MediaSessionCompat;
import android.text.Html;
import android.text.Spanned;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
@ -53,13 +54,10 @@ import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatImageView;
import androidx.appcompat.widget.PopupMenu;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.core.widget.NestedScrollView;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@ -79,7 +77,6 @@ import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.TrackSelector;
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.upstream.DefaultHttpDataSourceFactory;
@ -98,6 +95,7 @@ import app.fedilab.fedilabtube.client.APIResponse;
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
import app.fedilab.fedilabtube.client.data.AccountData.Account;
import app.fedilab.fedilabtube.client.data.CaptionData.Caption;
import app.fedilab.fedilabtube.client.data.CommentData;
import app.fedilab.fedilabtube.client.data.CommentData.Comment;
import app.fedilab.fedilabtube.client.data.PlaylistData;
import app.fedilab.fedilabtube.client.data.VideoData;
@ -105,6 +103,7 @@ import app.fedilab.fedilabtube.client.entities.File;
import app.fedilab.fedilabtube.client.entities.ItemStr;
import app.fedilab.fedilabtube.client.entities.PlaylistExist;
import app.fedilab.fedilabtube.client.entities.Report;
import app.fedilab.fedilabtube.databinding.ActivityPeertubeBinding;
import app.fedilab.fedilabtube.drawer.CommentListAdapter;
import app.fedilab.fedilabtube.helper.CacheDataSourceFactory;
import app.fedilab.fedilabtube.helper.FullScreenMediaController;
@ -124,6 +123,7 @@ import es.dmoral.toasty.Toasty;
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.ADD_COMMENT;
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.RATEVIDEO;
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.REPLY;
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.REPORT_ACCOUNT;
import static app.fedilab.fedilabtube.client.RetrofitPeertubeAPI.ActionType.REPORT_VIDEO;
import static app.fedilab.fedilabtube.helper.Helper.getAttColor;
@ -136,33 +136,23 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
public static String video_id;
private String peertubeInstance, videoUuid;
private FullScreenMediaController.fullscreen fullscreen;
private RelativeLayout loader;
private TextView peertube_view_count, peertube_playlist, peertube_bookmark, peertube_like_count, peertube_dislike_count, peertube_description, peertube_title, more_actions;
private NestedScrollView peertube_information_container;
private VideoData.Video peertube;
private PlayerView playerView;
private ImageView fullScreenIcon;
private SimpleExoPlayer player;
private boolean fullScreenMode;
private Dialog fullScreenDialog;
private AppCompatImageView fullScreenIcon;
private TextView resolution;
private VideoData.Video peertube;
private int mode;
private ConstraintLayout write_comment_container;
private ImageView send;
private TextView add_comment_read;
private EditText add_comment_write;
private Map<String, List<PlaylistExist>> playlists;
private boolean playInMinimized;
private boolean onStopCalled;
private List<Caption> captions;
private TextView no_action_text;
private String max_id;
private RecyclerView lv_comments;
private boolean flag_loading;
private boolean isMyVideo;
private List<Comment> comments;
private CommentListAdapter commentListAdapter;
private CommentListAdapter commentListAdapter, commentReplyListAdapter;
private boolean sepiaSearch;
private ActivityPeertubeBinding binding;
public static void hideKeyboard(Activity activity) {
if (activity != null && activity.getWindow() != null) {
@ -176,45 +166,32 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_peertube);
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);
more_actions = findViewById(R.id.more_actions);
peertube_description = findViewById(R.id.peertube_description);
peertube_title = findViewById(R.id.peertube_title);
peertube_information_container = findViewById(R.id.peertube_information_container);
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);
CustomWebview webview_video = findViewById(R.id.webview_video);
playerView = findViewById(R.id.media_video);
write_comment_container = findViewById(R.id.write_comment_container);
binding = ActivityPeertubeBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
max_id = "0";
loader = findViewById(R.id.loader);
ImageView my_pp = findViewById(R.id.my_pp);
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
String token = sharedpreferences.getString(Helper.PREF_KEY_OAUTH_TOKEN, null);
if (Helper.isLoggedIn(PeertubeActivity.this) && !sepiaSearch) {
Account account = new AccountDAO(PeertubeActivity.this, db).getAccountByToken(token);
Helper.loadGiF(PeertubeActivity.this, account.getAvatar() != null ? account.getAvatar().getPath() : null, my_pp);
Helper.loadGiF(PeertubeActivity.this, account.getAvatar() != null ? account.getAvatar().getPath() : null, binding.myPp);
Helper.loadGiF(PeertubeActivity.this, account.getAvatar() != null ? account.getAvatar().getPath() : null, binding.myPpReply);
}
if (Helper.isTablet(PeertubeActivity.this)) {
RelativeLayout video_container = findViewById(R.id.video_container);
LinearLayout.LayoutParams param = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
0,
2.0f
);
video_container.setLayoutParams(param);
binding.videoContainer.setLayoutParams(param);
}
if (getSupportActionBar() != null)
@ -239,23 +216,21 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
}
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);
binding.webviewVideo.setVisibility(View.VISIBLE);
binding.mediaVideo.setVisibility(View.GONE);
CustomWebview webview_video = Helper.initializeWebview(PeertubeActivity.this, R.id.webview_video, null);
MastalabWebChromeClient mastalabWebChromeClient = new MastalabWebChromeClient(PeertubeActivity.this, webview_video, webview_container, videoLayout);
MastalabWebChromeClient mastalabWebChromeClient = new MastalabWebChromeClient(PeertubeActivity.this, webview_video, binding.mainMediaFrame, binding.videoLayout);
mastalabWebChromeClient.setOnToggledFullscreen(fullscreen -> {
if (fullscreen) {
videoLayout.setVisibility(View.VISIBLE);
binding.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);
binding.peertubeInformationContainer.setVisibility(View.GONE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else {
WindowManager.LayoutParams attrs = getWindow().getAttributes();
@ -263,39 +238,41 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
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);
binding.videoLayout.setVisibility(View.GONE);
binding.peertubeInformationContainer.setVisibility(View.VISIBLE);
}
});
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/" + videoUuid);
binding.webviewVideo.getSettings().setAllowFileAccess(true);
binding.webviewVideo.setWebChromeClient(mastalabWebChromeClient);
binding.webviewVideo.getSettings().setDomStorageEnabled(true);
binding.webviewVideo.getSettings().setAppCacheEnabled(true);
binding.webviewVideo.getSettings().setMediaPlaybackRequiresUserGesture(false);
binding.webviewVideo.setWebViewClient(new MastalabWebViewClient(PeertubeActivity.this));
binding.webviewVideo.loadUrl("https://" + peertubeInstance + "/videos/embed/" + videoUuid);
} else {
webview_video.setVisibility(View.GONE);
playerView.setVisibility(View.VISIBLE);
loader.setVisibility(View.VISIBLE);
binding.webviewVideo.setVisibility(View.GONE);
binding.mediaVideo.setVisibility(View.VISIBLE);
binding.loader.setVisibility(View.VISIBLE);
}
if (mode != Helper.VIDEO_MODE_WEBVIEW) {
playerView.setControllerShowTimeoutMs(1000);
playerView.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIT);
binding.mediaVideo.setControllerShowTimeoutMs(1000);
binding.mediaVideo.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIT);
initFullscreenDialog();
initFullscreenButton();
}
flag_loading = true;
comments = new ArrayList<>();
lv_comments = findViewById(R.id.peertube_comments);
binding.closeReply.setOnClickListener(v->closeCommentThread());
commentListAdapter = new CommentListAdapter(comments, Helper.isVideoOwner(PeertubeActivity.this, peertube));
commentListAdapter.allCommentRemoved = PeertubeActivity.this;
LinearLayoutManager mLayoutManager = new LinearLayoutManager(PeertubeActivity.this);
lv_comments.setLayoutManager(mLayoutManager);
lv_comments.setNestedScrollingEnabled(false);
lv_comments.setAdapter(commentListAdapter);
lv_comments.addOnScrollListener(new RecyclerView.OnScrollListener() {
binding.peertubeComments.setLayoutManager(mLayoutManager);
binding.peertubeComments.setNestedScrollingEnabled(false);
binding.peertubeComments.setAdapter(commentListAdapter);
binding.peertubeComments.addOnScrollListener(new RecyclerView.OnScrollListener() {
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
if (dy > 0) {
int visibleItemCount = mLayoutManager.getChildCount();
@ -318,6 +295,8 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
}
}
private void manageVIewVideos(APIResponse apiResponse) {
if( apiResponse == null || apiResponse.getPeertubes() == null || apiResponse.getPeertubes().size() == 0) {
playVideo();
@ -346,11 +325,46 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
}
}
if (comments.size() > 0) {
lv_comments.setVisibility(View.VISIBLE);
binding.peertubeComments.setVisibility(View.VISIBLE);
commentListAdapter.notifyItemRangeInserted(oldSize, newComments);
}
}
public void manageVIewCommentReply(APIResponse apiResponse) {
if (apiResponse == null || apiResponse.getError() != null || apiResponse.getCommentThreadData() == null) {
if (apiResponse == null || apiResponse.getError() == 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<CommentData.CommentThreadData> commentThreadDataList = apiResponse.getCommentThreadData().getChildren();
List<Comment> comments = generateCommentReply(commentThreadDataList, new ArrayList<>());
if (comments.size() > 0) {
commentReplyListAdapter = new CommentListAdapter(comments, Helper.isVideoOwner(PeertubeActivity.this, peertube));
LinearLayoutManager mLayoutManager = new LinearLayoutManager(PeertubeActivity.this);
binding.peertubeReply.setLayoutManager(mLayoutManager);
binding.peertubeReply.setNestedScrollingEnabled(false);
binding.peertubeReply.setAdapter(commentReplyListAdapter);
binding.peertubeReply.setVisibility(View.VISIBLE);
commentReplyListAdapter.notifyItemRangeInserted(0, comments.size());
}
}
private List<Comment> generateCommentReply(List<CommentData.CommentThreadData> commentThreadDataList, List<Comment> comments) {
for (CommentData.CommentThreadData commentThreadData : commentThreadDataList) {
if (commentThreadData.getComment().getText() != null && commentThreadData.getComment().getText().trim().length() > 0) {
commentThreadData.getComment().setReply(true);
comments.add(commentThreadData.getComment());
}
if( commentThreadData.getChildren() != null && commentThreadData.getChildren().size() >0) {
generateCommentReply(commentThreadData.getChildren(), comments);
}
}
return comments;
}
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
@ -367,8 +381,8 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
player.setPlayWhenReady(false);
player.release();
player = ExoPlayerFactory.newSimpleInstance(PeertubeActivity.this);
playerView.setPlayer(player);
loader.setVisibility(View.GONE);
binding.mediaVideo.setPlayer(player);
binding.loader.setVisibility(View.GONE);
player.setPlayWhenReady(true);
captions = null;
}
@ -376,8 +390,8 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
setFullscreen(FullScreenMediaController.fullscreen.OFF);
fullScreenMode = false;
peertube_playlist.setVisibility(View.VISIBLE);
peertube_bookmark.setVisibility(View.GONE);
binding.peertubePlaylist.setVisibility(View.VISIBLE);
binding.peertubeBookmark.setVisibility(View.GONE);
TimelineVM feedsViewModel = new ViewModelProvider(PeertubeActivity.this).get(TimelineVM.class);
feedsViewModel.getVideo(sepiaSearch?peertubeInstance:null, videoUuid, isMyVideo).observe(PeertubeActivity.this, this::manageVIewVideo);
CaptionsVM captionsViewModel = new ViewModelProvider(PeertubeActivity.this).get(CaptionsVM.class);
@ -389,12 +403,12 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN |
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Objects.requireNonNull(getSupportActionBar()).hide();
peertube_information_container.setVisibility(View.GONE);
binding.peertubeInformationContainer.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);
binding.peertubeInformationContainer.setVisibility(View.VISIBLE);
}
}
@ -411,9 +425,9 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
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);
binding.addCommentRead.setVisibility(View.VISIBLE);
binding.addCommentWrite.setVisibility(View.GONE);
binding.send.setVisibility(View.GONE);
hideKeyboard(PeertubeActivity.this);
}
}
@ -439,8 +453,8 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
LayoutInflater inflater1 = getLayoutInflater();
View dialogView = inflater1.inflate(R.layout.popup_report, new LinearLayout(PeertubeActivity.this), false);
dialogBuilder.setView(dialogView);
EditText report_content = dialogView.findViewById(R.id.report_content);
dialogBuilder.setNeutralButton(R.string.cancel, (dialog, id) -> dialog.dismiss());
EditText report_content = dialogView.findViewById(R.id.report_content);
dialogBuilder.setPositiveButton(R.string.report, (dialog, id) -> {
if (report_content.getText().toString().trim().length() == 0) {
Toasty.info(PeertubeActivity.this, getString(R.string.report_comment_size), Toasty.LENGTH_LONG).show();
@ -493,12 +507,12 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
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);
binding.loader.setVisibility(View.GONE);
return;
}
if (apiResponse.getPeertubes() == null || apiResponse.getPeertubes().get(0) == null || apiResponse.getPeertubes().get(0).getFileUrl(null, PeertubeActivity.this) == null) {
Toasty.error(PeertubeActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show();
loader.setVisibility(View.GONE);
binding.loader.setVisibility(View.GONE);
return;
}
@ -513,13 +527,13 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
viewModel.videoExists(videoIds).observe(this, this::manageVIewPlaylist);
add_comment_read.setOnClickListener(v -> {
binding.writeCommentContainer.setOnClickListener(v -> {
if (isLoggedIn(PeertubeActivity.this) && !sepiaSearch) {
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());
binding.addCommentRead.setVisibility(View.GONE);
binding.addCommentWrite.setVisibility(View.VISIBLE);
binding.send.setVisibility(View.VISIBLE);
binding.addCommentWrite.requestFocus();
binding.addCommentWrite.setSelection( binding.addCommentWrite.getText().length());
} else {
if( sepiaSearch) {
Toasty.info(PeertubeActivity.this, getString(R.string.federation_issue), Toasty.LENGTH_SHORT).show();
@ -529,17 +543,32 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
}
});
send.setOnClickListener(v -> {
binding.writeCommentContainerReply.setOnClickListener(v -> {
if (isLoggedIn(PeertubeActivity.this) && !sepiaSearch) {
String comment = add_comment_write.getText().toString();
binding.addCommentReadReply.setVisibility(View.GONE);
binding.addCommentWriteReply.setVisibility(View.VISIBLE);
binding.send.setVisibility(View.VISIBLE);
binding.addCommentWriteReply.requestFocus();
binding.addCommentWriteReply.setSelection( binding.addCommentWriteReply.getText().length());
} else {
if( sepiaSearch) {
Toasty.info(PeertubeActivity.this, getString(R.string.federation_issue), Toasty.LENGTH_SHORT).show();
}else {
Toasty.error(PeertubeActivity.this, getString(R.string.not_logged_in), Toast.LENGTH_SHORT).show();
}
}
});
binding.send.setOnClickListener(v -> {
if (isLoggedIn(PeertubeActivity.this) && !sepiaSearch) {
String comment = binding.addCommentWrite.getText().toString();
if (comment.trim().length() > 0) {
PostActionsVM viewModelComment = new ViewModelProvider(PeertubeActivity.this).get(PostActionsVM.class);
viewModelComment.comment(ADD_COMMENT, peertube.getId(), null, comment).observe(PeertubeActivity.this, apiResponse1 -> manageVIewPostActions(ADD_COMMENT, apiResponse1));
add_comment_write.setText("");
add_comment_read.setVisibility(View.VISIBLE);
add_comment_write.setVisibility(View.GONE);
send.setVisibility(View.GONE);
add_comment_read.requestFocus();
binding.addCommentWrite.setText("");
binding.addCommentRead.setVisibility(View.VISIBLE);
binding.addCommentWrite.setVisibility(View.GONE);
binding.sendReply.setVisibility(View.GONE);
binding.addCommentRead.requestFocus();
}
} else {
if( sepiaSearch) {
@ -550,47 +579,45 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
}
});
peertube_playlist.setOnClickListener(v -> {
binding.peertubePlaylist.setOnClickListener(v -> {
PlaylistsVM viewModelOwnerPlaylist = new ViewModelProvider(PeertubeActivity.this).get(PlaylistsVM.class);
viewModelOwnerPlaylist.manage(PlaylistsVM.action.GET_PLAYLISTS, null, null).observe(PeertubeActivity.this, this::manageVIewPlaylists);
});
no_action_text = findViewById(R.id.no_action_text);
if (peertube.isCommentsEnabled()) {
CommentVM commentViewModel = new ViewModelProvider(PeertubeActivity.this).get(CommentVM.class);
commentViewModel.getThread(sepiaSearch?peertubeInstance:null, videoUuid, max_id).observe(PeertubeActivity.this, this::manageVIewComment);
write_comment_container.setVisibility(View.VISIBLE);
binding.writeCommentContainer.setVisibility(View.VISIBLE);
} else {
RelativeLayout no_action = findViewById(R.id.no_action);
no_action_text.setText(getString(R.string.comment_no_allowed_peertube));
no_action.setVisibility(View.VISIBLE);
write_comment_container.setVisibility(View.GONE);
binding.noActionText.setText(getString(R.string.comment_no_allowed_peertube));
binding.noAction.setVisibility(View.VISIBLE);
binding.writeCommentContainer.setVisibility(View.GONE);
}
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
setTitle(peertube.getName());
peertube_description.setText(peertube.getDescription());
binding.peertubeDescription.setText(peertube.getDescription());
peertube_title.setText(peertube.getName());
peertube_dislike_count.setText(String.valueOf(peertube.getDislikes()));
peertube_like_count.setText(String.valueOf(peertube.getLikes()));
peertube_view_count.setText(String.valueOf(peertube.getViews()));
binding.peertubeTitle.setText(peertube.getName());
binding.peertubeDislikeCount.setText(String.valueOf(peertube.getDislikes()));
binding.peertubeLikeCount.setText(String.valueOf(peertube.getLikes()));
binding.peertubeViewCount.setText(String.valueOf(peertube.getViews()));
video_id = peertube.getId();
changeColor();
initResolution();
peertube_like_count.setOnClickListener(v -> {
binding.peertubeLikeCount.setOnClickListener(v -> {
if (isLoggedIn(PeertubeActivity.this) && !sepiaSearch) {
String newState = peertube.getMyRating().equals("like") ? "none" : "like";
PostActionsVM viewModelLike = new ViewModelProvider(PeertubeActivity.this).get(PostActionsVM.class);
viewModelLike.post(RATEVIDEO, peertube.getId(), newState).observe(PeertubeActivity.this, apiResponse1 -> manageVIewPostActions(RATEVIDEO, apiResponse1));
peertube.setMyRating(newState);
int count = Integer.parseInt(peertube_like_count.getText().toString());
int count = Integer.parseInt(binding.peertubeLikeCount.getText().toString());
if (newState.compareTo("none") == 0) {
count--;
if (count - 1 < 0) {
@ -599,7 +626,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
} else {
count++;
}
peertube_like_count.setText(String.valueOf(count));
binding.peertubeLikeCount.setText(String.valueOf(count));
changeColor();
} else {
if( sepiaSearch) {
@ -609,13 +636,13 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
}
}
});
peertube_dislike_count.setOnClickListener(v -> {
binding.peertubeDislikeCount.setOnClickListener(v -> {
if (isLoggedIn(PeertubeActivity.this) && !sepiaSearch) {
String newState = peertube.getMyRating().equals("dislike") ? "none" : "dislike";
PostActionsVM viewModelLike = new ViewModelProvider(PeertubeActivity.this).get(PostActionsVM.class);
viewModelLike.post(RATEVIDEO, peertube.getId(), newState).observe(PeertubeActivity.this, apiResponse1 -> manageVIewPostActions(RATEVIDEO, apiResponse1));
peertube.setMyRating(newState);
int count = Integer.parseInt(peertube_dislike_count.getText().toString());
int count = Integer.parseInt(binding.peertubeDislikeCount.getText().toString());
if (newState.compareTo("none") == 0) {
count--;
if (count - 1 < 0) {
@ -624,7 +651,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
} else {
count++;
}
peertube_dislike_count.setText(String.valueOf(count));
binding.peertubeDislikeCount.setText(String.valueOf(count));
changeColor();
} else {
if( sepiaSearch) {
@ -642,8 +669,8 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
ProgressiveMediaSource videoSource;
player = ExoPlayerFactory.newSimpleInstance(PeertubeActivity.this);
playerView.setPlayer(player);
loader.setVisibility(View.GONE);
binding.mediaVideo.setPlayer(player);
binding.loader.setVisibility(View.GONE);
if (apiResponse.getPeertubes().get(0).getFiles() != null && apiResponse.getPeertubes().get(0).getFiles().size() > 0) {
if (video_cache == 0) {
@ -666,8 +693,8 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
}
more_actions.setOnClickListener(view -> {
PopupMenu popup = new PopupMenu(PeertubeActivity.this, more_actions);
binding.moreActions.setOnClickListener(view -> {
PopupMenu popup = new PopupMenu(PeertubeActivity.this, binding.moreActions);
popup.getMenuInflater()
.inflate(R.menu.main_video, popup.getMenu());
@ -778,7 +805,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
if (uri != null)
subtitleSource = new SingleSampleMediaSource.Factory(cacheDataSourceFactory).createMediaSource(uri, subtitleFormat, C.TIME_UNSET);
}
playerView.setPlayer(player);
binding.mediaVideo.setPlayer(player);
if (which > 0 && subtitleSource != null) {
MergingMediaSource mergedSource =
new MergingMediaSource(videoSource, subtitleSource);
@ -809,13 +836,12 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
LayoutInflater inflater1 = getLayoutInflater();
View dialogView = inflater1.inflate(R.layout.popup_report_choice, new LinearLayout(PeertubeActivity.this), false);
dialogBuilder.setView(dialogView);
Button report_video = dialogView.findViewById(R.id.report_video);
Button report_account = dialogView.findViewById(R.id.report_account);
dialogBuilder.setNeutralButton(R.string.cancel, (dialog, id) -> dialog.dismiss());
alertDialog = dialogBuilder.create();
alertDialog.show();
report_video.setOnClickListener(v -> reportAlert(REPORT_VIDEO, alertDialog));
report_account.setOnClickListener(v -> reportAlert(REPORT_ACCOUNT, alertDialog));
dialogView.findViewById(R.id.report_video).setOnClickListener(v -> reportAlert(REPORT_VIDEO, alertDialog));
dialogView.findViewById(R.id.report_account).setOnClickListener(v -> reportAlert(REPORT_ACCOUNT, alertDialog));
}
return true;
});
@ -846,6 +872,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
@Override
public void onDestroy() {
super.onDestroy();
binding = null;
if (player != null) {
player.setPlayWhenReady(false);
player.release();
@ -875,9 +902,9 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
MediaSessionCompat mediaSession = new MediaSessionCompat(this, getPackageName());
MediaSessionConnector mediaSessionConnector = new MediaSessionConnector(mediaSession);
mediaSessionConnector.setPlayer(player);
PlayerControlView controlView = playerView.findViewById(R.id.exo_controller);
PlayerControlView controlView = binding.mediaVideo.findViewById(R.id.exo_controller);
controlView.hide();
playerView.setControllerAutoShow(false);
binding.mediaVideo.setControllerAutoShow(false);
mediaSession.setActive(true);
enterPictureInPictureMode();
}
@ -938,18 +965,18 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
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);
if (binding.mediaVideo != null) {
binding.loader.setVisibility(View.VISIBLE);
long position = player.getCurrentPosition();
PlayerControlView controlView = playerView.findViewById(R.id.exo_controller);
resolution = controlView.findViewById(R.id.resolution);
PlayerControlView controlView = binding.mediaVideo.findViewById(R.id.exo_controller);
TextView resolution = controlView.findViewById(R.id.resolution);
resolution.setText(String.format("%sp", res));
if (mode == Helper.VIDEO_MODE_NORMAL) {
if (player != null)
player.release();
player = ExoPlayerFactory.newSimpleInstance(PeertubeActivity.this);
playerView.setPlayer(player);
loader.setVisibility(View.GONE);
binding.mediaVideo.setPlayer(player);
binding.loader.setVisibility(View.GONE);
int video_cache = sharedpreferences.getInt(Helper.SET_VIDEO_CACHE, Helper.DEFAULT_VIDEO_CACHE_MB);
ProgressiveMediaSource videoSource;
if (video_cache == 0) {
@ -1001,18 +1028,97 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
private void openFullscreenDialog() {
((ViewGroup) playerView.getParent()).removeView(playerView);
fullScreenDialog.addContentView(playerView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
((ViewGroup) binding.mediaVideo.getParent()).removeView(binding.mediaVideo);
fullScreenDialog.addContentView(binding.mediaVideo, 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();
}
public void openCommentThread(Comment comment){
CommentVM commentViewModel = new ViewModelProvider(PeertubeActivity.this).get(CommentVM.class);
binding.peertubeReply.setVisibility(View.GONE);
commentViewModel.getRepliesComment(videoUuid, comment.getId()).observe(PeertubeActivity.this, this::manageVIewCommentReply);
Account account = comment.getAccount();
Helper.loadGiF(PeertubeActivity.this, account.getAvatar() != null ? account.getAvatar().getPath() : null, binding.commentAccountProfile);
binding.commentAccountDisplayname.setText(account.getDisplayName());
binding.commentAccountUsername.setText(account.getAcct());
Spanned commentSpan;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
commentSpan = Html.fromHtml(comment.getText(), Html.FROM_HTML_MODE_COMPACT);
else
commentSpan = Html.fromHtml(comment.getText());
binding.commentContent.setText(commentSpan);
binding.commentDate.setText(Helper.dateDiff(PeertubeActivity.this, comment.getCreatedAt()));
binding.replyThread.setVisibility(View.VISIBLE);
TranslateAnimation animate = new TranslateAnimation(
binding.peertubeInformationContainer.getWidth(),
0,
0,
0);
animate.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
binding.peertubeInformationContainer.setVisibility(View.GONE);
}
@Override
public void onAnimationRepeat(Animation animation) {}
});
animate.setDuration(500);
binding.replyThread.startAnimation(animate);
binding.sendReply.setOnClickListener(null);
binding.sendReply.setOnClickListener(v -> {
if (isLoggedIn(PeertubeActivity.this) && !sepiaSearch) {
String commentView = binding.addCommentWriteReply.getText().toString();
if (commentView.trim().length() > 0) {
PostActionsVM viewModelComment = new ViewModelProvider(PeertubeActivity.this).get(PostActionsVM.class);
viewModelComment.comment(REPLY, peertube.getId(), comment.getId(), commentView).observe(PeertubeActivity.this, apiResponse1 -> manageVIewPostActions(ADD_COMMENT, apiResponse1));
binding.addCommentWriteReply.setText("");
binding.addCommentReadReply.setVisibility(View.VISIBLE);
binding.addCommentWriteReply.setVisibility(View.GONE);
binding.sendReply.setVisibility(View.GONE);
binding.addCommentReadReply.requestFocus();
}
} else {
if( sepiaSearch) {
Toasty.info(PeertubeActivity.this, getString(R.string.federation_issue), Toasty.LENGTH_SHORT).show();
}else {
Toasty.error(PeertubeActivity.this, getString(R.string.not_logged_in), Toast.LENGTH_SHORT).show();
}
}
});
}
private void closeCommentThread(){
binding.peertubeInformationContainer.setVisibility(View.VISIBLE);
TranslateAnimation animate = new TranslateAnimation(
0,
binding.replyThread.getWidth(),
0,
0);
animate.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
binding.replyThread.setVisibility(View.GONE);
}
@Override
public void onAnimationRepeat(Animation animation) {}
});
animate.setDuration(500);
binding.replyThread.startAnimation(animate);
}
private void closeFullscreenDialog() {
((ViewGroup) playerView.getParent()).removeView(playerView);
((FrameLayout) findViewById(R.id.main_media_frame)).addView(playerView);
((ViewGroup) binding.mediaVideo.getParent()).removeView(binding.mediaVideo);
((FrameLayout) findViewById(R.id.main_media_frame)).addView(binding.mediaVideo);
fullScreenMode = false;
fullScreenDialog.dismiss();
fullScreenIcon.setImageDrawable(ContextCompat.getDrawable(PeertubeActivity.this, R.drawable.ic_baseline_fullscreen_24));
@ -1020,7 +1126,7 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
private void initFullscreenButton() {
PlayerControlView controlView = playerView.findViewById(R.id.exo_controller);
PlayerControlView controlView = binding.mediaVideo.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 -> {
@ -1038,8 +1144,8 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
}
private void initResolution() {
PlayerControlView controlView = playerView.findViewById(R.id.exo_controller);
resolution = controlView.findViewById(R.id.resolution);
PlayerControlView controlView = binding.mediaVideo.findViewById(R.id.exo_controller);
TextView resolution = controlView.findViewById(R.id.resolution);
if (peertube.getFiles() != null && peertube.getFiles().size() > 0) {
resolution.setText(String.format("%s", Helper.defaultFile(PeertubeActivity.this, peertube.getFiles()).getResolutions().getLabel()));
resolution.setOnClickListener(v -> displayResolution());
@ -1073,8 +1179,8 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
DrawableCompat.setTint(thumbDown, getResources().getColor(R.color.negative_thumbs));
}
}
peertube_like_count.setCompoundDrawablesWithIntrinsicBounds(null, thumbUp, null, null);
peertube_dislike_count.setCompoundDrawablesWithIntrinsicBounds(null, thumbDown, null, null);
binding.peertubeLikeCount.setCompoundDrawablesWithIntrinsicBounds(null, thumbUp, null, null);
binding.peertubeDislikeCount.setCompoundDrawablesWithIntrinsicBounds(null, thumbDown, null, null);
}
public void manageVIewPlaylists(APIResponse apiResponse) {
@ -1160,6 +1266,6 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
@Override
public void onAllCommentRemoved() {
no_action_text.setVisibility(View.VISIBLE);
binding.noActionText.setVisibility(View.VISIBLE);
}
}

View File

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

View File

@ -328,7 +328,7 @@ public interface PeertubeService {
Call<CommentData> getComments(@Path("id") String id, @Query("start") String maxId, @Query("count") String count);
@GET("videos/{id}/comment-threads/{threadId}")
Call<CommentData> getReplies(@Path("id") String id, @Path("threadId") String threadId);
Call<CommentData.CommentThreadData> getReplies(@Path("id") String id, @Path("threadId") String threadId);
@FormUrlEncoded
@POST("videos/{id}/comment-threads")

View File

@ -1203,10 +1203,10 @@ public class RetrofitPeertubeAPI {
setError(apiResponse, response.code(), response.errorBody());
}
} else if (type == CommentVM.action.GET_REPLIES) {
Call<CommentData> commentsCall = peertubeService.getReplies(videoId, forCommentId);
Response<CommentData> response = commentsCall.execute();
Call<CommentData.CommentThreadData> commentsCall = peertubeService.getReplies(videoId, forCommentId);
Response<CommentData.CommentThreadData> response = commentsCall.execute();
if (response.isSuccessful() && response.body() != null) {
apiResponse.setComments(response.body().data);
apiResponse.setCommentThreadData(response.body());
} else {
setError(apiResponse, response.code(), response.errorBody());
}

View File

@ -172,6 +172,31 @@ public class CommentData {
}
}
public static class CommentThreadData {
@SerializedName("comment")
public Comment comment;
@SerializedName("children")
public List<CommentThreadData> children;
public Comment getComment() {
return comment;
}
public void setComment(Comment comment) {
this.comment = comment;
}
public List<CommentThreadData> getChildren() {
return children;
}
public void setChildren(List<CommentThreadData> children) {
this.children = children;
}
}
public static class CommentPosted{
@SerializedName("comment")
private Comment comment;

View File

@ -49,11 +49,13 @@ 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.client.APIResponse;
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
import app.fedilab.fedilabtube.client.data.CommentData.Comment;
import app.fedilab.fedilabtube.client.entities.Report;
import app.fedilab.fedilabtube.helper.EmojiHelper;
import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.viewmodel.PostActionsVM;
import es.dmoral.toasty.Toasty;
@ -206,15 +208,19 @@ public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
Spanned commentSpan;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
commentSpan = Html.fromHtml(comment.getText(), Html.FROM_HTML_MODE_COMPACT);
commentSpan = Html.fromHtml(EmojiHelper.shortnameToUnicode(comment.getText()), Html.FROM_HTML_MODE_COMPACT);
else
commentSpan = Html.fromHtml(comment.getText());
commentSpan = Html.fromHtml(EmojiHelper.shortnameToUnicode(comment.getText()));
holder.comment_content.setText(commentSpan, TextView.BufferType.SPANNABLE);
holder.comment_content.setMovementMethod(LinkMovementMethod.getInstance());
holder.comment_account_displayname.setText(comment.getAccount().getDisplayName());
if( context instanceof PeertubeActivity && !comment.isReply()) {
holder.main_container.setOnClickListener(v -> ((PeertubeActivity) context).openCommentThread(comment));
holder.comment_content.setOnClickListener(v -> ((PeertubeActivity) context).openCommentThread(comment));
}
if( comment.getTotalReplies() > 0) {
holder.number_of_replies.setVisibility(View.VISIBLE);
holder.number_of_replies.setText(context.getResources().getQuantityString(R.plurals.number_of_replies, comment.getTotalReplies(), comment.getTotalReplies()));

View File

@ -0,0 +1,78 @@
package app.fedilab.fedilabtube.helper;
/* Copyright 2020 Thomas Schneider
*
* This file is a part of TubeLab
*
* This program is free software; you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* TubeLab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along with TubeLab; if not,
* see <http://www.gnu.org/licenses>. */
import android.content.Context;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class EmojiHelper {
//Emoji manager
private static final Map<String, String> emoji = new HashMap<>();
private static final Pattern SHORTNAME_PATTERN = Pattern.compile(":( |)([-+\\w]+):");
/**
* Converts emojis in input to unicode
* @param input String
* @return String
*/
public static String shortnameToUnicode(String input) {
Matcher matcher = SHORTNAME_PATTERN.matcher(input);
while (matcher.find()) {
String unicode = emoji.get(matcher.group(2));
if (unicode == null) {
continue;
}
if (matcher.group(1).equals(" "))
input = input.replace(": " + matcher.group(2) + ":", unicode);
else
input = input.replace(":" + matcher.group(2) + ":", unicode);
}
return input;
}
public static void fillMapEmoji(Context context) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(context.getAssets().open("emoji.csv")));
String line;
while( (line = br.readLine()) != null) {
String[] str = line.split(",");
String unicode = null;
if(str.length == 2)
unicode = new String(new int[] {Integer.parseInt(str[1].replace("0x","").trim(), 16)}, 0, 1);
else if(str.length == 3)
unicode = new String(new int[] {Integer.parseInt(str[1].replace("0x","").trim(), 16), Integer.parseInt(str[2].replace("0x","").trim(), 16)}, 0, 2);
else if(str.length == 4)
unicode = new String(new int[] {Integer.parseInt(str[1].replace("0x","").trim(), 16), Integer.parseInt(str[2].replace("0x","").trim(), 16), Integer.parseInt(str[3].replace("0x","").trim(), 16)}, 0, 3);
else if(str.length == 5)
unicode = new String(new int[] {Integer.parseInt(str[1].replace("0x","").trim(), 16), Integer.parseInt(str[2].replace("0x","").trim(), 16), Integer.parseInt(str[3].replace("0x","").trim(), 16), Integer.parseInt(str[4].replace("0x","").trim(), 16)}, 0, 4);
if( unicode != null)
emoji.put(str[0],unicode);
}
br.close();
} catch (IOException ignored) {ignored.printStackTrace();}
}
}

View File

@ -33,6 +33,7 @@ import java.util.Objects;
import app.fedilab.fedilabtube.R;
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
import app.fedilab.fedilabtube.client.entities.PeertubeInformation;
import app.fedilab.fedilabtube.helper.EmojiHelper;
import app.fedilab.fedilabtube.helper.NetworkStateReceiver;
import static app.fedilab.fedilabtube.MainActivity.peertubeInformation;
@ -56,7 +57,6 @@ public class RetrieveInfoService extends Service implements NetworkStateReceiver
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
getString(R.string.notification_channel_name),
@ -110,6 +110,7 @@ public class RetrieveInfoService extends Service implements NetworkStateReceiver
@Override
public void run() {
EmojiHelper.fillMapEmoji(getApplicationContext());
peertubeInformation = new PeertubeInformation();
peertubeInformation.setCategories(new LinkedHashMap<>());
peertubeInformation.setLanguages(new LinkedHashMap<>());

View File

@ -74,7 +74,7 @@ public class CommentVM extends AndroidViewModel {
new Thread(() -> {
try {
RetrofitPeertubeAPI api = new RetrofitPeertubeAPI(_mContext);
APIResponse apiResponse = api.getComments(action.GET_REPLIES, videoId, null, null);
APIResponse apiResponse = api.getComments(action.GET_REPLIES, videoId, commentId, null);
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> apiResponseMutableLiveData.setValue(apiResponse);
mainHandler.post(myRunnable);

View File

@ -223,10 +223,21 @@
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
<View
android:id="@+id/separator_top"
android:layout_margin="5dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@+id/separator"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@+id/write_container"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@android:color/darker_gray"/>
<androidx.constraintlayout.widget.ConstraintLayout
app:layout_constraintTop_toBottomOf="@+id/separator_top"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@+id/separator_bottom"
android:id="@+id/write_container"
android:layout_width="match_parent"
android:layout_height="wrap_content">
@ -276,10 +287,9 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:id="@+id/separator"
android:id="@+id/separator_bottom"
android:layout_margin="5dp"
app:layout_constraintTop_toBottomOf="@+id/write_container"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="match_parent"
@ -312,6 +322,7 @@
</androidx.core.widget.NestedScrollView>
<androidx.core.widget.NestedScrollView
android:background="?android:colorBackground"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
@ -321,6 +332,10 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_marginStart="20dp"
android:layout_marginLeft="20dp"
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp"
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -397,10 +412,20 @@
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
<View
android:id="@+id/separator_top_reply"
android:layout_margin="5dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@+id/separator_reply"
app:layout_constraintBottom_toTopOf="@+id/write_container_reply"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@android:color/darker_gray"/>
<androidx.constraintlayout.widget.ConstraintLayout
app:layout_constraintTop_toBottomOf="@+id/separator_top_reply"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@+id/separator_bottom_reply"
android:id="@+id/write_container_reply"
android:layout_width="match_parent"
android:layout_height="wrap_content">
@ -414,7 +439,7 @@
<TextView
android:id="@+id/add_comment_read_reply"
android:gravity="center"
android:text="@string/add_public_comment"
android:text="@string/add_public_reply"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@+id/my_pp_reply"
app:layout_constraintEnd_toEndOf="parent"
@ -429,7 +454,7 @@
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="true"
android:hint="@string/add_public_comment"
android:hint="@string/add_public_reply"
android:importantForAutofill="no"
android:inputType="textMultiLine"
android:maxLines="4"
@ -450,7 +475,7 @@
</androidx.constraintlayout.widget.ConstraintLayout>
<View
android:id="@+id/separator_reply"
android:id="@+id/separator_bottom_reply"
android:layout_margin="5dp"
app:layout_constraintTop_toBottomOf="@+id/write_container_reply"
app:layout_constraintBottom_toBottomOf="parent"

View File

@ -21,7 +21,9 @@
android:layout_height="wrap_content"
android:divider="?android:dividerHorizontal"
android:orientation="vertical"
android:showDividers="end">
android:clickable="true"
android:showDividers="end"
android:focusable="true">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"

View File

@ -3,6 +3,7 @@ buildscript {
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
@ -17,6 +18,8 @@ allprojects {
repositories {
google()
jcenter()
mavenCentral()
mavenLocal()
}
}