Allow to edit profile

This commit is contained in:
Thomas 2020-10-31 18:24:52 +01:00
parent ed9e79496a
commit fdc6e6e325
14 changed files with 301 additions and 18 deletions

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name" translatable="false">TubeAcad</string>
<string name="app_id" translatable="false">app.fedilab.fedilabtube</string>
<string name="set_video_mode_choice" translatable="false">set_video_mode_choice</string>
<string name="set_video_minimize_choice" translatable="false">set_video_minimize_choice</string>
<string name="set_video_language_choice" translatable="false">set_video_language_choice</string>
@ -9,10 +10,14 @@
<string name="set_autoplay_choice" translatable="false">set_autoplay_choice</string>
<string name="set_theme_choice" translatable="false">set_theme_choice</string>
<string name="set_fullscreen_choice" translatable="false">set_fullscreen_choice</string>
<string name="set_autoplay_next_videochoice" translatable="false">set_autoplay_next_videochoice</string>
<string name="set_autoplay_next_video_choice" translatable="false">set_autoplay_next_video_choice</string>
<string name="set_store_in_history">set_store_in_history</string>
<string name="save">Enregistrer</string>
<string name="set_autoplay_next_video">Lire automatiquement la vidéo suivante</string>
<string name="set_autoplay_next_video_description">Quand une vidéo est terminée, lire la prochaine vidéo suggérée.</string>
<string name="enable_history">Activer l\'historique</string>
<string name="set_autoplay">Lecture automatique</string>
<string name="set_autoplay_description">Si activé, les vidéos seront lues automatiquement</string>

View File

@ -1,5 +1,6 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<string name="app_name" translatable="false">Tubelab</string>
<string name="app_id" translatable="false">app.fedilab.tubelab</string>
<string name="set_video_mode_choice" translatable="false">set_video_mode_choice</string>
<string name="set_video_minimize_choice" translatable="false">set_video_minimize_choice</string>
<string name="set_video_language_choice" translatable="false">set_video_language_choice</string>
@ -7,10 +8,11 @@
<string name="set_video_cache_choice" translatable="false">set_video_cache_choice</string>
<string name="set_autoplay_choice" translatable="false">set_autoplay_choice</string>
<string name="set_store_in_history">set_store_in_history</string>
<string name="set_autoplay_next_videochoice" translatable="false">set_autoplay_next_videochoice</string>
<string name="set_autoplay_next_video_choice" translatable="false">set_autoplay_next_video_choice</string>
<string name="set_theme_choice" translatable="false">set_theme_choice</string>
<string name="set_fullscreen_choice" translatable="false">set_fullscreen_choice</string>
<string name="save">Save</string>
<string name="enable_history">Enable history</string>
<string name="set_autoplay">Automatic playback</string>
@ -18,7 +20,8 @@
<string name="set_fullscreen">Fullscreen</string>
<string name="set_fullscreen_description">Automatically open videos in fullscreen</string>
<string name="set_autoplay_next_video">Automatically start playing the next video</string>
<string name="set_autoplay_next_video_description">When a video ends, follow up with the next suggested video.</string>
<string name="add_public_reply">Add a public reply</string>

View File

@ -68,6 +68,11 @@
android:configChanges="orientation|screenSize"
android:label="@string/app_name"
android:windowSoftInputMode="stateAlwaysHidden" />
<activity
android:name=".MyAccountActivity"
android:configChanges="orientation|screenSize"
android:label="@string/app_name"
android:windowSoftInputMode="stateAlwaysHidden" />
<activity
android:name=".SearchActivity"
android:configChanges="orientation|screenSize"

View File

