1
0
mirror of https://framagit.org/tom79/fedilab-tube synced 2025-02-09 08:38:50 +01:00

Allow to edit channel and playlists

This commit is contained in:
Thomas 2020-09-11 19:10:54 +02:00
parent bb2c129762
commit c714e6a625
6 changed files with 218 additions and 93 deletions

View File

@ -31,6 +31,7 @@ import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.text.Format;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
@ -874,6 +875,28 @@ public class PeertubeAPI {
}
}
/**
* Update a channel fot the authenticated user
*
* @param acct String
* @param channelCreation ChannelCreation
*/
public void updateChannel(String acct, ChannelCreation channelCreation) throws HttpsConnection.HttpsConnectionException {
actionCode = -1;
try {
HashMap<String, String> params = new HashMap<>();
params.put("displayName", channelCreation.getDisplayName());
params.put("name", channelCreation.getName());
params.put("description", channelCreation.getDescription());
params.put("support", channelCreation.getSupport());
HttpsConnection httpsConnection = new HttpsConnection(context);
httpsConnection.put(getAbsoluteUrl(String.format("/video-channels/%s", acct)), 30, params, prefKeyOauthTokenT);
actionCode = httpsConnection.getActionCode();
} catch (NoSuchAlgorithmException | IOException | KeyManagementException e) {
e.printStackTrace();
}
}
/**
* Delete a Channel
*

View File

@ -16,11 +16,20 @@ package app.fedilab.fedilabtube.client.entities;
* see <http://www.gnu.org/licenses>. */
public class ChannelCreation {
private String id;
private String displayName;
private String name;
private String description;
private String support;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getDisplayName() {
return displayName;
}

View File

@ -26,6 +26,7 @@ import android.text.util.Linkify;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@ -33,6 +34,7 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.PopupMenu;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ViewModelProvider;
@ -43,6 +45,7 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton;
import java.util.List;
import app.fedilab.fedilabtube.AccountActivity;
import app.fedilab.fedilabtube.R;
import app.fedilab.fedilabtube.ShowAccountActivity;
import app.fedilab.fedilabtube.client.APIResponse;
@ -59,6 +62,7 @@ import es.dmoral.toasty.Toasty;
public class AccountsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public AllAccountsRemoved allAccountsRemoved;
public EditAlertDialog editAlertDialog;
private List<Account> accounts;
private Context context;
private AccountsListAdapter accountsListAdapter;
@ -83,7 +87,8 @@ public class AccountsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
final AccountsListAdapter.ViewHolder holder = (AccountsListAdapter.ViewHolder) viewHolder;
final Account account = accounts.get(position);
if (type == AccountsVM.accountFetch.CHANNEL) {
holder.account_action.show();
holder.account_action.hide();
holder.more_actions.setVisibility(View.VISIBLE);
holder.account_action.setImageResource(R.drawable.ic_baseline_delete_24);
holder.account_action.setContentDescription(context.getString(R.string.delete_channel));
holder.account_action.setOnClickListener(view -> {
@ -99,15 +104,10 @@ public class AccountsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
new PeertubeAPI(context).deleteChannel(account.getAcct());
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> {
DisplayPlaylistsFragment displayPlaylistsFragment;
if (context == null)
return;
displayPlaylistsFragment = (DisplayPlaylistsFragment) ((AppCompatActivity) context).getSupportFragmentManager().findFragmentByTag("CHANNELS");
final FragmentTransaction ft = ((AppCompatActivity) context).getSupportFragmentManager().beginTransaction();
if (displayPlaylistsFragment != null) {
ft.detach(displayPlaylistsFragment);
ft.attach(displayPlaylistsFragment);
ft.commit();
accounts.remove(account);
notifyDataSetChanged();
if (accounts.size() == 0) {
allAccountsRemoved.onAllAccountsRemoved();
}
};
mainHandler.post(myRunnable);
@ -169,6 +169,65 @@ public class AccountsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
holder.account_action.setImageResource(R.drawable.ic_baseline_volume_mute_24);
}
holder.more_actions.setOnClickListener(view -> {
PopupMenu popup = new PopupMenu(context, holder.more_actions);
popup.getMenuInflater()
.inflate(R.menu.playlist_menu, popup.getMenu());
popup.setOnMenuItemClickListener(item -> {
switch (item.getItemId()) {
case R.id.action_delete:
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle(context.getString(R.string.action_channel_delete) + ": " + account.getAcct());
builder.setMessage(context.getString(R.string.action_channel_confirm_delete));
builder.setIcon(android.R.drawable.ic_dialog_alert)
.setPositiveButton(R.string.yes, (dialog, which) -> {
accounts.remove(account);
notifyDataSetChanged();
new Thread(() -> {
try {
new PeertubeAPI(context).deleteChannel(account.getAcct());
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> {
DisplayPlaylistsFragment displayPlaylistsFragment;
if (context == null)
return;
displayPlaylistsFragment = (DisplayPlaylistsFragment) ((AppCompatActivity) context).getSupportFragmentManager().findFragmentByTag("CHANNELS");
final FragmentTransaction ft = ((AppCompatActivity) context).getSupportFragmentManager().beginTransaction();
if (displayPlaylistsFragment != null) {
ft.detach(displayPlaylistsFragment);
ft.attach(displayPlaylistsFragment);
ft.commit();
}
};
mainHandler.post(myRunnable);
} catch (HttpsConnection.HttpsConnectionException e) {
e.printStackTrace();
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> {
if (e.getMessage() != null) {
Toasty.error(context, e.getMessage(), Toast.LENGTH_LONG).show();
} else {
Toasty.error(context, context.getString(R.string.toast_error), Toast.LENGTH_LONG).show();
}
};
mainHandler.post(myRunnable);
}
}).start();
dialog.dismiss();
})
.setNegativeButton(R.string.no, (dialog, which) -> dialog.dismiss())
.show();
break;
case R.id.action_edit:
if (context instanceof AccountActivity) {
editAlertDialog.show(account);
}
break;
}
return true;
});
popup.show();
});
holder.account_pp.setOnClickListener(v -> {
Intent intent = new Intent(context, ShowAccountActivity.class);
@ -243,6 +302,10 @@ public class AccountsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
void onAllAccountsRemoved();
}
public interface EditAlertDialog {
void show(Account account);
}
private static class ViewHolder extends RecyclerView.ViewHolder {
ImageView account_pp;
TextView account_ac;
@ -252,6 +315,7 @@ public class AccountsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
TextView account_sc;
TextView account_fgc;
TextView account_frc;
ImageButton more_actions;
LinearLayout account_info;
FloatingActionButton account_action;
LinearLayout account_container;
@ -268,6 +332,7 @@ public class AccountsListAdapter extends RecyclerView.Adapter<RecyclerView.ViewH
account_frc = itemView.findViewById(R.id.account_frc);
account_action = itemView.findViewById(R.id.account_action);
account_info = itemView.findViewById(R.id.account_info);
more_actions = itemView.findViewById(R.id.more_actions);
account_container = itemView.findViewById(R.id.account_container);
}
}

View File

@ -33,7 +33,6 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
@ -52,11 +51,12 @@ import app.fedilab.fedilabtube.client.PeertubeAPI;
import app.fedilab.fedilabtube.client.entities.Account;
import app.fedilab.fedilabtube.client.entities.ChannelCreation;
import app.fedilab.fedilabtube.drawer.AccountsListAdapter;
import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.viewmodel.AccountsVM;
import es.dmoral.toasty.Toasty;
public class DisplayAccountsFragment extends Fragment implements AccountsListAdapter.AllAccountsRemoved {
public class DisplayAccountsFragment extends Fragment implements AccountsListAdapter.AllAccountsRemoved, AccountsListAdapter.EditAlertDialog {
private boolean flag_loading;
private Context context;
@ -97,78 +97,7 @@ public class DisplayAccountsFragment extends Fragment implements AccountsListAda
if (getActivity() != null) {
action_button = getActivity().findViewById(R.id.action_button);
action_button.setOnClickListener(view -> {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
LayoutInflater inflater1 = ((Activity) context).getLayoutInflater();
View dialogView = inflater1.inflate(R.layout.add_channel, new LinearLayout(context), false);
dialogBuilder.setView(dialogView);
EditText display_name = dialogView.findViewById(R.id.display_name);
EditText name = dialogView.findViewById(R.id.name);
EditText description = dialogView.findViewById(R.id.description);
dialogBuilder.setPositiveButton(R.string.validate, (dialog, id) -> {
if (display_name.getText() != null && display_name.getText().toString().trim().length() > 0 && name.getText() != null && name.getText().toString().trim().length() > 0) {
ChannelCreation channelCreation = new ChannelCreation();
channelCreation.setDisplayName(display_name.getText().toString().trim());
channelCreation.setName(name.getText().toString().trim());
if (description.getText() != null && description.getText().toString().trim().length() > 0) {
channelCreation.setDescription(description.getText().toString().trim());
}
new Thread(() -> {
try {
new PeertubeAPI(context).createChannel(channelCreation);
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> {
DisplayPlaylistsFragment displayPlaylistsFragment;
if (getActivity() == null)
return;
displayPlaylistsFragment = (DisplayPlaylistsFragment) getActivity().getSupportFragmentManager().findFragmentByTag("CHANNELS");
final FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
if (displayPlaylistsFragment != null) {
ft.detach(displayPlaylistsFragment);
ft.attach(displayPlaylistsFragment);
ft.commit();
}
action_button.setEnabled(true);
};
mainHandler.post(myRunnable);
} catch (HttpsConnection.HttpsConnectionException e) {
action_button.setEnabled(true);
e.printStackTrace();
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> {
if (e.getMessage() != null) {
Toasty.error(context, e.getMessage(), Toast.LENGTH_LONG).show();
} else {
Toasty.error(context, context.getString(R.string.toast_error), Toast.LENGTH_LONG).show();
}
};
mainHandler.post(myRunnable);
}
}).start();
dialog.dismiss();
action_button.setEnabled(false);
} else {
Toasty.error(context, context.getString(R.string.error_display_name_channel), Toast.LENGTH_LONG).show();
}
});
dialogBuilder.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.dismiss());
AlertDialog alertDialog = dialogBuilder.create();
alertDialog.setTitle(getString(R.string.action_channel_create));
alertDialog.setOnDismissListener(dialogInterface -> {
//Hide keyboard
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
assert imm != null;
imm.hideSoftInputFromWindow(display_name.getWindowToken(), 0);
});
if (alertDialog.getWindow() != null)
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
alertDialog.show();
});
action_button.setOnClickListener(view -> manageAlert(null));
}
lv_accounts = rootView.findViewById(R.id.lv_elements);
lv_accounts.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL));
@ -179,6 +108,7 @@ public class DisplayAccountsFragment extends Fragment implements AccountsListAda
nextElementLoader.setVisibility(View.GONE);
accountsListAdapter = new AccountsListAdapter(accountFetch, this.accounts);
accountsListAdapter.allAccountsRemoved = this;
accountsListAdapter.editAlertDialog = this;
lv_accounts.setAdapter(accountsListAdapter);
TextView no_action_text = rootView.findViewById(R.id.no_action_text);
if (accountFetch == AccountsVM.accountFetch.MUTED) {
@ -312,4 +242,98 @@ public class DisplayAccountsFragment extends Fragment implements AccountsListAda
public void onAllAccountsRemoved() {
textviewNoAction.setVisibility(View.VISIBLE);
}
public void manageAlert(ChannelCreation oldChannelValues) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
LayoutInflater inflater1 = ((Activity) context).getLayoutInflater();
View dialogView = inflater1.inflate(R.layout.add_channel, new LinearLayout(context), false);
dialogBuilder.setView(dialogView);
EditText display_name = dialogView.findViewById(R.id.display_name);
EditText name = dialogView.findViewById(R.id.name);
EditText description = dialogView.findViewById(R.id.description);
if (oldChannelValues != null) {
display_name.setText(oldChannelValues.getDisplayName());
name.setText(oldChannelValues.getName());
description.setText(oldChannelValues.getDescription());
}
dialogBuilder.setPositiveButton(R.string.validate, (dialog, id) -> {
if (display_name.getText() != null && display_name.getText().toString().trim().length() > 0 && name.getText() != null && name.getText().toString().trim().length() > 0) {
ChannelCreation channelCreation = new ChannelCreation();
channelCreation.setDisplayName(display_name.getText().toString().trim());
channelCreation.setName(name.getText().toString().trim());
if (description.getText() != null && description.getText().toString().trim().length() > 0) {
channelCreation.setDescription(description.getText().toString().trim());
}
new Thread(() -> {
try {
if (oldChannelValues == null) {
new PeertubeAPI(context).createChannel(channelCreation);
} else {
new PeertubeAPI(context).updateChannel(name + "@" + Helper.getLiveInstance(context), channelCreation);
}
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> {
if (getActivity() == null)
return;
Account channel = new Account();
channel.setAcct(channelCreation.getName() + "@" + Helper.getLiveInstance(context));
channel.setUsername(channelCreation.getName());
channel.setDisplay_name(channelCreation.getDisplayName());
channel.setNote(channelCreation.getDescription());
accounts.add(0, channel);
accountsListAdapter.notifyItemInserted(0);
action_button.setEnabled(true);
};
mainHandler.post(myRunnable);
} catch (HttpsConnection.HttpsConnectionException e) {
e.printStackTrace();
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> {
action_button.setEnabled(true);
if (e.getMessage() != null) {
Toasty.error(context, e.getMessage(), Toast.LENGTH_LONG).show();
} else {
Toasty.error(context, context.getString(R.string.toast_error), Toast.LENGTH_LONG).show();
}
};
mainHandler.post(myRunnable);
}
}).start();
dialog.dismiss();
action_button.setEnabled(false);
} else {
Toasty.error(context, context.getString(R.string.error_display_name_channel), Toast.LENGTH_LONG).show();
}
});
dialogBuilder.setNegativeButton(R.string.cancel, (dialog, id) -> dialog.dismiss());
AlertDialog alertDialog = dialogBuilder.create();
alertDialog.setTitle(getString(R.string.action_channel_create));
alertDialog.setOnDismissListener(dialogInterface -> {
//Hide keyboard
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
assert imm != null;
imm.hideSoftInputFromWindow(display_name.getWindowToken(), 0);
});
if (alertDialog.getWindow() != null)
alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
alertDialog.show();
}
@Override
public void show(Account account) {
ChannelCreation oldChannelValues = new ChannelCreation();
oldChannelValues.setName(account.getUsername());
oldChannelValues.setDescription(account.getNote());
oldChannelValues.setDisplayName(account.getDisplay_name());
oldChannelValues.setId(account.getId());
manageAlert(oldChannelValues);
}
}

View File

@ -168,19 +168,14 @@ public class DisplayPlaylistsFragment extends Fragment {
playlistElement.setDescription(playlist.getDescription());
new Thread(() -> {
try {
new PeertubeAPI(context).createPlaylist(playlistElement);
String returnedId = new PeertubeAPI(context).createPlaylist(playlistElement);
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = () -> {
DisplayPlaylistsFragment displayPlaylistsFragment;
if (getActivity() == null)
return;
displayPlaylistsFragment = (DisplayPlaylistsFragment) getActivity().getSupportFragmentManager().findFragmentByTag("PLAYLISTS");
final FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
if (displayPlaylistsFragment != null) {
ft.detach(displayPlaylistsFragment);
ft.attach(displayPlaylistsFragment);
ft.commit();
}
playlist.setId(returnedId);
playlists.add(0, playlist);
playlistAdapter.notifyDataSetChanged();
};
mainHandler.post(myRunnable);
add_new.setEnabled(true);

View File

@ -147,6 +147,15 @@
</LinearLayout>
<ImageButton
android:id="@+id/more_actions"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:contentDescription="@string/display_more"
android:src="@drawable/ic_baseline_more_vert_24"
android:visibility="gone" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/account_action"