push notifications
This commit is contained in:
parent
631264eb57
commit
029b8b57ae
|
@ -130,5 +130,10 @@ dependencies {
|
|||
implementation "io.github.kobakei:ratethisapp:1.2.0"
|
||||
implementation 'com.github.HITGIF:TextFieldBoxes:1.4.5'
|
||||
implementation 'com.github.vkay94:DoubleTapPlayerView:1.0.0'
|
||||
implementation "ss.anoop:awesome-textinput-layout:1.0.3"
|
||||
|
||||
implementation "androidx.work:work-runtime:2.4.0"
|
||||
implementation "androidx.work:work-runtime-ktx:2.4.0"
|
||||
|
||||
|
||||
}
|
|
@ -11,11 +11,29 @@
|
|||
<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_video_choice" translatable="false">set_autoplay_next_video_choice</string>
|
||||
<string name="set_store_in_history">set_store_in_history</string>
|
||||
<string name="set_store_in_history" translatable="false">set_store_in_history</string>
|
||||
|
||||
<string name="change_profile_picture">Modifier la photo de profil</string>
|
||||
<string name="account_updated">Le compte a été mis à jour !</string>
|
||||
|
||||
|
||||
<string name="new_video">Nouvelle vidéo</string>
|
||||
<string name="new_blacklist">New blacklist info</string>
|
||||
<string name="new_my_video_published">Your video is published</string>
|
||||
<string name="new_my_video_error">Error when publishing your video</string>
|
||||
<string name="new_comment">New comment</string>
|
||||
<string name="new_follow">New follow</string>
|
||||
|
||||
<string name="notif_new_video">Nouvelle vidéo depuis vos souscriptions</string>
|
||||
<string name="notif_new_comment">Nouveau commentaire sur votre vidéo</string>
|
||||
<string name="notif_blocked">Une de vos vidéos est bloquée/débloquée</string>
|
||||
<string name="notif_video_published">Vidéo publiée (après transcodage / mise à jour programmée)</string>
|
||||
<string name="notif_video_imported">Import de vidéo terminé</string>
|
||||
<string name="notif_new_followers">Vous ou votre chaîne avez/a un·e nouvel·le abonné·e</string>
|
||||
<string name="notif_video_mention">Quelqu\'un vous a mentionné dans les commentaires d\'une vidéo</string>
|
||||
<string name="notif_abuse_received">Un signalement d\'abus a reçu un nouveau message</string>
|
||||
<string name="notif_abuse_accepted">Un de vos rapports d\'abus a été accepté ou rejeté par les modérateurs</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>
|
||||
|
@ -35,6 +53,16 @@
|
|||
<item>Automatique</item>
|
||||
</string-array>
|
||||
|
||||
<string name="refresh_every">Mettre à jour toutes les :</string>
|
||||
<string-array name="refresh_time">
|
||||
<item>Jamais</item>
|
||||
<item>15 minutes</item>
|
||||
<item>30 minutes</item>
|
||||
<item>1 heure</item>
|
||||
<item>2 heures</item>
|
||||
<item>6 heures</item>
|
||||
<item>12 heures</item>
|
||||
</string-array>
|
||||
|
||||
<plurals name="number_of_replies">
|
||||
<item quantity="zero">%d réponse</item>
|
||||
|
@ -206,7 +234,9 @@
|
|||
<string name="add_public_reply">Répondre publiquement</string>
|
||||
<string name="send_comment">Envoyer un commentaire</string>
|
||||
<string name="all">Tout</string>
|
||||
|
||||
<string name="activity">Activité</string>
|
||||
<string name="app">App</string>
|
||||
<string name="fetch_notification_channel_name">Mise à jour des notifications</string>
|
||||
<string name="peertube_video_report_success"><![CDATA[ Votre signalement <b>%1$s</b> a été accepté]]></string>
|
||||
<string name="reply">Répondre</string>
|
||||
<!-- end languages -->
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<string name="set_video_quality_choice" translatable="false">set_video_quality_choice</string>
|
||||
<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_store_in_history" translatable="false">set_store_in_history</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>
|
||||
|
@ -24,6 +24,17 @@
|
|||
<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>
|
||||
|
||||
<string name="activity">Activity</string>
|
||||
<string name="app">App</string>
|
||||
<string name="notif_new_video">New video from your subscriptions</string>
|
||||
<string name="notif_new_comment">New comment on your video</string>
|
||||
<string name="notif_blocked">One of your video is blocked/unblocked</string>
|
||||
<string name="notif_video_published">Video published (after transcoding/scheduled update)</string>
|
||||
<string name="notif_video_imported">Video import finished</string>
|
||||
<string name="notif_new_followers">You or your channel(s) has a new follower</string>
|
||||
<string name="notif_video_mention">Someone mentioned you in video comments</string>
|
||||
<string name="notif_abuse_received">An abuse report received a new message</string>
|
||||
<string name="notif_abuse_accepted">One of your abuse reports has been accepted or rejected by moderators</string>
|
||||
|
||||
<plurals name="number_of_replies">
|
||||
<item quantity="one">%d reply</item>
|
||||
|
@ -59,10 +70,28 @@
|
|||
<string name="image_preview">Image preview</string>
|
||||
<string name="file_to_upload">Select the file to upload</string>
|
||||
|
||||
<string name="new_video">New video</string>
|
||||
<string name="new_blacklist">New blacklist info</string>
|
||||
<string name="new_my_video_published">Your video is published</string>
|
||||
<string name="new_my_video_error">Error when publishing your video</string>
|
||||
<string name="new_comment">New comment</string>
|
||||
<string name="new_follow">New follow</string>
|
||||
|
||||
<string name="channel">Channel</string>
|
||||
<string name="videos">Videos</string>
|
||||
<string name="channels">Channels</string>
|
||||
|
||||
<string name="refresh_every">Fetch every:</string>
|
||||
<string-array name="refresh_time">
|
||||
<item>Never</item>
|
||||
<item>15 minutes</item>
|
||||
<item>30 minutes</item>
|
||||
<item>1 hour</item>
|
||||
<item>2 hours</item>
|
||||
<item>6 hours</item>
|
||||
<item>12 hours</item>
|
||||
</string-array>
|
||||
|
||||
<string name="yes">Yes</string>
|
||||
<string name="no">No</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
|
@ -352,6 +381,7 @@
|
|||
<string name="pickup_categories">Pick categories</string>
|
||||
<string name="pickup_languages">Pick languages</string>
|
||||
<string name="notification_channel_name">Update information</string>
|
||||
<string name="fetch_notification_channel_name">Fetch notifications</string>
|
||||
|
||||
<string name="add_account">Add an account</string>
|
||||
<string name="list_of_accounts">List of accounts</string>
|
||||
|
|
|
@ -150,6 +150,12 @@
|
|||
<action android:name="app.fedilab.fedilabtube.uploadservice.broadcast.status" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<provider
|
||||
android:name="androidx.work.impl.WorkManagerInitializer"
|
||||
android:authorities="${applicationId}.workmanager-init"
|
||||
tools:node="remove"
|
||||
android:exported="false" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -19,13 +19,34 @@ import android.content.SharedPreferences;
|
|||
|
||||
import androidx.multidex.MultiDex;
|
||||
import androidx.multidex.MultiDexApplication;
|
||||
import androidx.work.Configuration;
|
||||
import androidx.work.WorkManager;
|
||||
|
||||
import net.gotev.uploadservice.UploadService;
|
||||
|
||||
import app.fedilab.fedilabtube.helper.Helper;
|
||||
import app.fedilab.fedilabtube.helper.ThemeHelper;
|
||||
import app.fedilab.fedilabtube.worker.WorkHelper;
|
||||
|
||||
public class FedilabTube extends MultiDexApplication {
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
int interval = sharedpreferences.getInt(Helper.NOTIFICATION_INTERVAL, 60);
|
||||
|
||||
Configuration myConfig = new Configuration.Builder()
|
||||
.setMinimumLoggingLevel(android.util.Log.INFO)
|
||||
.build();
|
||||
WorkManager.initialize(FedilabTube.this, myConfig);
|
||||
if( interval >= 15 ) {
|
||||
WorkHelper.fetchNotifications(this, interval);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void attachBaseContext(Context base) {
|
||||
super.attachBaseContext(base);
|
||||
|
@ -36,6 +57,8 @@ public class FedilabTube extends MultiDexApplication {
|
|||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
int themePref = sharedpreferences.getInt(Helper.SET_THEME, Helper.DEFAULT_MODE);
|
||||
ThemeHelper.switchTo(themePref);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,20 +22,16 @@ import android.text.SpannableString;
|
|||
import android.text.Spanned;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.UnderlineSpan;
|
||||
import android.util.Patterns;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
|
||||
|
@ -43,6 +39,7 @@ import app.fedilab.fedilabtube.client.entities.Error;
|
|||
import app.fedilab.fedilabtube.client.entities.Oauth;
|
||||
import app.fedilab.fedilabtube.client.entities.OauthParams;
|
||||
import app.fedilab.fedilabtube.client.entities.Token;
|
||||
import app.fedilab.fedilabtube.databinding.ActivityLoginBinding;
|
||||
import app.fedilab.fedilabtube.helper.Helper;
|
||||
import es.dmoral.toasty.Toasty;
|
||||
|
||||
|
@ -54,29 +51,26 @@ public class LoginActivity extends AppCompatActivity {
|
|||
|
||||
private static String client_id;
|
||||
private static String client_secret;
|
||||
private EditText login_uid;
|
||||
private EditText login_passwd;
|
||||
private Button connectionButton;
|
||||
private TextInputEditText login_instance;
|
||||
private ActivityLoginBinding binding;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
binding = ActivityLoginBinding.inflate(getLayoutInflater());
|
||||
View view = binding.getRoot();
|
||||
setContentView(view);
|
||||
|
||||
|
||||
setContentView(R.layout.activity_login);
|
||||
if (getSupportActionBar() != null)
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
TextView create_an_account_peertube = findViewById(R.id.create_an_account_peertube);
|
||||
|
||||
SpannableString content_create = new SpannableString(getString(R.string.join_peertube));
|
||||
content_create.setSpan(new UnderlineSpan(), 0, content_create.length(), 0);
|
||||
content_create.setSpan(new ForegroundColorSpan(ContextCompat.getColor(LoginActivity.this, Helper.getColorAccent())), 0, content_create.length(),
|
||||
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
create_an_account_peertube.setText(content_create);
|
||||
binding.createAnAccountPeertube.setText(content_create, TextView.BufferType.SPANNABLE);
|
||||
|
||||
create_an_account_peertube.setOnClickListener(v -> {
|
||||
binding.createAnAccountPeertube.setOnClickListener(v -> {
|
||||
Intent mainActivity = new Intent(LoginActivity.this, PeertubeRegisterActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
mainActivity.putExtras(b);
|
||||
|
@ -84,42 +78,35 @@ public class LoginActivity extends AppCompatActivity {
|
|||
});
|
||||
|
||||
|
||||
TextInputLayout login_instance_container = findViewById(R.id.login_instance_container);
|
||||
login_instance = findViewById(R.id.login_instance);
|
||||
if (BuildConfig.full_instances) {
|
||||
login_instance_container.setVisibility(View.VISIBLE);
|
||||
binding.loginInstanceContainer.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
login_uid = findViewById(R.id.login_uid);
|
||||
login_passwd = findViewById(R.id.login_passwd);
|
||||
|
||||
if (Helper.isTablet(LoginActivity.this)) {
|
||||
|
||||
ViewGroup.LayoutParams layoutParamsI = login_instance_container.getLayoutParams();
|
||||
ViewGroup.LayoutParams layoutParamsI = binding.loginInstanceContainer.getLayoutParams();
|
||||
layoutParamsI.width = (int) Helper.convertDpToPixel(300, LoginActivity.this);
|
||||
login_instance_container.setLayoutParams(layoutParamsI);
|
||||
binding.loginInstanceContainer.setLayoutParams(layoutParamsI);
|
||||
|
||||
TextInputLayout login_uid_container = findViewById(R.id.login_uid_container);
|
||||
ViewGroup.LayoutParams layoutParamsU = login_uid_container.getLayoutParams();
|
||||
ViewGroup.LayoutParams layoutParamsU = binding.loginUidContainer.getLayoutParams();
|
||||
layoutParamsU.width = (int) Helper.convertDpToPixel(300, LoginActivity.this);
|
||||
login_uid_container.setLayoutParams(layoutParamsU);
|
||||
binding.loginUidContainer.setLayoutParams(layoutParamsU);
|
||||
|
||||
TextInputLayout login_passwd_container = findViewById(R.id.login_passwd_container);
|
||||
ViewGroup.LayoutParams layoutParamsP = login_passwd_container.getLayoutParams();
|
||||
ViewGroup.LayoutParams layoutParamsP = binding.loginPasswdContainer.getLayoutParams();
|
||||
layoutParamsP.width = (int) Helper.convertDpToPixel(300, LoginActivity.this);
|
||||
login_passwd_container.setLayoutParams(layoutParamsP);
|
||||
binding.loginPasswdContainer.setLayoutParams(layoutParamsP);
|
||||
}
|
||||
|
||||
|
||||
connectionButton = findViewById(R.id.login_button);
|
||||
|
||||
if (!BuildConfig.full_instances) {
|
||||
login_uid.setOnFocusChangeListener((v, hasFocus) -> {
|
||||
binding.loginUid.setOnFocusChangeListener((v, hasFocus) -> {
|
||||
if (!hasFocus) {
|
||||
if (android.util.Patterns.EMAIL_ADDRESS.matcher(login_uid.getText().toString().trim()).matches()) {
|
||||
String[] emailArray = login_uid.getText().toString().split("@");
|
||||
if (binding.loginUid.getText() != null && android.util.Patterns.EMAIL_ADDRESS.matcher(binding.loginUid.getText().toString().trim()).matches()) {
|
||||
String[] emailArray = binding.loginUid.getText().toString().split("@");
|
||||
if (emailArray.length > 1 && Arrays.asList(Helper.openid).contains(emailArray[1])) {
|
||||
connectionButton.callOnClick();
|
||||
binding.loginButton.callOnClick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -127,30 +114,35 @@ public class LoginActivity extends AppCompatActivity {
|
|||
}
|
||||
|
||||
|
||||
connectionButton.setOnClickListener(v -> {
|
||||
binding.loginButton.setOnClickListener(v -> {
|
||||
|
||||
if (login_uid.getText().toString().contains("@") && !android.util.Patterns.EMAIL_ADDRESS.matcher(login_uid.getText().toString().trim()).matches()) {
|
||||
if (binding.loginUid.getText() != null && binding.loginUid.getText().toString().contains("@") && !android.util.Patterns.EMAIL_ADDRESS.matcher(binding.loginUid.getText().toString().trim()).matches()) {
|
||||
Toasty.error(LoginActivity.this, getString(R.string.email_error)).show();
|
||||
return;
|
||||
}
|
||||
connectionButton.setEnabled(false);
|
||||
binding.loginButton.setEnabled(false);
|
||||
String instance, host;
|
||||
if (!BuildConfig.full_instances) {
|
||||
String[] emailArray = login_uid.getText().toString().split("@");
|
||||
String[] emailArray = binding.loginUid.getText().toString().split("@");
|
||||
if (emailArray.length > 1 && !Arrays.asList(Helper.valideEmails).contains(emailArray[1])) {
|
||||
Toasty.error(LoginActivity.this, getString(R.string.email_error_domain, emailArray[1])).show();
|
||||
connectionButton.setEnabled(true);
|
||||
binding.loginButton.setEnabled(true);
|
||||
return;
|
||||
}
|
||||
host = emailArray[1];
|
||||
instance = Helper.getPeertubeUrl(host);
|
||||
} else {
|
||||
if (login_instance == null || login_instance.getText() == null || login_instance.getText().toString().trim().length() == 0) {
|
||||
if (binding.loginInstance.getText() == null || binding.loginInstance.getText().toString().trim().length() == 0) {
|
||||
Toasty.error(LoginActivity.this, getString(R.string.not_valide_instance)).show();
|
||||
connectionButton.setEnabled(true);
|
||||
binding.loginButton.setEnabled(true);
|
||||
return;
|
||||
}
|
||||
instance = host = login_instance.getText().toString().trim().toLowerCase();
|
||||
instance = host = binding.loginInstance.getText().toString().trim().toLowerCase();
|
||||
}
|
||||
if (!Patterns.WEB_URL.matcher("https://"+instance).matches()) {
|
||||
Toasty.error(LoginActivity.this, getString(R.string.not_valide_instance)).show();
|
||||
binding.loginButton.setEnabled(true);
|
||||
return;
|
||||
}
|
||||
if (Arrays.asList(Helper.openid).contains(host) && !BuildConfig.full_instances) {
|
||||
new Thread(() -> {
|
||||
|
@ -158,7 +150,7 @@ public class LoginActivity extends AppCompatActivity {
|
|||
Oauth oauth = new RetrofitPeertubeAPI(LoginActivity.this, instance, null).oauthClient(null, null, null, null);
|
||||
if (oauth == null) {
|
||||
runOnUiThread(() -> {
|
||||
connectionButton.setEnabled(true);
|
||||
binding.loginButton.setEnabled(true);
|
||||
Toasty.error(LoginActivity.this, getString(R.string.client_error), Toast.LENGTH_LONG).show();
|
||||
});
|
||||
return;
|
||||
|
@ -179,7 +171,7 @@ public class LoginActivity extends AppCompatActivity {
|
|||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
runOnUiThread(() -> {
|
||||
connectionButton.setEnabled(true);
|
||||
binding.loginButton.setEnabled(true);
|
||||
Toasty.error(LoginActivity.this, getString(R.string.toast_error), Toast.LENGTH_LONG).show();
|
||||
});
|
||||
}
|
||||
|
@ -190,7 +182,7 @@ public class LoginActivity extends AppCompatActivity {
|
|||
Oauth oauth = new RetrofitPeertubeAPI(LoginActivity.this, instance, null).oauthClient(Helper.CLIENT_NAME_VALUE, Helper.WEBSITE_VALUE, Helper.OAUTH_SCOPES_PEERTUBE, Helper.WEBSITE_VALUE);
|
||||
if (oauth == null) {
|
||||
runOnUiThread(() -> {
|
||||
connectionButton.setEnabled(true);
|
||||
binding.loginButton.setEnabled(true);
|
||||
Toasty.error(LoginActivity.this, getString(R.string.client_error), Toast.LENGTH_LONG).show();
|
||||
});
|
||||
return;
|
||||
|
@ -209,20 +201,22 @@ public class LoginActivity extends AppCompatActivity {
|
|||
oauthParams.setClient_secret(client_secret);
|
||||
oauthParams.setGrant_type("password");
|
||||
oauthParams.setScope("user");
|
||||
oauthParams.setUsername(login_uid.getText().toString().trim());
|
||||
oauthParams.setPassword(login_passwd.getText().toString());
|
||||
oauthParams.setUsername(binding.loginUid.getText().toString().trim());
|
||||
if( binding.loginPasswd.getText() != null) {
|
||||
oauthParams.setPassword(binding.loginPasswd.getText().toString());
|
||||
}
|
||||
try {
|
||||
Token token = new RetrofitPeertubeAPI(LoginActivity.this, instance, null).manageToken(oauthParams);
|
||||
proceedLogin(token, host);
|
||||
} catch (final Exception | Error e) {
|
||||
oauthParams.setUsername(login_uid.getText().toString().toLowerCase().trim());
|
||||
oauthParams.setUsername(binding.loginUid.getText().toString().toLowerCase().trim());
|
||||
try {
|
||||
Token token = new RetrofitPeertubeAPI(LoginActivity.this, instance, null).manageToken(oauthParams);
|
||||
proceedLogin(token, host);
|
||||
} catch (Error error) {
|
||||
Error.displayError(LoginActivity.this, error);
|
||||
error.printStackTrace();
|
||||
runOnUiThread(() -> connectionButton.setEnabled(true));
|
||||
runOnUiThread(() -> binding.loginButton.setEnabled(true));
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
@ -243,7 +237,7 @@ public class LoginActivity extends AppCompatActivity {
|
|||
//Update the account with the token;
|
||||
updateCredential(LoginActivity.this, token.getAccess_token(), client_id, client_secret, token.getRefresh_token(), host);
|
||||
} else {
|
||||
connectionButton.setEnabled(true);
|
||||
binding.loginButton.setEnabled(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,37 +1,4 @@
|
|||
package app.fedilab.fedilabtube;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.documentfile.provider.DocumentFile;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
|
||||
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
|
||||
import app.fedilab.fedilabtube.client.entities.Error;
|
||||
import app.fedilab.fedilabtube.client.entities.UserMe;
|
||||
import app.fedilab.fedilabtube.client.entities.UserSettings;
|
||||
import app.fedilab.fedilabtube.databinding.ActivityMyAccountSettingsBinding;
|
||||
import app.fedilab.fedilabtube.helper.Helper;
|
||||
import es.dmoral.toasty.Toasty;
|
||||
|
||||
import static app.fedilab.fedilabtube.PeertubeUploadActivity.MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE;
|
||||
|
||||
/* Copyright 2020 Thomas Schneider
|
||||
*
|
||||
* This file is a part of TubeLab
|
||||
|
@ -46,6 +13,49 @@ import static app.fedilab.fedilabtube.PeertubeUploadActivity.MY_PERMISSIONS_REQU
|
|||
*
|
||||
* 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.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.SwitchCompat;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.documentfile.provider.DocumentFile;
|
||||
import androidx.work.WorkManager;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.resource.bitmap.CenterCrop;
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
|
||||
import app.fedilab.fedilabtube.client.entities.Error;
|
||||
import app.fedilab.fedilabtube.client.entities.NotificationSettings;
|
||||
import app.fedilab.fedilabtube.client.entities.UserMe;
|
||||
import app.fedilab.fedilabtube.client.entities.UserSettings;
|
||||
import app.fedilab.fedilabtube.databinding.ActivityMyAccountSettingsBinding;
|
||||
import app.fedilab.fedilabtube.helper.Helper;
|
||||
import app.fedilab.fedilabtube.worker.WorkHelper;
|
||||
import es.dmoral.toasty.Toasty;
|
||||
|
||||
import static app.fedilab.fedilabtube.PeertubeUploadActivity.MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE;
|
||||
import static app.fedilab.fedilabtube.worker.WorkHelper.NOTIFICATION_WORKER;
|
||||
|
||||
public class MyAccountActivity extends AppCompatActivity {
|
||||
|
||||
|
@ -53,6 +63,7 @@ public class MyAccountActivity extends AppCompatActivity {
|
|||
private static final int PICK_IMAGE = 466;
|
||||
private Uri inputData;
|
||||
private String fileName;
|
||||
private NotificationSettings notificationSettings;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -71,8 +82,93 @@ public class MyAccountActivity extends AppCompatActivity {
|
|||
binding.displayname.setText(MainActivity.userMe.getAccount().getDisplayName());
|
||||
binding.description.setText(MainActivity.userMe.getAccount().getDescription());
|
||||
|
||||
notificationSettings = MainActivity.userMe.getNotificationSettings();
|
||||
initializeValues(notificationSettings.getAbuseStateChange(), binding.notifAbuseAcceptedApp, binding.notifAbuseAcceptedMail);
|
||||
initializeValues(notificationSettings.getAbuseNewMessage(), binding.notifAbuseReceivedApp, binding.notifAbuseReceivedMail);
|
||||
initializeValues(notificationSettings.getCommentMention(), binding.notifVideoMentionApp, binding.notifVideoMentionMail);
|
||||
initializeValues(notificationSettings.getNewFollow(), binding.notifNewFollowersApp, binding.notifNewFollowersMail);
|
||||
initializeValues(notificationSettings.getMyVideoImportFinished(), binding.notifVideoImportedApp, binding.notifVideoImportedMail);
|
||||
initializeValues(notificationSettings.getMyVideoPublished(), binding.notifVideoPublishedApp, binding.notifVideoPublishedMail);
|
||||
initializeValues(notificationSettings.getBlacklistOnMyVideo(), binding.notifBlockedApp, binding.notifBlockedMail);
|
||||
initializeValues(notificationSettings.getNewCommentOnMyVideo(), binding.notifNewCommentApp, binding.notifNewCommentMail);
|
||||
initializeValues(notificationSettings.getNewVideoFromSubscription(), binding.notifNewVideoApp, binding.notifNewVideoMail);
|
||||
|
||||
Helper.loadGiF(MyAccountActivity.this, MainActivity.userMe.getAccount().getAvatar()!=null?MainActivity.userMe.getAccount().getAvatar().getPath():null, binding.profilePicture);
|
||||
|
||||
String[] refresh_array = getResources().getStringArray(R.array.refresh_time);
|
||||
ArrayAdapter<String> refreshArray = new ArrayAdapter<>(MyAccountActivity.this,
|
||||
android.R.layout.simple_spinner_dropdown_item, refresh_array);
|
||||
binding.refreshTime.setAdapter(refreshArray);
|
||||
|
||||
SharedPreferences sharedpreferences = getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
int interval = sharedpreferences.getInt(Helper.NOTIFICATION_INTERVAL, 60);
|
||||
binding.refreshTime.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
int time;
|
||||
switch (position) {
|
||||
case 1:
|
||||
time = 15;
|
||||
break;
|
||||
case 2:
|
||||
time = 30;
|
||||
break;
|
||||
case 3:
|
||||
time = 60;
|
||||
break;
|
||||
case 4:
|
||||
time = 120;
|
||||
break;
|
||||
case 5:
|
||||
time = 360;
|
||||
break;
|
||||
case 6:
|
||||
time = 720;
|
||||
break;
|
||||
default:
|
||||
time = 0;
|
||||
}
|
||||
editor.putInt(Helper.NOTIFICATION_INTERVAL, time);
|
||||
editor.apply();
|
||||
WorkManager.getInstance(getApplicationContext()).cancelAllWorkByTag(NOTIFICATION_WORKER);
|
||||
if( time > 0 ) {
|
||||
WorkHelper.fetchNotifications(getApplication(), time);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
int position = 0;
|
||||
switch (interval) {
|
||||
case 0:
|
||||
position = 0;
|
||||
break;
|
||||
case 15:
|
||||
position = 1;
|
||||
break;
|
||||
case 30:
|
||||
position = 2;
|
||||
break;
|
||||
case 60:
|
||||
position = 3;
|
||||
break;
|
||||
case 120:
|
||||
position = 4;
|
||||
break;
|
||||
case 360:
|
||||
position = 5;
|
||||
break;
|
||||
case 720:
|
||||
position = 6;
|
||||
break;
|
||||
}
|
||||
binding.refreshTime.setSelection(position, false);
|
||||
|
||||
binding.selectFile.setOnClickListener(v->{
|
||||
if (ContextCompat.checkSelfPermission(MyAccountActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) !=
|
||||
PackageManager.PERMISSION_GRANTED) {
|
||||
|
@ -90,11 +186,24 @@ public class MyAccountActivity extends AppCompatActivity {
|
|||
startActivityForResult(intent, PICK_IMAGE);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
binding.save.setOnClickListener(v -> {
|
||||
binding.save.setEnabled(false);
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(@NotNull Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.main_my_account, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
} else if (item.getItemId() == R.id.action_validate) {
|
||||
item.setEnabled(false);
|
||||
new Thread(() -> {
|
||||
UserSettings userSettings = new UserSettings();
|
||||
userSettings.setNotificationSettings(notificationSettings);
|
||||
if( binding.displayname.getText() != null) {
|
||||
userSettings.setDisplayName(binding.displayname.getText().toString().trim());
|
||||
}
|
||||
|
@ -113,30 +222,22 @@ public class MyAccountActivity extends AppCompatActivity {
|
|||
if( avatarResponse != null && avatarResponse.getAvatar() != null ) {
|
||||
MainActivity.userMe.getAccount().setAvatar(avatarResponse.getAvatar());
|
||||
}
|
||||
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> {
|
||||
Toasty.info(MyAccountActivity.this, getString(R.string.account_updated), Toasty.LENGTH_LONG).show();
|
||||
binding.save.setEnabled(true);
|
||||
item.setEnabled(true);
|
||||
};
|
||||
mainHandler.post(myRunnable);
|
||||
} catch (Exception | Error e) {
|
||||
Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||
Runnable myRunnable = () -> {
|
||||
Toasty.error(MyAccountActivity.this, getString(R.string.toast_error), Toasty.LENGTH_LONG).show();
|
||||
binding.save.setEnabled(true);
|
||||
item.setEnabled(true);
|
||||
};
|
||||
mainHandler.post(myRunnable);
|
||||
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
@ -163,4 +264,96 @@ public class MyAccountActivity extends AppCompatActivity {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeValues(int value, SwitchCompat app, SwitchCompat email) {
|
||||
switch (value) {
|
||||
case 1:
|
||||
app.setChecked(true);
|
||||
email.setChecked(false);
|
||||
break;
|
||||
case 2:
|
||||
app.setChecked(false);
|
||||
email.setChecked(true);
|
||||
break;
|
||||
case 3:
|
||||
app.setChecked(true);
|
||||
email.setChecked(true);
|
||||
break;
|
||||
default:
|
||||
app.setChecked(false);
|
||||
email.setChecked(false);
|
||||
}
|
||||
app.setOnCheckedChangeListener((compoundButton, checked) -> {
|
||||
int id = app.getId();
|
||||
if (id == R.id.notif_new_video_app) {
|
||||
notificationSettings.setNewVideoFromSubscription(getNewAppCheckedValue(checked, email));
|
||||
} else if (id == R.id.notif_new_comment_app) {
|
||||
notificationSettings.setNewCommentOnMyVideo(getNewAppCheckedValue(checked, email));
|
||||
} else if (id == R.id.notif_blocked_app) {
|
||||
notificationSettings.setBlacklistOnMyVideo(getNewAppCheckedValue(checked, email));
|
||||
} else if (id == R.id.notif_video_published_app) {
|
||||
notificationSettings.setMyVideoPublished(getNewAppCheckedValue(checked, email));
|
||||
} else if (id == R.id.notif_video_imported_app) {
|
||||
notificationSettings.setMyVideoImportFinished(getNewAppCheckedValue(checked, email));
|
||||
} else if (id == R.id.notif_new_followers_app) {
|
||||
notificationSettings.setNewFollow(getNewAppCheckedValue(checked, email));
|
||||
} else if (id == R.id.notif_video_mention_app) {
|
||||
notificationSettings.setCommentMention(getNewAppCheckedValue(checked, email));
|
||||
} else if (id == R.id.notif_abuse_received_app) {
|
||||
notificationSettings.setAbuseNewMessage(getNewAppCheckedValue(checked, email));
|
||||
} else if (id == R.id.notif_abuse_accepted_app) {
|
||||
notificationSettings.setAbuseStateChange(getNewAppCheckedValue(checked, email));
|
||||
}
|
||||
});
|
||||
email.setOnCheckedChangeListener((compoundButtonMail, checkedMail) -> {
|
||||
int id = email.getId();
|
||||
if (id == R.id.notif_new_video_mail) {
|
||||
notificationSettings.setNewVideoFromSubscription(getNewMailCheckedValue(checkedMail, app));
|
||||
} else if (id == R.id.notif_new_comment_mail) {
|
||||
notificationSettings.setNewCommentOnMyVideo(getNewMailCheckedValue(checkedMail, app));
|
||||
} else if (id == R.id.notif_blocked_mail) {
|
||||
notificationSettings.setBlacklistOnMyVideo(getNewMailCheckedValue(checkedMail, app));
|
||||
} else if (id == R.id.notif_video_published_mail) {
|
||||
notificationSettings.setMyVideoPublished(getNewMailCheckedValue(checkedMail, app));
|
||||
} else if (id == R.id.notif_video_imported_mail) {
|
||||
notificationSettings.setMyVideoImportFinished(getNewMailCheckedValue(checkedMail, app));
|
||||
} else if (id == R.id.notif_new_followers_mail) {
|
||||
notificationSettings.setNewFollow(getNewMailCheckedValue(checkedMail, app));
|
||||
} else if (id == R.id.notif_video_mention_mail) {
|
||||
notificationSettings.setCommentMention(getNewMailCheckedValue(checkedMail, app));
|
||||
} else if (id == R.id.notif_abuse_received_mail) {
|
||||
notificationSettings.setAbuseNewMessage(getNewMailCheckedValue(checkedMail, app));
|
||||
} else if (id == R.id.notif_abuse_accepted_mail) {
|
||||
notificationSettings.setAbuseStateChange(getNewMailCheckedValue(checkedMail, app));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private int getNewAppCheckedValue(boolean checked, SwitchCompat email){
|
||||
int newValue;
|
||||
if( checked && email.isChecked()) {
|
||||
newValue = 3;
|
||||
}else if( !checked && email.isChecked()) {
|
||||
newValue = 2;
|
||||
} else if( checked && !email.isChecked()) {
|
||||
newValue = 1;
|
||||
}else {
|
||||
newValue = 0;
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
|
||||
private int getNewMailCheckedValue(boolean checked, SwitchCompat app){
|
||||
int newValue;
|
||||
if( checked && app.isChecked()) {
|
||||
newValue = 3;
|
||||
}else if( !checked && app.isChecked()) {
|
||||
newValue = 1;
|
||||
} else if( checked && !app.isChecked()) {
|
||||
newValue = 2;
|
||||
}else {
|
||||
newValue = 0;
|
||||
}
|
||||
return newValue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,17 +25,11 @@ import android.text.method.LinkMovementMethod;
|
|||
import android.util.Patterns;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.google.android.material.textfield.TextInputEditText;
|
||||
import com.google.android.material.textfield.TextInputLayout;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -43,6 +37,7 @@ import java.util.regex.Pattern;
|
|||
import app.fedilab.fedilabtube.client.APIResponse;
|
||||
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
|
||||
import app.fedilab.fedilabtube.client.entities.AccountCreation;
|
||||
import app.fedilab.fedilabtube.databinding.ActivityRegisterPeertubeBinding;
|
||||
import app.fedilab.fedilabtube.helper.Helper;
|
||||
import es.dmoral.toasty.Toasty;
|
||||
|
||||
|
@ -51,100 +46,89 @@ import static app.fedilab.fedilabtube.MainActivity.PICK_INSTANCE;
|
|||
public class PeertubeRegisterActivity extends AppCompatActivity {
|
||||
|
||||
|
||||
private Button signup;
|
||||
private TextView error_message;
|
||||
private String instance;
|
||||
private TextInputEditText login_instance;
|
||||
private ActivityRegisterPeertubeBinding binding;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_register_peertube);
|
||||
binding = ActivityRegisterPeertubeBinding.inflate(getLayoutInflater());
|
||||
View mainView = binding.getRoot();
|
||||
setContentView(mainView);
|
||||
|
||||
if (getSupportActionBar() != null)
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
signup = findViewById(R.id.signup);
|
||||
|
||||
TextInputLayout login_instance_container = findViewById(R.id.login_instance_container);
|
||||
LinearLayout title_login_instance = findViewById(R.id.title_login_instance);
|
||||
TextInputEditText username = findViewById(R.id.username);
|
||||
TextInputEditText email = findViewById(R.id.email);
|
||||
TextInputEditText password = findViewById(R.id.password);
|
||||
TextInputEditText password_confirm = findViewById(R.id.password_confirm);
|
||||
login_instance = findViewById(R.id.login_instance);
|
||||
CheckBox agreement = findViewById(R.id.agreement);
|
||||
error_message = findViewById(R.id.error_message);
|
||||
|
||||
if (BuildConfig.full_instances) {
|
||||
login_instance_container.setVisibility(View.VISIBLE);
|
||||
title_login_instance.setVisibility(View.VISIBLE);
|
||||
binding.loginInstanceContainer.setVisibility(View.VISIBLE);
|
||||
binding.titleLoginInstance.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
login_instance_container.setVisibility(View.GONE);
|
||||
title_login_instance.setVisibility(View.GONE);
|
||||
binding.loginInstanceContainer.setVisibility(View.GONE);
|
||||
binding.titleLoginInstance.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
username.setOnFocusChangeListener((view, focused) -> {
|
||||
if (!focused && username.getText() != null) {
|
||||
binding.username.setOnFocusChangeListener((view, focused) -> {
|
||||
if (!focused && binding.username.getText() != null) {
|
||||
Pattern patternUsername = Pattern.compile("^[a-z0-9._]{1,50}$");
|
||||
Matcher matcherMaxId = patternUsername.matcher(username.getText().toString());
|
||||
Matcher matcherMaxId = patternUsername.matcher(binding.username.getText().toString());
|
||||
if (!matcherMaxId.matches()) {
|
||||
username.setError(getString(R.string.username_error));
|
||||
binding.username.setError(getString(R.string.username_error));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Button instance_help = findViewById(R.id.instance_help);
|
||||
|
||||
instance_help.setOnClickListener(v -> {
|
||||
binding.instanceHelp.setOnClickListener(v -> {
|
||||
Intent intent = new Intent(PeertubeRegisterActivity.this, InstancePickerActivity.class);
|
||||
startActivityForResult(intent, PICK_INSTANCE);
|
||||
});
|
||||
|
||||
email.setOnFocusChangeListener((view, focused) -> {
|
||||
if (!focused && email.getText() != null) {
|
||||
binding.email.setOnFocusChangeListener((view, focused) -> {
|
||||
if (!focused && binding.email.getText() != null) {
|
||||
Pattern patternUsername = Patterns.EMAIL_ADDRESS;
|
||||
Matcher matcherMaxId = patternUsername.matcher(email.getText().toString());
|
||||
Matcher matcherMaxId = patternUsername.matcher(binding.email.getText().toString());
|
||||
if (!matcherMaxId.matches()) {
|
||||
email.setError(getString(R.string.email_error));
|
||||
binding.email.setError(getString(R.string.email_error));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
password.setOnFocusChangeListener((view, focused) -> {
|
||||
if (!focused && password.getText() != null) {
|
||||
if (password.getText().length() < 6) {
|
||||
password.setError(getString(R.string.password_length_error));
|
||||
binding.password.setOnFocusChangeListener((view, focused) -> {
|
||||
if (!focused && binding.password.getText() != null) {
|
||||
if (binding.password.getText().length() < 6) {
|
||||
binding.password.setError(getString(R.string.password_length_error));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
password_confirm.setOnFocusChangeListener((view, focused) -> {
|
||||
if (!focused && password_confirm.getText() != null && password.getText() != null) {
|
||||
if (password_confirm.getText().toString().compareTo(password.getText().toString()) != 0) {
|
||||
password_confirm.setError(getString(R.string.password));
|
||||
binding.passwordConfirm.setOnFocusChangeListener((view, focused) -> {
|
||||
if (!focused && binding.passwordConfirm.getText() != null && binding.password.getText() != null) {
|
||||
if (binding.passwordConfirm.getText().toString().compareTo(binding.password.getText().toString()) != 0) {
|
||||
binding.passwordConfirm.setError(getString(R.string.password));
|
||||
}
|
||||
}
|
||||
});
|
||||
setTextAgreement();
|
||||
signup.setOnClickListener(view -> {
|
||||
error_message.setVisibility(View.GONE);
|
||||
if (username.getText() == null || email.getText() == null || password.getText() == null || password_confirm.getText() == null || username.getText().toString().trim().length() == 0 || email.getText().toString().trim().length() == 0 ||
|
||||
password.getText().toString().trim().length() == 0 || password_confirm.getText().toString().trim().length() == 0 || !agreement.isChecked()) {
|
||||
binding.signup.setOnClickListener(view -> {
|
||||
binding.errorMessage.setVisibility(View.GONE);
|
||||
if ( binding.username.getText() == null || binding.email.getText() == null || binding.password.getText() == null || binding.passwordConfirm.getText() == null || binding.username.getText().toString().trim().length() == 0 || binding.email.getText().toString().trim().length() == 0 ||
|
||||
binding.password.getText().toString().trim().length() == 0 || binding.passwordConfirm.getText().toString().trim().length() == 0 || ! binding.agreement.isChecked()) {
|
||||
Toasty.error(PeertubeRegisterActivity.this, getString(R.string.all_field_filled)).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!password.getText().toString().trim().equals(password_confirm.getText().toString().trim())) {
|
||||
if (! binding.password.getText().toString().trim().equals( binding.passwordConfirm.getText().toString().trim())) {
|
||||
Toasty.error(PeertubeRegisterActivity.this, getString(R.string.password_error)).show();
|
||||
return;
|
||||
}
|
||||
if (!android.util.Patterns.EMAIL_ADDRESS.matcher(email.getText().toString().trim()).matches()) {
|
||||
if (!android.util.Patterns.EMAIL_ADDRESS.matcher( binding.email.getText().toString().trim()).matches()) {
|
||||
Toasty.error(PeertubeRegisterActivity.this, getString(R.string.email_error)).show();
|
||||
return;
|
||||
}
|
||||
String[] emailArray = email.getText().toString().split("@");
|
||||
String[] emailArray = binding.email.getText().toString().split("@");
|
||||
if (!BuildConfig.full_instances) {
|
||||
if (emailArray.length > 1 && !Arrays.asList(Helper.valideEmails).contains(emailArray[1])) {
|
||||
Toasty.error(PeertubeRegisterActivity.this, getString(R.string.email_error_domain, emailArray[1])).show();
|
||||
|
@ -152,23 +136,23 @@ public class PeertubeRegisterActivity extends AppCompatActivity {
|
|||
}
|
||||
}
|
||||
|
||||
if (password.getText().toString().trim().length() < 8) {
|
||||
if ( binding.password.getText().toString().trim().length() < 8) {
|
||||
Toasty.error(PeertubeRegisterActivity.this, getString(R.string.password_too_short)).show();
|
||||
return;
|
||||
}
|
||||
if (username.getText().toString().matches("[a-z0-9_]")) {
|
||||
if ( binding.username.getText().toString().matches("[a-z0-9_]")) {
|
||||
Toasty.error(PeertubeRegisterActivity.this, getString(R.string.username_error)).show();
|
||||
return;
|
||||
}
|
||||
signup.setEnabled(false);
|
||||
binding.signup.setEnabled(false);
|
||||
|
||||
if (BuildConfig.full_instances) {
|
||||
if (login_instance.getText() != null) {
|
||||
instance = login_instance.getText().toString();
|
||||
if ( binding.loginInstance.getText() != null) {
|
||||
instance = binding.loginInstance.getText().toString();
|
||||
} else {
|
||||
instance = "";
|
||||
}
|
||||
login_instance.setOnFocusChangeListener((view1, focus) -> {
|
||||
binding.loginInstance.setOnFocusChangeListener((view1, focus) -> {
|
||||
if (!focus) {
|
||||
setTextAgreement();
|
||||
}
|
||||
|
@ -182,10 +166,10 @@ public class PeertubeRegisterActivity extends AppCompatActivity {
|
|||
}
|
||||
|
||||
AccountCreation accountCreation = new AccountCreation();
|
||||
accountCreation.setEmail(email.getText().toString().trim());
|
||||
accountCreation.setPassword(password.getText().toString().trim());
|
||||
accountCreation.setPasswordConfirm(password_confirm.getText().toString().trim());
|
||||
accountCreation.setUsername(username.getText().toString().trim());
|
||||
accountCreation.setEmail( binding.email.getText().toString().trim());
|
||||
accountCreation.setPassword( binding.password.getText().toString().trim());
|
||||
accountCreation.setPasswordConfirm( binding.passwordConfirm.getText().toString().trim());
|
||||
accountCreation.setUsername( binding.username.getText().toString().trim());
|
||||
accountCreation.setInstance(instance);
|
||||
|
||||
new Thread(() -> {
|
||||
|
@ -210,9 +194,9 @@ public class PeertubeRegisterActivity extends AppCompatActivity {
|
|||
} else {
|
||||
errorMessage = getString(R.string.toast_error);
|
||||
}
|
||||
error_message.setText(errorMessage);
|
||||
error_message.setVisibility(View.VISIBLE);
|
||||
signup.setEnabled(true);
|
||||
binding.errorMessage.setText(errorMessage);
|
||||
binding.errorMessage.setVisibility(View.VISIBLE);
|
||||
binding.signup.setEnabled(true);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -260,8 +244,8 @@ public class PeertubeRegisterActivity extends AppCompatActivity {
|
|||
if (requestCode == PICK_INSTANCE && resultCode == Activity.RESULT_OK) {
|
||||
if (data != null && data.getData() != null) {
|
||||
String instance = String.valueOf(data.getData());
|
||||
login_instance.setText(instance);
|
||||
login_instance.setSelection(instance.length());
|
||||
binding.loginInstance.setText(instance);
|
||||
binding.loginInstance.setSelection(instance.length());
|
||||
setTextAgreement();
|
||||
}
|
||||
}
|
||||
|
@ -275,9 +259,9 @@ public class PeertubeRegisterActivity extends AppCompatActivity {
|
|||
agreement_text.setMovementMethod(null);
|
||||
agreement_text.setText(null);
|
||||
if (BuildConfig.full_instances) {
|
||||
if (login_instance.getText() != null) {
|
||||
if ( binding.loginInstance.getText() != null) {
|
||||
content_agreement = getString(R.string.agreement_check_peertube,
|
||||
"<a href='https://" + login_instance.getText().toString() + "/about/instance#terms-section' >" + tos + "</a>"
|
||||
"<a href='https://" + binding.loginInstance.getText().toString() + "/about/instance#terms-section' >" + tos + "</a>"
|
||||
);
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -29,6 +29,7 @@ import app.fedilab.fedilabtube.client.data.VideoData;
|
|||
import app.fedilab.fedilabtube.client.data.VideoPlaylistData;
|
||||
import app.fedilab.fedilabtube.client.entities.CaptionsParams;
|
||||
import app.fedilab.fedilabtube.client.entities.ChannelParams;
|
||||
import app.fedilab.fedilabtube.client.entities.NotificationSettings;
|
||||
import app.fedilab.fedilabtube.client.entities.Oauth;
|
||||
import app.fedilab.fedilabtube.client.entities.OverviewVideo;
|
||||
import app.fedilab.fedilabtube.client.entities.PlaylistExist;
|
||||
|
@ -192,6 +193,10 @@ public interface PeertubeService {
|
|||
@GET("users/me/notifications")
|
||||
Call<NotificationData> getNotifications(@Header("Authorization") String credentials, @Query("start") String maxId, @Query("count") String count, @Query("since_id") String sinceId);
|
||||
|
||||
//Update Notification settings
|
||||
@PUT("users/me/notification-settings")
|
||||
Call<String> updateNotifications(@Header("Authorization") String credentials, @Body NotificationSettings notificationSettings);
|
||||
|
||||
//Get/Post/Update/Delete video
|
||||
//Get a video
|
||||
@GET("videos/{id}")
|
||||
|
|
|
@ -54,6 +54,7 @@ import app.fedilab.fedilabtube.client.entities.AccountCreation;
|
|||
import app.fedilab.fedilabtube.client.entities.ChannelParams;
|
||||
import app.fedilab.fedilabtube.client.entities.Error;
|
||||
import app.fedilab.fedilabtube.client.entities.InstanceParams;
|
||||
import app.fedilab.fedilabtube.client.entities.NotificationSettings;
|
||||
import app.fedilab.fedilabtube.client.entities.Oauth;
|
||||
import app.fedilab.fedilabtube.client.entities.OauthParams;
|
||||
import app.fedilab.fedilabtube.client.entities.OverviewVideo;
|
||||
|
@ -237,6 +238,33 @@ public class RetrofitPeertubeAPI {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve notifications
|
||||
*
|
||||
* @return APIResponse
|
||||
*/
|
||||
public APIResponse getNotifications() {
|
||||
APIResponse apiResponse = new APIResponse();
|
||||
PeertubeService peertubeService = init();
|
||||
|
||||
Call<NotificationData> notificationsCall = peertubeService.getNotifications("Bearer " + token, "0", "40", null);
|
||||
try {
|
||||
Response<NotificationData> response = notificationsCall.execute();
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
apiResponse.setPeertubeNotifications(response.body().data);
|
||||
} else {
|
||||
setError(apiResponse, response.code(), response.errorBody());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Error error = new Error();
|
||||
error.setError(_context.getString(R.string.toast_error));
|
||||
apiResponse.setError(error);
|
||||
e.printStackTrace();
|
||||
}
|
||||
return apiResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve notifications
|
||||
*
|
||||
|
@ -458,6 +486,9 @@ public class RetrofitPeertubeAPI {
|
|||
APIResponse apiResponse = new APIResponse();
|
||||
UserMe.AvatarResponse avatarResponse = null;
|
||||
PeertubeService peertubeService = init();
|
||||
|
||||
peertubeService.updateNotifications(getToken(), userSettings.getNotificationSettings());
|
||||
|
||||
Call<String> updateUser = peertubeService.updateUser(getToken(),
|
||||
userSettings.isVideosHistoryEnabled(),
|
||||
userSettings.isAutoPlayVideo(),
|
||||
|
|
|
@ -30,6 +30,7 @@ public class UserSettings {
|
|||
private String displayName;
|
||||
private Uri avatarfile;
|
||||
private String fileName;
|
||||
private NotificationSettings notificationSettings;
|
||||
|
||||
public Boolean isVideosHistoryEnabled() {
|
||||
return videosHistoryEnabled;
|
||||
|
@ -122,5 +123,13 @@ public class UserSettings {
|
|||
this.fileName = fileName;
|
||||
}
|
||||
}
|
||||
|
||||
public NotificationSettings getNotificationSettings() {
|
||||
return notificationSettings;
|
||||
}
|
||||
|
||||
public void setNotificationSettings(NotificationSettings notificationSettings) {
|
||||
this.notificationSettings = notificationSettings;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,16 +42,28 @@ import app.fedilab.fedilabtube.viewmodel.NotificationsVM;
|
|||
import es.dmoral.toasty.Toasty;
|
||||
|
||||
|
||||
@SuppressWarnings({"unused", "RedundantSuppression"})
|
||||
public class DisplayNotificationsFragment extends Fragment {
|
||||
|
||||
//Peertube notification type
|
||||
public static int NEW_VIDEO_FROM_SUBSCRIPTION = 1;
|
||||
public static int UNBLACKLIST_ON_MY_VIDEO = 5;
|
||||
public static int BLACKLIST_ON_MY_VIDEO = 4;
|
||||
public static int MY_VIDEO_PUBLISHED = 6;
|
||||
public static int MY_VIDEO_IMPORT_SUCCESS = 7;
|
||||
public static int MY_VIDEO_IMPORT_ERROR = 8;
|
||||
public static int MY_VIDEO_REPPORT_SUCCESS = 15;
|
||||
public final static int NEW_VIDEO_FROM_SUBSCRIPTION = 1;
|
||||
public final static int NEW_COMMENT_ON_MY_VIDEO = 2;
|
||||
public final static int NEW_ABUSE_FOR_MODERATORS = 3;
|
||||
public final static int BLACKLIST_ON_MY_VIDEO = 4;
|
||||
public final static int UNBLACKLIST_ON_MY_VIDEO = 5;
|
||||
public final static int MY_VIDEO_PUBLISHED = 6;
|
||||
public final static int MY_VIDEO_IMPORT_SUCCESS = 7;
|
||||
public final static int MY_VIDEO_IMPORT_ERROR = 8;
|
||||
public final static int NEW_USER_REGISTRATION = 9;
|
||||
public final static int NEW_FOLLOW = 10;
|
||||
public final static int COMMENT_MENTION = 11;
|
||||
public final static int VIDEO_AUTO_BLACKLIST_FOR_MODERATORS = 12;
|
||||
public final static int NEW_INSTANCE_FOLLOWER = 13;
|
||||
public final static int AUTO_INSTANCE_FOLLOWING = 14;
|
||||
public final static int MY_VIDEO_REPPORT_SUCCESS = 15;
|
||||
public final static int ABUSE_NEW_MESSAGE = 16;
|
||||
|
||||
|
||||
private boolean flag_loading;
|
||||
private Context context;
|
||||
private PeertubeNotificationsListAdapter peertubeNotificationsListAdapter;
|
||||
|
|
|
@ -91,6 +91,8 @@ public class Helper {
|
|||
public static final int QUALITY_LOW = 2;
|
||||
public static final int ADD_USER_INTENT = 5;
|
||||
public static final String SET_SHARE_DETAILS = "set_share_details";
|
||||
public static final String NOTIFICATION_INTERVAL = "notification_interval";
|
||||
public static final String LAST_NOTIFICATION_READ = "last_notification_read";
|
||||
public static final int DEFAULT_VIDEO_CACHE_MB = 100;
|
||||
@SuppressWarnings({"unused", "RedundantSuppression"})
|
||||
public static final String TAG = "mastodon_etalab";
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
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.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.media.RingtoneManager;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
|
||||
import app.fedilab.fedilabtube.R;
|
||||
import app.fedilab.fedilabtube.client.data.AccountData;
|
||||
|
||||
import static app.fedilab.fedilabtube.worker.NotificationsWorker.FETCH_NOTIFICATION_CHANNEL_ID;
|
||||
|
||||
public class NotificationHelper {
|
||||
|
||||
|
||||
/**
|
||||
* Sends notification with intent
|
||||
*
|
||||
* @param context Context
|
||||
* @param intent Intent associated to the notifcation
|
||||
* @param icon Bitmap profile picture
|
||||
* @param title String title of the notification
|
||||
* @param message String message for the notification
|
||||
*/
|
||||
public static void notify_user(Context context, AccountData.Account account, Intent intent, Bitmap icon, String title, String message) {
|
||||
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
||||
int notificationId = (int) System.currentTimeMillis();
|
||||
PendingIntent pIntent = PendingIntent.getActivity(context, notificationId, intent, PendingIntent.FLAG_ONE_SHOT);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
|
||||
|
||||
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, FETCH_NOTIFICATION_CHANNEL_ID)
|
||||
.setSmallIcon(R.drawable.ic_notification_tubelab).setTicker(message)
|
||||
.setWhen(System.currentTimeMillis())
|
||||
.setAutoCancel(true);
|
||||
notificationBuilder.setGroup(account.getAcct())
|
||||
.setContentIntent(pIntent)
|
||||
.setContentText(message);
|
||||
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
NotificationChannel channel;
|
||||
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
channel = new NotificationChannel(FETCH_NOTIFICATION_CHANNEL_ID, context.getString(R.string.fetch_notification_channel_name), NotificationManager.IMPORTANCE_DEFAULT);
|
||||
mNotificationManager.createNotificationChannel(channel);
|
||||
}
|
||||
notificationBuilder.setContentTitle(title);
|
||||
notificationBuilder.setLargeIcon(icon);
|
||||
notificationManager.notify(notificationId, notificationBuilder.build());
|
||||
|
||||
Notification summaryNotification =
|
||||
new NotificationCompat.Builder(context, FETCH_NOTIFICATION_CHANNEL_ID)
|
||||
.setContentTitle(title)
|
||||
.setContentText(context.getApplicationContext().getString(R.string.fetch_notification_channel_name))
|
||||
.setContentIntent(pIntent)
|
||||
.setLargeIcon(icon)
|
||||
.setSmallIcon(R.drawable.ic_notification_tubelab)
|
||||
.setGroup(account.getAcct())
|
||||
.setGroupSummary(true)
|
||||
.build();
|
||||
notificationManager.notify(0, summaryNotification);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,322 @@
|
|||
package app.fedilab.fedilabtube.worker;
|
||||
/* 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.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.Html;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.work.ForegroundInfo;
|
||||
import androidx.work.Worker;
|
||||
import androidx.work.WorkerParameters;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.request.FutureTarget;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import app.fedilab.fedilabtube.MainActivity;
|
||||
import app.fedilab.fedilabtube.PeertubeActivity;
|
||||
import app.fedilab.fedilabtube.R;
|
||||
import app.fedilab.fedilabtube.ShowAccountActivity;
|
||||
import app.fedilab.fedilabtube.client.APIResponse;
|
||||
import app.fedilab.fedilabtube.client.RetrofitPeertubeAPI;
|
||||
import app.fedilab.fedilabtube.client.data.AccountData;
|
||||
import app.fedilab.fedilabtube.client.data.NotificationData;
|
||||
import app.fedilab.fedilabtube.client.entities.Actor;
|
||||
import app.fedilab.fedilabtube.client.entities.Error;
|
||||
import app.fedilab.fedilabtube.client.entities.NotificationSettings;
|
||||
import app.fedilab.fedilabtube.client.entities.UserMe;
|
||||
import app.fedilab.fedilabtube.fragment.DisplayNotificationsFragment;
|
||||
import app.fedilab.fedilabtube.helper.Helper;
|
||||
import app.fedilab.fedilabtube.helper.NotificationHelper;
|
||||
import app.fedilab.fedilabtube.sqlite.AccountDAO;
|
||||
import app.fedilab.fedilabtube.sqlite.Sqlite;
|
||||
|
||||
import static android.content.Context.NOTIFICATION_SERVICE;
|
||||
|
||||
public class NotificationsWorker extends Worker {
|
||||
|
||||
private final NotificationManager notificationManager;
|
||||
public static String FETCH_NOTIFICATION_CHANNEL_ID = "fetch_notification_peertube";
|
||||
public static int pendingNotificationID = 1;
|
||||
|
||||
public NotificationsWorker(
|
||||
@NonNull Context context,
|
||||
@NonNull WorkerParameters params) {
|
||||
super(context, params);
|
||||
notificationManager = (NotificationManager)
|
||||
context.getSystemService(NOTIFICATION_SERVICE);
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Result doWork() {
|
||||
Context applicationContext = getApplicationContext();
|
||||
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
List<AccountData.Account> accounts = new AccountDAO(applicationContext, db).getAllAccount();
|
||||
if( accounts == null || accounts.size() == 0) {
|
||||
return Result.success();
|
||||
}
|
||||
setForegroundAsync(createForegroundInfo());
|
||||
fetchNotification();
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings({"SwitchStatementWithoutDefaultBranch", "DuplicateBranchesInSwitch"})
|
||||
private void fetchNotification() {
|
||||
SQLiteDatabase db = Sqlite.getInstance(getApplicationContext(), Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open();
|
||||
List<AccountData.Account> accounts = new AccountDAO(getApplicationContext(), db).getAllAccount();
|
||||
SharedPreferences sharedpreferences = getApplicationContext().getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||
for(AccountData.Account account: accounts) {
|
||||
RetrofitPeertubeAPI retrofitPeertubeAPI = new RetrofitPeertubeAPI(getApplicationContext(), account.getHost(), account.getToken());
|
||||
APIResponse apiResponse = retrofitPeertubeAPI.getNotifications();
|
||||
try {
|
||||
UserMe userMe = retrofitPeertubeAPI.verifyCredentials();
|
||||
if( userMe != null) {
|
||||
List<NotificationData.Notification> notifications = apiResponse.getPeertubeNotifications();
|
||||
NotificationSettings notificationSettings = userMe.getNotificationSettings();
|
||||
if( apiResponse != null && apiResponse.getPeertubeNotifications() != null && apiResponse.getPeertubeNotifications().size() > 0 ) {
|
||||
String last_read = sharedpreferences.getString(Helper.LAST_NOTIFICATION_READ + account.getId() + account.getHost(), null);
|
||||
if( last_read != null) {
|
||||
for(NotificationData.Notification notification: notifications) {
|
||||
String title = "";
|
||||
String message = "";
|
||||
FutureTarget<Bitmap> futureBitmap = Glide.with(getApplicationContext())
|
||||
.asBitmap()
|
||||
.load("https://"+account.getHost()+account.getAvatar()).submit();
|
||||
Bitmap icon;
|
||||
try {
|
||||
icon = futureBitmap.get();
|
||||
} catch (Exception e) {
|
||||
icon = BitmapFactory.decodeResource(getApplicationContext().getResources(),
|
||||
R.drawable.missing_peertube);
|
||||
}
|
||||
|
||||
Intent intent = null;
|
||||
if( last_read == null || notification.getId().compareTo(last_read) > 0) {
|
||||
switch (notification.getType()) {
|
||||
case DisplayNotificationsFragment.NEW_VIDEO_FROM_SUBSCRIPTION:
|
||||
if(notificationSettings.getNewVideoFromSubscription() == 1 || notificationSettings.getNewVideoFromSubscription() == 3) {
|
||||
if( notification.getVideo().getChannel().getAvatar() != null ) {
|
||||
FutureTarget<Bitmap> futureBitmapChannel = Glide.with(getApplicationContext())
|
||||
.asBitmap()
|
||||
.load("https://"+account.getHost()+notification.getVideo().getChannel().getAvatar().getPath()).submit();
|
||||
try {
|
||||
icon = futureBitmapChannel.get();
|
||||
} catch (Exception e) {
|
||||
icon = BitmapFactory.decodeResource(getApplicationContext().getResources(),
|
||||
R.drawable.missing_peertube);
|
||||
}
|
||||
|
||||
}else{
|
||||
icon = BitmapFactory.decodeResource(getApplicationContext().getResources(),
|
||||
R.drawable.missing_peertube);
|
||||
}
|
||||
title = getApplicationContext().getString(R.string.new_video);
|
||||
message = getApplicationContext().getString(R.string.peertube_video_from_subscription, notification.getVideo().getChannel().getDisplayName(), notification.getVideo().getName());
|
||||
intent = new Intent(getApplicationContext(), PeertubeActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putParcelable("video", notification.getVideo());
|
||||
b.putString("peertube_instance", notification.getVideo().getChannel().getHost());
|
||||
b.putBoolean("isMyVideo", false);
|
||||
b.putString("video_id", notification.getVideo().getId());
|
||||
b.putString("video_uuid", notification.getVideo().getUuid());
|
||||
intent.putExtras(b);
|
||||
}
|
||||
break;
|
||||
case DisplayNotificationsFragment.NEW_COMMENT_ON_MY_VIDEO:
|
||||
if(notificationSettings.getNewCommentOnMyVideo() == 1 || notificationSettings.getNewCommentOnMyVideo() == 3) {
|
||||
if( notification.getComment().getAccount().getAvatar() != null ) {
|
||||
FutureTarget<Bitmap> futureBitmapChannel = Glide.with(getApplicationContext())
|
||||
.asBitmap()
|
||||
.load("https://"+account.getHost()+ notification.getComment().getAccount().getAvatar().getPath()).submit();
|
||||
try {
|
||||
icon = futureBitmapChannel.get();
|
||||
} catch (Exception e) {
|
||||
icon = BitmapFactory.decodeResource(getApplicationContext().getResources(),
|
||||
R.drawable.missing_peertube);
|
||||
}
|
||||
|
||||
}else{
|
||||
icon = BitmapFactory.decodeResource(getApplicationContext().getResources(),
|
||||
R.drawable.missing_peertube);
|
||||
}
|
||||
title = getApplicationContext().getString(R.string.new_comment);
|
||||
message = getApplicationContext().getString(R.string.peertube_comment_on_video, notification.getComment().getAccount().getDisplayName(), notification.getComment().getAccount().getUsername());
|
||||
intent = new Intent(getApplicationContext(), PeertubeActivity.class);
|
||||
Bundle b = new Bundle();
|
||||
b.putParcelable("video", notification.getVideo());
|
||||
b.putString("peertube_instance", notification.getVideo().getChannel().getHost());
|
||||
b.putBoolean("isMyVideo", false);
|
||||
b.putString("video_id", notification.getVideo().getId());
|
||||
b.putString("video_uuid", notification.getVideo().getUuid());
|
||||
intent.putExtras(b);
|
||||
}
|
||||
|
||||
break;
|
||||
case DisplayNotificationsFragment.NEW_ABUSE_FOR_MODERATORS:
|
||||
|
||||
break;
|
||||
case DisplayNotificationsFragment.BLACKLIST_ON_MY_VIDEO:
|
||||
if(notificationSettings.getBlacklistOnMyVideo() == 1 || notificationSettings.getBlacklistOnMyVideo() == 3) {
|
||||
title = getApplicationContext().getString(R.string.new_blacklist);
|
||||
message = getApplicationContext().getString(R.string.peertube_video_blacklist, notification.getVideo().getName());
|
||||
}
|
||||
break;
|
||||
case DisplayNotificationsFragment.UNBLACKLIST_ON_MY_VIDEO:
|
||||
if(notificationSettings.getBlacklistOnMyVideo() == 1 || notificationSettings.getBlacklistOnMyVideo() == 3) {
|
||||
title = getApplicationContext().getString(R.string.new_blacklist);
|
||||
message = getApplicationContext().getString(R.string.peertube_video_unblacklist, notification.getVideo().getName());
|
||||
}
|
||||
break;
|
||||
case DisplayNotificationsFragment.MY_VIDEO_PUBLISHED:
|
||||
if(notificationSettings.getMyVideoPublished() == 1 || notificationSettings.getMyVideoPublished() == 3) {
|
||||
title = getApplicationContext().getString(R.string.new_my_video_published);
|
||||
message = getApplicationContext().getString(R.string.peertube_video_published, notification.getVideo().getName());
|
||||
}
|
||||
break;
|
||||
case DisplayNotificationsFragment.MY_VIDEO_IMPORT_SUCCESS:
|
||||
if(notificationSettings.getMyVideoPublished() == 1 || notificationSettings.getMyVideoPublished() == 3) {
|
||||
message = getApplicationContext().getString(R.string.peertube_video_import_success, notification.getVideo().getName());
|
||||
title = getApplicationContext().getString(R.string.new_my_video_error);
|
||||
}
|
||||
break;
|
||||
case DisplayNotificationsFragment.MY_VIDEO_IMPORT_ERROR:
|
||||
if(notificationSettings.getMyVideoPublished() == 1 || notificationSettings.getMyVideoPublished() == 3) {
|
||||
message = getApplicationContext().getString(R.string.peertube_video_import_error, notification.getVideo().getName());
|
||||
title = getApplicationContext().getString(R.string.new_my_video_error);
|
||||
}
|
||||
break;
|
||||
case DisplayNotificationsFragment.NEW_USER_REGISTRATION:
|
||||
|
||||
break;
|
||||
case DisplayNotificationsFragment.NEW_FOLLOW:
|
||||
if(notificationSettings.getNewFollow() == 1 || notificationSettings.getNewFollow() == 3) {
|
||||
if( notification.getVideo().getChannel().getAvatar() != null ) {
|
||||
FutureTarget<Bitmap> futureBitmapChannel = Glide.with(getApplicationContext())
|
||||
.asBitmap()
|
||||
.load("https://"+account.getHost()+notification.getVideo().getChannel().getAvatar().getPath()).submit();
|
||||
icon = futureBitmapChannel.get();
|
||||
|
||||
}else{
|
||||
icon = BitmapFactory.decodeResource(getApplicationContext().getResources(),
|
||||
R.drawable.missing_peertube);
|
||||
}
|
||||
title = getApplicationContext().getString(R.string.new_video);
|
||||
String type = notification.getActorFollow().getFollowing().getType();
|
||||
if (type != null && type.compareTo("channel") == 0) {
|
||||
message = getApplicationContext().getString(R.string.peertube_follow_channel, notification.getActorFollow().getFollower().getDisplayName(), notification.getActorFollow().getFollowing().getDisplayName());
|
||||
} else {
|
||||
message = getApplicationContext().getString(R.string.peertube_follow_account, notification.getActorFollow().getFollower().getDisplayName());
|
||||
}
|
||||
Bundle b = new Bundle();
|
||||
Actor actor = notification.getActorFollow().getFollower();
|
||||
AccountData.Account accountAction = new AccountData.Account();
|
||||
accountAction.setAvatar(actor.getAvatar());
|
||||
accountAction.setDisplayName(actor.getDisplayName());
|
||||
accountAction.setHost(actor.getHost());
|
||||
accountAction.setUsername(actor.getName());
|
||||
intent = new Intent(getApplicationContext(), ShowAccountActivity.class);
|
||||
b.putParcelable("account", accountAction);
|
||||
b.putString("accountAcct", accountAction.getUsername() + "@" + accountAction.getHost());
|
||||
intent.putExtras(b);
|
||||
}
|
||||
break;
|
||||
case DisplayNotificationsFragment.COMMENT_MENTION:
|
||||
|
||||
break;
|
||||
case DisplayNotificationsFragment.VIDEO_AUTO_BLACKLIST_FOR_MODERATORS:
|
||||
|
||||
break;
|
||||
case DisplayNotificationsFragment.NEW_INSTANCE_FOLLOWER:
|
||||
|
||||
break;
|
||||
case DisplayNotificationsFragment.AUTO_INSTANCE_FOLLOWING:
|
||||
|
||||
break;
|
||||
case DisplayNotificationsFragment.MY_VIDEO_REPPORT_SUCCESS:
|
||||
|
||||
break;
|
||||
case DisplayNotificationsFragment.ABUSE_NEW_MESSAGE:
|
||||
|
||||
break;
|
||||
}
|
||||
if( message != null && icon != null && title != null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
|
||||
message = Html.fromHtml(message, Html.FROM_HTML_MODE_LEGACY).toString();
|
||||
else
|
||||
message = Html.fromHtml(message).toString();
|
||||
NotificationHelper.notify_user(getApplicationContext(), account, intent, icon, title, message);
|
||||
}
|
||||
}else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
editor.putString(Helper.LAST_NOTIFICATION_READ + account.getId() + account.getHost(), apiResponse.getPeertubeNotifications().get(0).getId());
|
||||
editor.apply();
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Error | InterruptedException | ExecutionException error) {
|
||||
error.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private ForegroundInfo createForegroundInfo() {
|
||||
|
||||
String title = getApplicationContext().getString(R.string.fetch_notification_channel_name);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
NotificationChannel channel = new NotificationChannel(FETCH_NOTIFICATION_CHANNEL_ID,
|
||||
getApplicationContext().getString(R.string.fetch_notification_channel_name),
|
||||
NotificationManager.IMPORTANCE_DEFAULT);
|
||||
notificationManager.createNotificationChannel(channel);
|
||||
}
|
||||
Intent myIntent = new Intent(getApplicationContext(), MainActivity.class);
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(
|
||||
getApplicationContext(),
|
||||
0,
|
||||
myIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext(), FETCH_NOTIFICATION_CHANNEL_ID)
|
||||
.setContentTitle(title)
|
||||
.setTicker(title)
|
||||
.setProgress(100, 0, false)
|
||||
.setOnlyAlertOnce(true)
|
||||
.setContentIntent(pendingIntent)
|
||||
.setSmallIcon(R.drawable.ic_notification_tubelab)
|
||||
.setOngoing(true);
|
||||
return new ForegroundInfo(pendingNotificationID, notificationBuilder.build());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package app.fedilab.fedilabtube.worker;
|
||||
/* 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.app.Application;
|
||||
import androidx.work.BackoffPolicy;
|
||||
import androidx.work.Constraints;
|
||||
import androidx.work.ExistingPeriodicWorkPolicy;
|
||||
import androidx.work.NetworkType;
|
||||
import androidx.work.PeriodicWorkRequest;
|
||||
import androidx.work.WorkManager;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class WorkHelper {
|
||||
|
||||
public static String NOTIFICATION_WORKER = "NOTIFICATION_WORKER";
|
||||
|
||||
public static void fetchNotifications(Application application, int interval) {
|
||||
|
||||
// Create Network constraint
|
||||
Constraints constraints = new Constraints.Builder()
|
||||
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||
.build();
|
||||
|
||||
WorkManager workManager = WorkManager.getInstance(application.getApplicationContext());
|
||||
PeriodicWorkRequest periodicSyncDataWork =
|
||||
new PeriodicWorkRequest.Builder(NotificationsWorker.class, interval, TimeUnit.MINUTES)
|
||||
.setConstraints(constraints)
|
||||
// setting a backoff on case the work needs to retry
|
||||
.setBackoffCriteria(BackoffPolicy.LINEAR, PeriodicWorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS)
|
||||
.build();
|
||||
workManager.enqueueUniquePeriodicWork(
|
||||
NOTIFICATION_WORKER,
|
||||
ExistingPeriodicWorkPolicy.KEEP, //Existing Periodic Work policy
|
||||
periodicSyncDataWork //work request
|
||||
);
|
||||
|
||||
}
|
||||
}
|
|
@ -59,56 +59,57 @@
|
|||
android:paddingStart="50dp"
|
||||
android:paddingEnd="50dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/instance_chosen"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="20dp"
|
||||
android:textColor="?colorAccent"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
|
||||
<ss.anoop.awesometextinputlayout.AwesomeTextInputLayout
|
||||
android:id="@+id/login_instance_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/instance_chosen">
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:borderColor="?attr/colorAccent"
|
||||
app:borderWidth="1dp"
|
||||
app:cornerRadius="8dp"
|
||||
android:padding="16dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
<EditText
|
||||
android:id="@+id/login_instance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/title_instance_login"
|
||||
android:paddingTop="2dp"
|
||||
android:inputType="textWebEmailAddress"
|
||||
android:singleLine="true" />
|
||||
android:singleLine="true"
|
||||
android:importantForAutofill="no" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</ss.anoop.awesometextinputlayout.AwesomeTextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
<ss.anoop.awesometextinputlayout.AwesomeTextInputLayout
|
||||
android:id="@+id/login_uid_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/login_instance_container">
|
||||
app:layout_constraintTop_toBottomOf="@id/login_instance_container"
|
||||
app:borderColor="?attr/colorAccent"
|
||||
app:borderWidth="1dp"
|
||||
app:cornerRadius="8dp"
|
||||
android:padding="16dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
<EditText
|
||||
android:id="@+id/login_uid"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/email_address"
|
||||
android:inputType="textEmailAddress"
|
||||
android:singleLine="true" />
|
||||
android:singleLine="true"
|
||||
android:importantForAutofill="no" />
|
||||
</ss.anoop.awesometextinputlayout.AwesomeTextInputLayout>
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
<ss.anoop.awesometextinputlayout.AwesomeTextInputLayout
|
||||
android:id="@+id/login_passwd_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -116,17 +117,20 @@
|
|||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/login_uid_container"
|
||||
app:passwordToggleEnabled="true">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
app:passwordToggleEnabled="true"
|
||||
app:borderColor="?attr/colorAccent"
|
||||
app:borderWidth="1dp"
|
||||
app:cornerRadius="8dp"
|
||||
android:padding="16dp">
|
||||
<EditText
|
||||
android:id="@+id/login_passwd"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/password"
|
||||
android:inputType="textPassword"
|
||||
android:singleLine="true" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
android:singleLine="true"
|
||||
android:importantForAutofill="no" />
|
||||
</ss.anoop.awesometextinputlayout.AwesomeTextInputLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/login_button"
|
||||
|
|
|
@ -62,20 +62,34 @@
|
|||
|
||||
|
||||
<LinearLayout
|
||||
android:visibility="gone"
|
||||
android:id="@+id/title_login_instance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="center_vertical"
|
||||
<ss.anoop.awesometextinputlayout.AwesomeTextInputLayout
|
||||
android:id="@+id/login_instance_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="wrap_content"
|
||||
app:borderColor="?attr/colorAccent"
|
||||
app:borderWidth="1dp"
|
||||
app:cornerRadius="8dp"
|
||||
android:padding="16dp"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
android:labelFor="@+id/login_instance"
|
||||
android:text="@string/title_instance_login" />
|
||||
<EditText
|
||||
android:id="@+id/login_instance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textWebEditText"
|
||||
android:hint="@string/title_instance_login"
|
||||
android:singleLine="true"
|
||||
android:importantForAutofill="no" />
|
||||
|
||||
</ss.anoop.awesometextinputlayout.AwesomeTextInputLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/instance_help"
|
||||
|
@ -88,64 +102,44 @@
|
|||
</LinearLayout>
|
||||
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/login_instance_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/login_instance"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textWebEditText"
|
||||
android:singleLine="true" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:labelFor="@+id/username"
|
||||
android:text="@string/username" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
<ss.anoop.awesometextinputlayout.AwesomeTextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:borderColor="?attr/colorAccent"
|
||||
app:borderWidth="1dp"
|
||||
app:cornerRadius="8dp"
|
||||
android:padding="16dp"
|
||||
app:errorEnabled="true">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
<EditText
|
||||
android:id="@+id/username"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLength="50" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
android:hint="@string/username"
|
||||
android:maxLength="50"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="text" />
|
||||
</ss.anoop.awesometextinputlayout.AwesomeTextInputLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:labelFor="@+id/email"
|
||||
android:text="@string/email" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
|
||||
|
||||
<ss.anoop.awesometextinputlayout.AwesomeTextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:borderColor="?attr/colorAccent"
|
||||
app:borderWidth="1dp"
|
||||
app:cornerRadius="8dp"
|
||||
android:padding="16dp"
|
||||
app:errorEnabled="true">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
<EditText
|
||||
android:id="@+id/email"
|
||||
android:hint="@string/email"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
android:layout_height="wrap_content"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="textEmailAddress" />
|
||||
</ss.anoop.awesometextinputlayout.AwesomeTextInputLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
|
@ -153,24 +147,24 @@
|
|||
android:text="@string/email_indicator"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:labelFor="@+id/password"
|
||||
android:text="@string/password" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
<ss.anoop.awesometextinputlayout.AwesomeTextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:borderColor="?attr/colorAccent"
|
||||
app:borderWidth="1dp"
|
||||
app:cornerRadius="8dp"
|
||||
android:padding="16dp"
|
||||
app:errorEnabled="true">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
<EditText
|
||||
android:id="@+id/password"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textPassword" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
android:inputType="textPassword"
|
||||
android:hint="@string/password"
|
||||
android:importantForAutofill="no" />
|
||||
</ss.anoop.awesometextinputlayout.AwesomeTextInputLayout>
|
||||
|
||||
|
||||
<TextView
|
||||
|
@ -179,25 +173,23 @@
|
|||
android:text="@string/password_indicator"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="150dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="10dp"
|
||||
android:labelFor="@+id/password_confirm"
|
||||
android:text="@string/password_confirm" />
|
||||
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
<ss.anoop.awesometextinputlayout.AwesomeTextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:borderColor="?attr/colorAccent"
|
||||
app:borderWidth="1dp"
|
||||
app:cornerRadius="8dp"
|
||||
android:padding="16dp"
|
||||
app:errorEnabled="true">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
<EditText
|
||||
android:id="@+id/password_confirm"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textPassword" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
android:inputType="textPassword"
|
||||
android:hint="@string/password_confirm"
|
||||
android:importantForAutofill="no" />
|
||||
</ss.anoop.awesometextinputlayout.AwesomeTextInputLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_validate"
|
||||
android:icon="@drawable/ic_check_white_24dp"
|
||||
android:title="@string/validate"
|
||||
app:showAsAction="always" />
|
||||
</menu>
|
Loading…
Reference in New Issue