@ -75,6 +75,7 @@ public class MainActivity extends AppCompatActivity {
Fragment active;
private DisplayVideosFragment recentFragment, locaFragment, trendingFragment, subscriptionFragment, mostLikedFragment;
private DisplayOverviewFragment overviewFragment;
public static UserMe userMe;
private final BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= item -> {
@ -219,7 +220,7 @@ public class MainActivity extends AppCompatActivity {
});
});
UserMe userMe = new RetrofitPeertubeAPI(MainActivity.this, instance, token.getAccess_token()).verifyCredentials();
userMe = new RetrofitPeertubeAPI(MainActivity.this, instance, token.getAccess_token()).verifyCredentials();
if (userMe != null && userMe.getAccount() != null) {
new AccountDAO(MainActivity.this, db).updateAccount(userMe.getAccount());
SharedPreferences.Editor editor = sharedpreferences.edit();
@ -227,7 +228,7 @@ public class MainActivity extends AppCompatActivity {
editor.putString(Helper.PREF_KEY_NAME, account.getUsername());
editor.putBoolean(getString(R.string.set_autoplay_choice), userMe.isAutoPlayVideo());
editor.putBoolean(getString(R.string.set_store_in_history), userMe.isVideosHistoryEnabled());
editor.putBoolean(getString(R.string.set_autoplay_next_videochoice), userMe.isAutoPlayNextVideo());
editor.putBoolean(getString(R.string.set_autoplay_next_video_choice), userMe.isAutoPlayNextVideo());
//Sync languages from server
List<String> videoLanguageServer = userMe.getVideoLanguages();
if (videoLanguageServer != null) {
@ -411,7 +412,7 @@ public class MainActivity extends AppCompatActivity {
try {
RetrofitPeertubeAPI api = new RetrofitPeertubeAPI(MainActivity.this);
api.updateUser(userSettings);
} catch (Exception e) {
} catch (Exception | Error e) {
e.printStackTrace();
}
}).start();

View File

@ -0,0 +1,74 @@
package app.fedilab.fedilabtube;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
import app.fedilab.fedilabtube.client.entities.Error;
import app.fedilab.fedilabtube.client.entities.UserSettings;
import app.fedilab.fedilabtube.databinding.ActivityMyAccountSettingsBinding;
import es.dmoral.toasty.Toasty;
/* 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>. */
public class MyAccountActivity extends AppCompatActivity {
ActivityMyAccountSettingsBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMyAccountSettingsBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
if (getSupportActionBar() != null)
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
if( MainActivity.userMe == null) {
finish();
return;
}
setTitle(String.format("@%s",MainActivity.userMe.getUsername()));
binding.displayname.setText(MainActivity.userMe.getAccount().getDisplayName());
binding.description.setText(MainActivity.userMe.getAccount().getDescription());
binding.save.setOnClickListener(v -> new Thread(() -> {
UserSettings userSettings = new UserSettings();
userSettings.setDisplayName(binding.displayname.getText().toString().trim());
userSettings.setDescription(binding.description.getText().toString().trim());
try {
RetrofitPeertubeAPI api = new RetrofitPeertubeAPI(MyAccountActivity.this);
api.updateUser(userSettings);
MainActivity.userMe.getAccount().setDisplayName(binding.displayname.getText().toString().trim());
MainActivity.userMe.getAccount().setDescription(binding.description.getText().toString().trim());
} catch (Exception | Error e) {
Toasty.error(MyAccountActivity.this, getString(R.string.toast_error), Toasty.LENGTH_LONG).show();
}
}).start());
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}

View File

@ -1477,7 +1477,9 @@ public class PeertubeActivity extends AppCompatActivity implements CommentListAd
@Override
public void onMediaItemTransition(MediaItem mediaItem, int reason) {
if (reason == MEDIA_ITEM_TRANSITION_REASON_AUTO){
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
boolean autoplayNextVideo = sharedpreferences.getBoolean(getString(R.string.set_autoplay_next_video_choice), true);
if (reason == MEDIA_ITEM_TRANSITION_REASON_AUTO && autoplayNextVideo){
player.removeMediaItems(0, player.getMediaItemCount());
playNextVideo();
}

View File

@ -129,6 +129,7 @@ public interface PeertubeService {
@Header("Authorization") String credentials,
@Field("videosHistoryEnabled") Boolean videosHistoryEnabled,
@Field("autoPlayVideo") Boolean autoPlayVideo,
@Field("autoPlayNextVideo") Boolean autoPlayNextVideo,
@Field("webTorrentEnabled") Boolean webTorrentEnabled,
@Field("videoLanguages") List<String> videoLanguages,
@Field("description") String description,

View File

@ -451,26 +451,31 @@ public class RetrofitPeertubeAPI {
*
* @param userSettings UserSettings
*/
public void updateUser(UserSettings userSettings) {
public void updateUser(UserSettings userSettings) throws IOException, Error {
APIResponse apiResponse = new APIResponse();
PeertubeService peertubeService = init();
Call<String> updateUser = peertubeService.updateUser(getToken(),
userSettings.isVideosHistoryEnabled(),
userSettings.isAutoPlayVideo(),
userSettings.isAutoPlayNextVideo(),
userSettings.isWebTorrentEnabled(),
userSettings.getVideoLanguages(),
userSettings.getDescription(),
userSettings.getDisplayName()
);
try {
Response<String> response = updateUser.execute();
if (response.isSuccessful()) {
apiResponse.setActionReturn(response.body());
Response<String> response = updateUser.execute();
if (response.isSuccessful()) {
apiResponse.setActionReturn(response.body());
} else {
setError(apiResponse, response.code(), response.errorBody());
Error error = new Error();
error.setStatusCode(response.code());
if (response.errorBody() != null) {
error.setError(response.errorBody().string());
} else {
setError(apiResponse, response.code(), response.errorBody());
error.setError(_context.getString(R.string.toast_error));
}
} catch (IOException e) {
e.printStackTrace();
throw error;
}
if (userSettings.getAvatarfile() != null) {
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), userSettings.getAvatarfile());

View File

@ -17,11 +17,13 @@ package app.fedilab.fedilabtube.client.entities;
import java.util.List;
import java.io.File;
@SuppressWarnings({"unused", "RedundantSuppression"})
public class UserSettings {
private Boolean videosHistoryEnabled;
private Boolean autoPlayVideo;
private Boolean webTorrentEnabled;
private Boolean autoPlayNextVideo;
private List<String> videoLanguages;
private String description;
private String displayName;
@ -82,4 +84,24 @@ public class UserSettings {
public void setAvatarfile(File avatarfile) {
this.avatarfile = avatarfile;
}
public Boolean getVideosHistoryEnabled() {
return videosHistoryEnabled;
}
public Boolean getAutoPlayVideo() {
return autoPlayVideo;
}
public Boolean getWebTorrentEnabled() {
return webTorrentEnabled;
}
public Boolean isAutoPlayNextVideo() {
return autoPlayNextVideo;
}
public void setAutoPlayNextVideo(Boolean autoPlayNextVideo) {
this.autoPlayNextVideo = autoPlayNextVideo;
}
}

View File

@ -2,16 +2,28 @@ package app.fedilab.fedilabtube.fragment;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.res.ResourcesCompat;
import androidx.fragment.app.FragmentActivity;
import androidx.preference.ListPreference;
import androidx.preference.MultiSelectListPreference;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceScreen;
import androidx.preference.SeekBarPreference;
import androidx.preference.SwitchPreference;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
@ -19,15 +31,16 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import app.fedilab.fedilabtube.R;
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
import app.fedilab.fedilabtube.client.entities.Error;
import app.fedilab.fedilabtube.client.entities.UserSettings;
import app.fedilab.fedilabtube.helper.Helper;
import app.fedilab.fedilabtube.helper.ThemeHelper;
import es.dmoral.toasty.Toasty;
import static app.fedilab.fedilabtube.MainActivity.peertubeInformation;
import static app.fedilab.fedilabtube.MainActivity.userMe;
/* Copyright 2020 Thomas Schneider
*
@ -150,7 +163,7 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
try {
RetrofitPeertubeAPI api = new RetrofitPeertubeAPI(getActivity());
api.updateUser(userSettings);
} catch (Exception e) {
} catch (Exception | Error e) {
e.printStackTrace();
}
}).start();
@ -161,6 +174,23 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
assert set_fullscreen_choice != null;
editor.putBoolean(getString(R.string.set_fullscreen_choice), set_fullscreen_choice.isChecked());
}
if (key.compareTo(getString(R.string.set_autoplay_next_video_choice)) == 0) {
SwitchPreference set_autoplay_next_video_choice = findPreference(getString(R.string.set_autoplay_next_video_choice));
assert set_autoplay_next_video_choice != null;
editor.putBoolean(getString(R.string.set_autoplay_next_video_choice), set_autoplay_next_video_choice.isChecked());
if(Helper.isLoggedIn(getActivity())) {
new Thread(() -> {
UserSettings userSettings = new UserSettings();
userSettings.setAutoPlayNextVideo(set_autoplay_next_video_choice.isChecked());
try {
RetrofitPeertubeAPI api = new RetrofitPeertubeAPI(getActivity());
api.updateUser(userSettings);
} catch (Exception | Error e) {
e.printStackTrace();
}
}).start();
}
}
if (key.compareTo(getString(R.string.set_video_language_choice)) == 0) {
MultiSelectListPreference set_video_language_choice = findPreference(getString(R.string.set_video_language_choice));
assert set_video_language_choice != null;
@ -173,7 +203,7 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
try {
RetrofitPeertubeAPI api = new RetrofitPeertubeAPI(getActivity());
api.updateUser(userSettings);
} catch (Exception e) {
} catch (Exception | Error e) {
e.printStackTrace();
}
}).start();
@ -194,6 +224,33 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
return;
}
//****** My Account ******
Preference my_account = findPreference("my_account");
if(!Helper.isLoggedIn(getActivity()) || userMe == null) {
my_account.setVisible(false);
} else {
my_account.setTitle(userMe.getUsername());
my_account.setSummary(userMe.getEmail());
Resources resources = getResources();
Drawable defaultAvatar = ResourcesCompat.getDrawable(resources, R.drawable.missing_peertube, null);
my_account.setIcon(defaultAvatar);
Glide.with(getActivity())
.asDrawable()
.load("https://" + Helper.getLiveInstance(context) + userMe.getAccount().getAvatar().getPath())
.into(new CustomTarget<Drawable>() {
@Override
public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
my_account.setIcon(resource);
}
@Override
public void onLoadCleared(@Nullable Drawable placeholder) {
}
});
}
//****** App theme *******
ListPreference set_theme_choice = findPreference(getString(R.string.set_theme_choice));
List<String> arrayTheme = Arrays.asList(getResources().getStringArray(R.array.settings_theme));
@ -250,6 +307,10 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
SwitchPreference set_video_minimize_choice = findPreference(getString(R.string.set_video_minimize_choice));
assert set_video_minimize_choice != null;
set_video_minimize_choice.setChecked(minimized);
if ( Build.VERSION.SDK_INT < Build.VERSION_CODES.O
|| !getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)) {
set_video_minimize_choice.setVisible(false);
}
//****** Autoplay videos *******
@ -265,6 +326,12 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Shared
assert set_fullscreen_choice != null;
set_fullscreen_choice.setChecked(fullscreen);
//****** Autoplay next videos *******
boolean autoplayNextVideo = sharedpref.getBoolean(getString(R.string.set_autoplay_next_video_choice), false);
SwitchPreference set_autoplay_next_video_choice = findPreference(getString(R.string.set_autoplay_next_video_choice));
assert set_autoplay_next_video_choice != null;
set_autoplay_next_video_choice.setChecked(autoplayNextVideo);
//****** Language filter *********
LinkedHashMap<String, String> languages = new LinkedHashMap<>(peertubeInformation.getLanguages());
List<CharSequence> entriesLanguages = new ArrayList<>();

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M21,3L3,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,5c0,-1.1 -0.9,-2 -2,-2zM12,11L3,11L3,9h9v2zM12,7L3,7L3,5h9v2z"/>
</vector>

View File

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/displayname_container"
android:layout_width="match_parent"
android:layout_marginTop="50dp"
android:layout_height="wrap_content"
android:layout_marginStart="50dp"
android:layout_marginEnd="50dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/displayname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/display_name"
android:inputType="text"
android:singleLine="true" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/description_container"
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_marginStart="50dp"
android:layout_marginEnd="50dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/displayname_container">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/description"
android:inputType="textMultiLine"
android:gravity="top"
android:lines="4"
android:minLines="4"
android:maxLines="6"
android:singleLine="false" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/save"
style="@style/Base.Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="30dp"
android:gravity="center"
android:singleLine="true"
android:text="@string/save"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/description_container" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Button android:id="@+id/set_preview"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:text="@string/save"
xmlns:android="http://schemas.android.com/apk/res/android" />

View File

@ -3,6 +3,14 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:key="app_prefs">
<Preference
android:key="my_account">
<intent
android:action="android.intent.action.VIEW"
android:targetPackage="@string/app_id"
android:targetClass="app.fedilab.fedilabtube.MyAccountActivity" />
</Preference>
<PreferenceCategory android:title="@string/video_settings">
<androidx.preference.ListPreference
android:icon="@drawable/ic_baseline_slow_motion_video_24"
@ -33,6 +41,12 @@
android:summary="@string/set_fullscreen_description"
android:title="@string/set_fullscreen" />
<androidx.preference.SwitchPreference
android:icon="@drawable/ic_baseline_featured_play_list_24"
android:key="@string/set_autoplay_next_video_choice"
android:summary="@string/set_autoplay_next_video_description"
android:title="@string/set_autoplay_next_video" />
<androidx.preference.SeekBarPreference
android:icon="@drawable/ic_baseline_storage_24"
android:defaultValue="10"