diff --git a/app/build.gradle b/app/build.gradle
index 62394ec..059cde8 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -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"
+
}
\ No newline at end of file
diff --git a/app/src/acad/res/values/strings.xml b/app/src/acad/res/values/strings.xml
index 6455633..70d536d 100644
--- a/app/src/acad/res/values/strings.xml
+++ b/app/src/acad/res/values/strings.xml
@@ -11,11 +11,29 @@
set_theme_choice
set_fullscreen_choice
set_autoplay_next_video_choice
- set_store_in_history
+ set_store_in_history
Modifier la photo de profil
Le compte a été mis à jour !
+
+ Nouvelle vidéo
+ New blacklist info
+ Your video is published
+ Error when publishing your video
+ New comment
+ New follow
+
+ Nouvelle vidéo depuis vos souscriptions
+ Nouveau commentaire sur votre vidéo
+ Une de vos vidéos est bloquée/débloquée
+ Vidéo publiée (après transcodage / mise à jour programmée)
+ Import de vidéo terminé
+ Vous ou votre chaîne avez/a un·e nouvel·le abonné·e
+ Quelqu\'un vous a mentionné dans les commentaires d\'une vidéo
+ Un signalement d\'abus a reçu un nouveau message
+ Un de vos rapports d\'abus a été accepté ou rejeté par les modérateurs
+
Enregistrer
Lire automatiquement la vidéo suivante
Quand une vidéo est terminée, lire la prochaine vidéo suggérée.
@@ -35,6 +53,16 @@
- Automatique
+ Mettre à jour toutes les :
+
+ - Jamais
+ - 15 minutes
+ - 30 minutes
+ - 1 heure
+ - 2 heures
+ - 6 heures
+ - 12 heures
+
- %d réponse
@@ -206,7 +234,9 @@
Répondre publiquement
Envoyer un commentaire
Tout
-
+ Activité
+ App
+ Mise à jour des notifications
%1$s a été accepté]]>
Répondre
diff --git a/app/src/full/res/values/strings.xml b/app/src/full/res/values/strings.xml
index d1cfad0..aca83d5 100644
--- a/app/src/full/res/values/strings.xml
+++ b/app/src/full/res/values/strings.xml
@@ -7,7 +7,7 @@
set_video_quality_choice
set_video_cache_choice
set_autoplay_choice
- set_store_in_history
+ set_store_in_history
set_autoplay_next_video_choice
set_theme_choice
set_fullscreen_choice
@@ -24,6 +24,17 @@
When a video ends, follow up with the next suggested video.
Add a public reply
+ Activity
+ App
+ New video from your subscriptions
+ New comment on your video
+ One of your video is blocked/unblocked
+ Video published (after transcoding/scheduled update)
+ Video import finished
+ You or your channel(s) has a new follower
+ Someone mentioned you in video comments
+ An abuse report received a new message
+ One of your abuse reports has been accepted or rejected by moderators
- %d reply
@@ -59,10 +70,28 @@
Image preview
Select the file to upload
+ New video
+ New blacklist info
+ Your video is published
+ Error when publishing your video
+ New comment
+ New follow
+
Channel
Videos
Channels
+ Fetch every:
+
+ - Never
+ - 15 minutes
+ - 30 minutes
+ - 1 hour
+ - 2 hours
+ - 6 hours
+ - 12 hours
+
+
Yes
No
Cancel
@@ -352,6 +381,7 @@
Pick categories
Pick languages
Update information
+ Fetch notifications
Add an account
List of accounts
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 606b842..f63e144 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -150,6 +150,12 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/app/fedilab/fedilabtube/FedilabTube.java b/app/src/main/java/app/fedilab/fedilabtube/FedilabTube.java
index f5c3517..ff2be2c 100644
--- a/app/src/main/java/app/fedilab/fedilabtube/FedilabTube.java
+++ b/app/src/main/java/app/fedilab/fedilabtube/FedilabTube.java
@@ -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);
+
+
}
diff --git a/app/src/main/java/app/fedilab/fedilabtube/LoginActivity.java b/app/src/main/java/app/fedilab/fedilabtube/LoginActivity.java
index 7b63c97..d03c039 100644
--- a/app/src/main/java/app/fedilab/fedilabtube/LoginActivity.java
+++ b/app/src/main/java/app/fedilab/fedilabtube/LoginActivity.java
@@ -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);
}
});
}
diff --git a/app/src/main/java/app/fedilab/fedilabtube/MyAccountActivity.java b/app/src/main/java/app/fedilab/fedilabtube/MyAccountActivity.java
index a88fe8e..39f49f6 100644
--- a/app/src/main/java/app/fedilab/fedilabtube/MyAccountActivity.java
+++ b/app/src/main/java/app/fedilab/fedilabtube/MyAccountActivity.java
@@ -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 . */
+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 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;
+ }
}
diff --git a/app/src/main/java/app/fedilab/fedilabtube/PeertubeRegisterActivity.java b/app/src/main/java/app/fedilab/fedilabtube/PeertubeRegisterActivity.java
index bf7d0ce..a9e5af6 100644
--- a/app/src/main/java/app/fedilab/fedilabtube/PeertubeRegisterActivity.java
+++ b/app/src/main/java/app/fedilab/fedilabtube/PeertubeRegisterActivity.java
@@ -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,
- "" + tos + ""
+ "" + tos + ""
);
}
} else {
diff --git a/app/src/main/java/app/fedilab/fedilabtube/client/PeertubeService.java b/app/src/main/java/app/fedilab/fedilabtube/client/PeertubeService.java
index 54ecd91..46d1988 100644
--- a/app/src/main/java/app/fedilab/fedilabtube/client/PeertubeService.java
+++ b/app/src/main/java/app/fedilab/fedilabtube/client/PeertubeService.java
@@ -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 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 updateNotifications(@Header("Authorization") String credentials, @Body NotificationSettings notificationSettings);
+
//Get/Post/Update/Delete video
//Get a video
@GET("videos/{id}")
diff --git a/app/src/main/java/app/fedilab/fedilabtube/client/RetrofitPeertubeAPI.java b/app/src/main/java/app/fedilab/fedilabtube/client/RetrofitPeertubeAPI.java
index 426bd72..1b4d8dd 100644
--- a/app/src/main/java/app/fedilab/fedilabtube/client/RetrofitPeertubeAPI.java
+++ b/app/src/main/java/app/fedilab/fedilabtube/client/RetrofitPeertubeAPI.java
@@ -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 notificationsCall = peertubeService.getNotifications("Bearer " + token, "0", "40", null);
+ try {
+ Response 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 updateUser = peertubeService.updateUser(getToken(),
userSettings.isVideosHistoryEnabled(),
userSettings.isAutoPlayVideo(),
diff --git a/app/src/main/java/app/fedilab/fedilabtube/client/entities/UserSettings.java b/app/src/main/java/app/fedilab/fedilabtube/client/entities/UserSettings.java
index fdb5dce..1c78d87 100644
--- a/app/src/main/java/app/fedilab/fedilabtube/client/entities/UserSettings.java
+++ b/app/src/main/java/app/fedilab/fedilabtube/client/entities/UserSettings.java
@@ -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;
+ }
}
diff --git a/app/src/main/java/app/fedilab/fedilabtube/fragment/DisplayNotificationsFragment.java b/app/src/main/java/app/fedilab/fedilabtube/fragment/DisplayNotificationsFragment.java
index f9f3113..933f3d8 100644
--- a/app/src/main/java/app/fedilab/fedilabtube/fragment/DisplayNotificationsFragment.java
+++ b/app/src/main/java/app/fedilab/fedilabtube/fragment/DisplayNotificationsFragment.java
@@ -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;
diff --git a/app/src/main/java/app/fedilab/fedilabtube/helper/Helper.java b/app/src/main/java/app/fedilab/fedilabtube/helper/Helper.java
index 1ef96eb..7881838 100644
--- a/app/src/main/java/app/fedilab/fedilabtube/helper/Helper.java
+++ b/app/src/main/java/app/fedilab/fedilabtube/helper/Helper.java
@@ -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";
diff --git a/app/src/main/java/app/fedilab/fedilabtube/helper/NotificationHelper.java b/app/src/main/java/app/fedilab/fedilabtube/helper/NotificationHelper.java
new file mode 100644
index 0000000..4078f64
--- /dev/null
+++ b/app/src/main/java/app/fedilab/fedilabtube/helper/NotificationHelper.java
@@ -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 . */
+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);
+ }
+
+
+}
diff --git a/app/src/main/java/app/fedilab/fedilabtube/worker/NotificationsWorker.java b/app/src/main/java/app/fedilab/fedilabtube/worker/NotificationsWorker.java
new file mode 100644
index 0000000..cc6b711
--- /dev/null
+++ b/app/src/main/java/app/fedilab/fedilabtube/worker/NotificationsWorker.java
@@ -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 . */
+
+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 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 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 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 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 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 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 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());
+ }
+}
diff --git a/app/src/main/java/app/fedilab/fedilabtube/worker/WorkHelper.java b/app/src/main/java/app/fedilab/fedilabtube/worker/WorkHelper.java
new file mode 100644
index 0000000..1d5b2f9
--- /dev/null
+++ b/app/src/main/java/app/fedilab/fedilabtube/worker/WorkHelper.java
@@ -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 . */
+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
+ );
+
+ }
+}
diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml
index 1205045..3f884a6 100644
--- a/app/src/main/res/layout/activity_login.xml
+++ b/app/src/main/res/layout/activity_login.xml
@@ -59,56 +59,57 @@
android:paddingStart="50dp"
android:paddingEnd="50dp">
-
-
+ app:layout_constraintTop_toTopOf="parent"
+ app:borderColor="?attr/colorAccent"
+ app:borderWidth="1dp"
+ app:cornerRadius="8dp"
+ android:padding="16dp">
-
+ android:singleLine="true"
+ android:importantForAutofill="no" />
-
+
-
+ app:layout_constraintTop_toBottomOf="@id/login_instance_container"
+ app:borderColor="?attr/colorAccent"
+ app:borderWidth="1dp"
+ app:cornerRadius="8dp"
+ android:padding="16dp">
-
+ android:singleLine="true"
+ android:importantForAutofill="no" />
+
-
-
-
-
-
+
-
-
+ android:singleLine="true"
+ android:importantForAutofill="no" />
+