Improve notifications (#764)
Moving translation. Adding option to enable/disable notifications. Fix typos Improve notifications Co-authored-by: opyale <opyale@noreply.codeberg.org> Co-authored-by: M M Arif <mmarif@swatian.com> Reviewed-on: https://codeberg.org/gitnex/GitNex/pulls/764 Reviewed-by: opyale <opyale@noreply.codeberg.org>
This commit is contained in:
parent
87379ae0b2
commit
a92da6a6d4
@ -153,6 +153,9 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".activities.SettingsGeneralActivity"
|
android:name=".activities.SettingsGeneralActivity"
|
||||||
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||||
|
<activity
|
||||||
|
android:name=".activities.SettingsNotificationsActivity"
|
||||||
|
android:configChanges="orientation|screenSize|smallestScreenSize|density|screenLayout|uiMode|keyboard|keyboardHidden|navigation" />
|
||||||
|
|
||||||
<!-- Version < 3.0. DeX Mode and Screen Mirroring support -->
|
<!-- Version < 3.0. DeX Mode and Screen Mirroring support -->
|
||||||
<meta-data android:name="com.samsung.android.keepalive.density" android:value="true"/>
|
<meta-data android:name="com.samsung.android.keepalive.density" android:value="true"/>
|
||||||
|
@ -15,6 +15,7 @@ import org.acra.data.StringFormat;
|
|||||||
import org.mian.gitnex.R;
|
import org.mian.gitnex.R;
|
||||||
import org.mian.gitnex.helpers.AppUtil;
|
import org.mian.gitnex.helpers.AppUtil;
|
||||||
import org.mian.gitnex.helpers.FontsOverride;
|
import org.mian.gitnex.helpers.FontsOverride;
|
||||||
|
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||||
import org.mian.gitnex.helpers.TimeHelper;
|
import org.mian.gitnex.helpers.TimeHelper;
|
||||||
import org.mian.gitnex.helpers.TinyDB;
|
import org.mian.gitnex.helpers.TinyDB;
|
||||||
import org.mian.gitnex.notifications.NotificationsMaster;
|
import org.mian.gitnex.notifications.NotificationsMaster;
|
||||||
@ -115,9 +116,9 @@ public abstract class BaseActivity extends AppCompatActivity {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tinyDB.getInt("pollingDelayMinutes") == 0) {
|
if(tinyDB.getInt("pollingDelayMinutes", 0) <= 0) {
|
||||||
|
|
||||||
tinyDB.putInt("pollingDelayMinutes", 15);
|
tinyDB.putInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME Performance nightmare
|
// FIXME Performance nightmare
|
||||||
|
@ -0,0 +1,123 @@
|
|||||||
|
package org.mian.gitnex.activities;
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.NumberPicker;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import com.pes.androidmaterialcolorpickerdialog.ColorPicker;
|
||||||
|
import org.mian.gitnex.R;
|
||||||
|
import org.mian.gitnex.databinding.ActivitySettingsNotificationsBinding;
|
||||||
|
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||||
|
import org.mian.gitnex.helpers.Toasty;
|
||||||
|
import org.mian.gitnex.notifications.NotificationsMaster;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template Author M M Arif
|
||||||
|
* Author opyale
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SettingsNotificationsActivity extends BaseActivity {
|
||||||
|
|
||||||
|
private ActivitySettingsNotificationsBinding viewBinding;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getLayoutResourceId() {
|
||||||
|
|
||||||
|
return R.layout.activity_settings_notifications;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
viewBinding = ActivitySettingsNotificationsBinding.inflate(getLayoutInflater());
|
||||||
|
View view = viewBinding.getRoot();
|
||||||
|
setContentView(view);
|
||||||
|
|
||||||
|
View.OnClickListener onClickListener = viewClose -> finish();
|
||||||
|
|
||||||
|
viewBinding.close.setOnClickListener(onClickListener);
|
||||||
|
|
||||||
|
viewBinding.pollingDelaySelected.setText(String.format(getString(R.string.pollingDelaySelectedText), tinyDB.getInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay)));
|
||||||
|
viewBinding.chooseColorState.setCardBackgroundColor(tinyDB.getInt("notificationsLightColor", Color.GREEN));
|
||||||
|
|
||||||
|
viewBinding.enableNotificationsMode.setChecked(tinyDB.getBoolean("notificationsEnabled", true));
|
||||||
|
viewBinding.enableLightsMode.setChecked(tinyDB.getBoolean("notificationsEnableLights", true));
|
||||||
|
viewBinding.enableVibrationMode.setChecked(tinyDB.getBoolean("notificationsEnableVibration", true));
|
||||||
|
|
||||||
|
viewBinding.enableNotificationsMode.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
|
|
||||||
|
tinyDB.putBoolean("notificationsEnabled", isChecked);
|
||||||
|
if(!isChecked) NotificationsMaster.fireWorker(ctx);
|
||||||
|
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// polling delay
|
||||||
|
viewBinding.pollingDelayFrame.setOnClickListener(v -> {
|
||||||
|
|
||||||
|
NumberPicker numberPicker = new NumberPicker(ctx);
|
||||||
|
numberPicker.setMinValue(StaticGlobalVariables.minimumPollingDelay);
|
||||||
|
numberPicker.setMaxValue(StaticGlobalVariables.maximumPollingDelay);
|
||||||
|
numberPicker.setValue(tinyDB.getInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay));
|
||||||
|
numberPicker.setWrapSelectorWheel(true);
|
||||||
|
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
|
||||||
|
builder.setTitle(getString(R.string.pollingDelayDialogHeaderText));
|
||||||
|
builder.setMessage(getString(R.string.pollingDelayDialogDescriptionText));
|
||||||
|
|
||||||
|
builder.setCancelable(true);
|
||||||
|
builder.setPositiveButton(getString(R.string.okButton), (dialog, which) -> {
|
||||||
|
|
||||||
|
tinyDB.putInt("pollingDelayMinutes", numberPicker.getValue());
|
||||||
|
|
||||||
|
NotificationsMaster.fireWorker(ctx);
|
||||||
|
NotificationsMaster.hireWorker(ctx);
|
||||||
|
|
||||||
|
viewBinding.pollingDelaySelected.setText(String.format(getString(R.string.pollingDelaySelectedText), numberPicker.getValue()));
|
||||||
|
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.setNegativeButton(R.string.cancelButton, (dialog, which) -> dialog.dismiss());
|
||||||
|
builder.setView(numberPicker);
|
||||||
|
builder.create().show();
|
||||||
|
});
|
||||||
|
|
||||||
|
// lights switcher
|
||||||
|
viewBinding.enableLightsMode.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
|
|
||||||
|
tinyDB.putBoolean("notificationsEnableLights", isChecked);
|
||||||
|
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// lights color chooser
|
||||||
|
viewBinding.chooseColorFrame.setOnClickListener(v -> {
|
||||||
|
|
||||||
|
ColorPicker colorPicker = new ColorPicker(SettingsNotificationsActivity.this);
|
||||||
|
colorPicker.setColor(tinyDB.getInt("notificationsLightColor", Color.GREEN));
|
||||||
|
colorPicker.setCallback(color -> {
|
||||||
|
|
||||||
|
tinyDB.putInt("notificationsLightColor", color);
|
||||||
|
viewBinding.chooseColorState.setCardBackgroundColor(color);
|
||||||
|
colorPicker.dismiss();
|
||||||
|
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
|
||||||
|
});
|
||||||
|
|
||||||
|
colorPicker.show();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// vibration switcher
|
||||||
|
viewBinding.enableVibrationMode.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
|
|
||||||
|
tinyDB.putBoolean("notificationsEnableVibration", isChecked);
|
||||||
|
Toasty.info(appCtx, getResources().getString(R.string.settingsSave));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -7,15 +7,12 @@ import android.util.Log;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.NumberPicker;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.mian.gitnex.R;
|
import org.mian.gitnex.R;
|
||||||
import org.mian.gitnex.helpers.Toasty;
|
import org.mian.gitnex.helpers.Toasty;
|
||||||
import org.mian.gitnex.helpers.Version;
|
|
||||||
import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
|
import org.mian.gitnex.helpers.ssl.MemorizingTrustManager;
|
||||||
import org.mian.gitnex.notifications.NotificationsMaster;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@ -27,16 +24,12 @@ public class SettingsSecurityActivity extends BaseActivity {
|
|||||||
|
|
||||||
private View.OnClickListener onClickListener;
|
private View.OnClickListener onClickListener;
|
||||||
|
|
||||||
private static String[] cacheSizeDataList = {"50 MB", "100 MB", "250 MB", "500 MB", "1 GB"};
|
private static final String[] cacheSizeDataList = {"50 MB", "100 MB", "250 MB", "500 MB", "1 GB"};
|
||||||
private static int cacheSizeDataSelectedChoice = 0;
|
private static int cacheSizeDataSelectedChoice = 0;
|
||||||
|
|
||||||
private static String[] cacheSizeImagesList = {"50 MB", "100 MB", "250 MB", "500 MB", "1 GB"};
|
private static final String[] cacheSizeImagesList = {"50 MB", "100 MB", "250 MB", "500 MB", "1 GB"};
|
||||||
private static int cacheSizeImagesSelectedChoice = 0;
|
private static int cacheSizeImagesSelectedChoice = 0;
|
||||||
|
|
||||||
private static int MINIMUM_POLLING_DELAY = 1;
|
|
||||||
private static int DEFAULT_POLLING_DELAY = 20;
|
|
||||||
private static int MAXIMUM_POLLING_DELAY = 720;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getLayoutResourceId() {
|
protected int getLayoutResourceId() {
|
||||||
|
|
||||||
@ -48,8 +41,6 @@ public class SettingsSecurityActivity extends BaseActivity {
|
|||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
String currentVersion = tinyDB.getString("giteaVersion");
|
|
||||||
|
|
||||||
ImageView closeActivity = findViewById(R.id.close);
|
ImageView closeActivity = findViewById(R.id.close);
|
||||||
|
|
||||||
initCloseListener();
|
initCloseListener();
|
||||||
@ -58,10 +49,8 @@ public class SettingsSecurityActivity extends BaseActivity {
|
|||||||
TextView cacheSizeDataSelected = findViewById(R.id.cacheSizeDataSelected); // setter for data cache size
|
TextView cacheSizeDataSelected = findViewById(R.id.cacheSizeDataSelected); // setter for data cache size
|
||||||
TextView cacheSizeImagesSelected = findViewById(R.id.cacheSizeImagesSelected); // setter for images cache size
|
TextView cacheSizeImagesSelected = findViewById(R.id.cacheSizeImagesSelected); // setter for images cache size
|
||||||
TextView clearCacheSelected = findViewById(R.id.clearCacheSelected); // setter for clear cache
|
TextView clearCacheSelected = findViewById(R.id.clearCacheSelected); // setter for clear cache
|
||||||
TextView pollingDelaySelected = findViewById(R.id.pollingDelaySelected);
|
|
||||||
|
|
||||||
LinearLayout certsFrame = findViewById(R.id.certsFrame);
|
LinearLayout certsFrame = findViewById(R.id.certsFrame);
|
||||||
LinearLayout pollingDelayFrame = findViewById(R.id.pollingDelayFrame);
|
|
||||||
LinearLayout cacheSizeDataFrame = findViewById(R.id.cacheSizeDataSelectionFrame);
|
LinearLayout cacheSizeDataFrame = findViewById(R.id.cacheSizeDataSelectionFrame);
|
||||||
LinearLayout cacheSizeImagesFrame = findViewById(R.id.cacheSizeImagesSelectionFrame);
|
LinearLayout cacheSizeImagesFrame = findViewById(R.id.cacheSizeImagesSelectionFrame);
|
||||||
LinearLayout clearCacheFrame = findViewById(R.id.clearCacheSelectionFrame);
|
LinearLayout clearCacheFrame = findViewById(R.id.clearCacheSelectionFrame);
|
||||||
@ -86,13 +75,6 @@ public class SettingsSecurityActivity extends BaseActivity {
|
|||||||
cacheSizeImagesSelectedChoice = tinyDB.getInt("cacheSizeImagesId");
|
cacheSizeImagesSelectedChoice = tinyDB.getInt("cacheSizeImagesId");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(new Version(currentVersion).less("1.12.3")) {
|
|
||||||
|
|
||||||
pollingDelayFrame.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
pollingDelaySelected.setText(String.format(getString(R.string.pollingDelaySelectedText), tinyDB.getInt("pollingDelayMinutes", DEFAULT_POLLING_DELAY)));
|
|
||||||
|
|
||||||
// clear cache setter
|
// clear cache setter
|
||||||
File cacheDir = appCtx.getCacheDir();
|
File cacheDir = appCtx.getCacheDir();
|
||||||
clearCacheSelected.setText(FileUtils.byteCountToDisplaySize((int) FileUtils.sizeOfDirectory(cacheDir)));
|
clearCacheSelected.setText(FileUtils.byteCountToDisplaySize((int) FileUtils.sizeOfDirectory(cacheDir)));
|
||||||
@ -193,36 +175,6 @@ public class SettingsSecurityActivity extends BaseActivity {
|
|||||||
builder.setNeutralButton(R.string.cancelButton, (dialog, which) -> dialog.dismiss());
|
builder.setNeutralButton(R.string.cancelButton, (dialog, which) -> dialog.dismiss());
|
||||||
builder.create().show();
|
builder.create().show();
|
||||||
});
|
});
|
||||||
|
|
||||||
// polling delay
|
|
||||||
pollingDelayFrame.setOnClickListener(v -> {
|
|
||||||
|
|
||||||
NumberPicker numberPicker = new NumberPicker(ctx);
|
|
||||||
numberPicker.setMinValue(MINIMUM_POLLING_DELAY);
|
|
||||||
numberPicker.setMaxValue(MAXIMUM_POLLING_DELAY);
|
|
||||||
numberPicker.setValue(tinyDB.getInt("pollingDelayMinutes", DEFAULT_POLLING_DELAY));
|
|
||||||
numberPicker.setWrapSelectorWheel(true);
|
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(ctx);
|
|
||||||
builder.setTitle(getString(R.string.pollingDelayDialogHeaderText));
|
|
||||||
builder.setMessage(getString(R.string.pollingDelayDialogDescriptionText));
|
|
||||||
|
|
||||||
builder.setCancelable(true);
|
|
||||||
builder.setPositiveButton(getString(R.string.okButton), (dialog, which) -> {
|
|
||||||
|
|
||||||
tinyDB.putInt("pollingDelayMinutes", numberPicker.getValue());
|
|
||||||
|
|
||||||
NotificationsMaster.fireWorker(ctx);
|
|
||||||
NotificationsMaster.hireWorker(ctx);
|
|
||||||
|
|
||||||
pollingDelaySelected.setText(String.format(getString(R.string.pollingDelaySelectedText), numberPicker.getValue()));
|
|
||||||
Toasty.success(appCtx, getResources().getString(R.string.settingsSave));
|
|
||||||
});
|
|
||||||
|
|
||||||
builder.setNeutralButton(R.string.cancelButton, null);
|
|
||||||
builder.setView(numberPicker);
|
|
||||||
builder.create().show();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initCloseListener() {
|
private void initCloseListener() {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.mian.gitnex.fragments;
|
package org.mian.gitnex.fragments;
|
||||||
|
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -17,10 +18,12 @@ import org.mian.gitnex.activities.SettingsAppearanceActivity;
|
|||||||
import org.mian.gitnex.activities.SettingsDraftsActivity;
|
import org.mian.gitnex.activities.SettingsDraftsActivity;
|
||||||
import org.mian.gitnex.activities.SettingsFileViewerActivity;
|
import org.mian.gitnex.activities.SettingsFileViewerActivity;
|
||||||
import org.mian.gitnex.activities.SettingsGeneralActivity;
|
import org.mian.gitnex.activities.SettingsGeneralActivity;
|
||||||
|
import org.mian.gitnex.activities.SettingsNotificationsActivity;
|
||||||
import org.mian.gitnex.activities.SettingsReportsActivity;
|
import org.mian.gitnex.activities.SettingsReportsActivity;
|
||||||
import org.mian.gitnex.activities.SettingsSecurityActivity;
|
import org.mian.gitnex.activities.SettingsSecurityActivity;
|
||||||
import org.mian.gitnex.activities.SettingsTranslationActivity;
|
import org.mian.gitnex.activities.SettingsTranslationActivity;
|
||||||
import org.mian.gitnex.helpers.TinyDB;
|
import org.mian.gitnex.helpers.TinyDB;
|
||||||
|
import org.mian.gitnex.helpers.Version;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Author M M Arif
|
* Author M M Arif
|
||||||
@ -28,11 +31,16 @@ import org.mian.gitnex.helpers.TinyDB;
|
|||||||
|
|
||||||
public class SettingsFragment extends Fragment {
|
public class SettingsFragment extends Fragment {
|
||||||
|
|
||||||
|
private Context ctx;
|
||||||
|
private TinyDB tinyDB;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||||
|
|
||||||
View v = inflater.inflate(R.layout.fragment_settings, container, false);
|
View v = inflater.inflate(R.layout.fragment_settings, container, false);
|
||||||
|
ctx = getContext();
|
||||||
|
tinyDB = TinyDB.getInstance(ctx);
|
||||||
|
|
||||||
((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navSettings));
|
((MainActivity) requireActivity()).setActionBarTitle(getResources().getString(R.string.navSettings));
|
||||||
|
|
||||||
@ -41,39 +49,48 @@ public class SettingsFragment extends Fragment {
|
|||||||
LinearLayout fileViewerFrame = v.findViewById(R.id.fileViewerFrame);
|
LinearLayout fileViewerFrame = v.findViewById(R.id.fileViewerFrame);
|
||||||
LinearLayout draftsFrame = v.findViewById(R.id.draftsFrame);
|
LinearLayout draftsFrame = v.findViewById(R.id.draftsFrame);
|
||||||
LinearLayout securityFrame = v.findViewById(R.id.securityFrame);
|
LinearLayout securityFrame = v.findViewById(R.id.securityFrame);
|
||||||
|
LinearLayout notificationsFrame = v.findViewById(R.id.notificationsFrame);
|
||||||
LinearLayout languagesFrame = v.findViewById(R.id.languagesFrame);
|
LinearLayout languagesFrame = v.findViewById(R.id.languagesFrame);
|
||||||
LinearLayout reportsFrame = v.findViewById(R.id.reportsFrame);
|
LinearLayout reportsFrame = v.findViewById(R.id.reportsFrame);
|
||||||
LinearLayout rateAppFrame = v.findViewById(R.id.rateAppFrame);
|
LinearLayout rateAppFrame = v.findViewById(R.id.rateAppFrame);
|
||||||
LinearLayout aboutAppFrame = v.findViewById(R.id.aboutAppFrame);
|
LinearLayout aboutAppFrame = v.findViewById(R.id.aboutAppFrame);
|
||||||
|
|
||||||
generalFrame.setOnClickListener(generalFrameCall -> startActivity(new Intent(getContext(), SettingsGeneralActivity.class)));
|
if(new Version(tinyDB.getString("giteaVersion")).higherOrEqual("1.12.3")) {
|
||||||
|
|
||||||
appearanceFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsAppearanceActivity.class)));
|
notificationsFrame.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
fileViewerFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsFileViewerActivity.class)));
|
generalFrame.setOnClickListener(generalFrameCall -> startActivity(new Intent(ctx, SettingsGeneralActivity.class)));
|
||||||
|
|
||||||
draftsFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsDraftsActivity.class)));
|
appearanceFrame.setOnClickListener(v1 -> startActivity(new Intent(ctx, SettingsAppearanceActivity.class)));
|
||||||
|
|
||||||
securityFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsSecurityActivity.class)));
|
fileViewerFrame.setOnClickListener(v1 -> startActivity(new Intent(ctx, SettingsFileViewerActivity.class)));
|
||||||
|
|
||||||
languagesFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsTranslationActivity.class)));
|
draftsFrame.setOnClickListener(v1 -> startActivity(new Intent(ctx, SettingsDraftsActivity.class)));
|
||||||
|
|
||||||
reportsFrame.setOnClickListener(v1 -> startActivity(new Intent(getContext(), SettingsReportsActivity.class)));
|
securityFrame.setOnClickListener(v1 -> startActivity(new Intent(ctx, SettingsSecurityActivity.class)));
|
||||||
|
|
||||||
|
notificationsFrame.setOnClickListener(v1 -> startActivity(new Intent(ctx, SettingsNotificationsActivity.class)));
|
||||||
|
|
||||||
|
languagesFrame.setOnClickListener(v1 -> startActivity(new Intent(ctx, SettingsTranslationActivity.class)));
|
||||||
|
|
||||||
|
reportsFrame.setOnClickListener(v1 -> startActivity(new Intent(ctx, SettingsReportsActivity.class)));
|
||||||
|
|
||||||
rateAppFrame.setOnClickListener(aboutApp -> rateThisApp());
|
rateAppFrame.setOnClickListener(aboutApp -> rateThisApp());
|
||||||
|
|
||||||
aboutAppFrame.setOnClickListener(aboutApp -> requireActivity().getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AboutFragment()).commit());
|
aboutAppFrame.setOnClickListener(aboutApp -> requireActivity().getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new AboutFragment()).commit());
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rateThisApp() {
|
public void rateThisApp() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + requireActivity().getPackageName())));
|
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + requireActivity().getPackageName())));
|
||||||
}
|
}
|
||||||
catch(ActivityNotFoundException e) {
|
catch(ActivityNotFoundException e) {
|
||||||
|
|
||||||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + requireActivity().getPackageName())));
|
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + requireActivity().getPackageName())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,14 +100,12 @@ public class SettingsFragment extends Fragment {
|
|||||||
|
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
TinyDB tinyDb = TinyDB.getInstance(getContext());
|
if(tinyDB.getBoolean("refreshParent")) {
|
||||||
|
|
||||||
if(tinyDb.getBoolean("refreshParent")) {
|
|
||||||
requireActivity().recreate();
|
requireActivity().recreate();
|
||||||
requireActivity().overridePendingTransition(0, 0);
|
requireActivity().overridePendingTransition(0, 0);
|
||||||
tinyDb.putBoolean("refreshParent", false);
|
tinyDB.putBoolean("refreshParent", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -92,14 +92,10 @@ public class StarredRepositoriesFragment extends Fragment {
|
|||||||
|
|
||||||
createNewRepo = v.findViewById(R.id.addNewRepo);
|
createNewRepo = v.findViewById(R.id.addNewRepo);
|
||||||
|
|
||||||
createNewRepo.setOnClickListener(new View.OnClickListener() {
|
createNewRepo.setOnClickListener(view -> {
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(View view) {
|
|
||||||
Intent intent = new Intent(view.getContext(), CreateRepoActivity.class);
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Intent intent = new Intent(view.getContext(), CreateRepoActivity.class);
|
||||||
|
startActivity(intent);
|
||||||
});
|
});
|
||||||
|
|
||||||
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
|
||||||
@ -133,6 +129,7 @@ public class StarredRepositoriesFragment extends Fragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
|
|
||||||
super.onResume();
|
super.onResume();
|
||||||
TinyDB tinyDb = TinyDB.getInstance(getContext());
|
TinyDB tinyDb = TinyDB.getInstance(getContext());
|
||||||
final String loginUid = tinyDb.getString("loginUid");
|
final String loginUid = tinyDb.getString("loginUid");
|
||||||
|
@ -46,4 +46,8 @@ public abstract class StaticGlobalVariables {
|
|||||||
public static String draftTypeIssue = "Issue";
|
public static String draftTypeIssue = "Issue";
|
||||||
public static String draftTypePull = "Pull";
|
public static String draftTypePull = "Pull";
|
||||||
|
|
||||||
|
// polling - notifications
|
||||||
|
public static int minimumPollingDelay = 1;
|
||||||
|
public static int defaultPollingDelay = 15;
|
||||||
|
public static int maximumPollingDelay = 720;
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import androidx.work.ExistingPeriodicWorkPolicy;
|
|||||||
import androidx.work.NetworkType;
|
import androidx.work.NetworkType;
|
||||||
import androidx.work.PeriodicWorkRequest;
|
import androidx.work.PeriodicWorkRequest;
|
||||||
import androidx.work.WorkManager;
|
import androidx.work.WorkManager;
|
||||||
|
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||||
import org.mian.gitnex.helpers.TinyDB;
|
import org.mian.gitnex.helpers.TinyDB;
|
||||||
import org.mian.gitnex.helpers.Version;
|
import org.mian.gitnex.helpers.Version;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -38,30 +39,33 @@ public class NotificationsMaster {
|
|||||||
|
|
||||||
TinyDB tinyDB = TinyDB.getInstance(context);
|
TinyDB tinyDB = TinyDB.getInstance(context);
|
||||||
|
|
||||||
if(notificationsSupported == -1) {
|
if(tinyDB.getBoolean("notificationsEnabled", true)) {
|
||||||
checkVersion(tinyDB);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(notificationsSupported == 1) {
|
if(notificationsSupported == -1) checkVersion(tinyDB);
|
||||||
|
|
||||||
Constraints.Builder constraints = new Constraints.Builder()
|
if(notificationsSupported == 1) {
|
||||||
.setRequiredNetworkType(NetworkType.CONNECTED)
|
|
||||||
.setRequiresBatteryNotLow(false)
|
|
||||||
.setRequiresStorageNotLow(false)
|
|
||||||
.setRequiresCharging(false);
|
|
||||||
|
|
||||||
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
Constraints.Builder constraints = new Constraints.Builder()
|
||||||
|
.setRequiredNetworkType(NetworkType.CONNECTED)
|
||||||
|
.setRequiresBatteryNotLow(false)
|
||||||
|
.setRequiresStorageNotLow(false)
|
||||||
|
.setRequiresCharging(false);
|
||||||
|
|
||||||
|
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
|
|
||||||
|
constraints.setRequiresDeviceIdle(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
int pollingDelayMinutes = Math.max(tinyDB.getInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay), 15);
|
||||||
|
|
||||||
|
PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(NotificationsWorker.class, pollingDelayMinutes, TimeUnit.MINUTES)
|
||||||
|
.setConstraints(constraints.build())
|
||||||
|
.addTag(context.getPackageName())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
WorkManager.getInstance(context).enqueueUniquePeriodicWork(context.getPackageName(), ExistingPeriodicWorkPolicy.KEEP, periodicWorkRequest);
|
||||||
|
|
||||||
constraints.setRequiresDeviceIdle(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PeriodicWorkRequest periodicWorkRequest = new PeriodicWorkRequest.Builder(NotificationsWorker.class, tinyDB.getInt("pollingDelayMinutes"), TimeUnit.MINUTES)
|
|
||||||
.setConstraints(constraints.build())
|
|
||||||
.addTag(context.getPackageName())
|
|
||||||
.build();
|
|
||||||
|
|
||||||
WorkManager.getInstance(context).enqueueUniquePeriodicWork(context.getPackageName(), ExistingPeriodicWorkPolicy.KEEP, periodicWorkRequest);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package org.mian.gitnex.notifications;
|
package org.mian.gitnex.notifications;
|
||||||
|
|
||||||
|
import android.app.Notification;
|
||||||
import android.app.NotificationChannel;
|
import android.app.NotificationChannel;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
@ -11,12 +12,14 @@ import android.os.Build;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.app.NotificationCompat;
|
import androidx.core.app.NotificationCompat;
|
||||||
|
import androidx.core.app.NotificationManagerCompat;
|
||||||
import androidx.work.Worker;
|
import androidx.work.Worker;
|
||||||
import androidx.work.WorkerParameters;
|
import androidx.work.WorkerParameters;
|
||||||
import org.mian.gitnex.R;
|
import org.mian.gitnex.R;
|
||||||
import org.mian.gitnex.activities.MainActivity;
|
import org.mian.gitnex.activities.MainActivity;
|
||||||
import org.mian.gitnex.clients.RetrofitClient;
|
import org.mian.gitnex.clients.RetrofitClient;
|
||||||
import org.mian.gitnex.helpers.AppUtil;
|
import org.mian.gitnex.helpers.AppUtil;
|
||||||
|
import org.mian.gitnex.helpers.StaticGlobalVariables;
|
||||||
import org.mian.gitnex.helpers.TinyDB;
|
import org.mian.gitnex.helpers.TinyDB;
|
||||||
import org.mian.gitnex.models.NotificationThread;
|
import org.mian.gitnex.models.NotificationThread;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -42,7 +45,6 @@ public class NotificationsWorker extends Worker {
|
|||||||
|
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.tinyDB = TinyDB.getInstance(context);
|
this.tinyDB = TinyDB.getInstance(context);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@ -51,7 +53,7 @@ public class NotificationsWorker extends Worker {
|
|||||||
|
|
||||||
String token = "token " + tinyDB.getString(tinyDB.getString("loginUid") + "-token");
|
String token = "token " + tinyDB.getString(tinyDB.getString("loginUid") + "-token");
|
||||||
|
|
||||||
int notificationLoops = tinyDB.getInt("pollingDelayMinutes") >= 15 ? 1 : Math.min(15 - tinyDB.getInt("pollingDelayMinutes"), 10);
|
int notificationLoops = tinyDB.getInt("pollingDelayMinutes", StaticGlobalVariables.defaultPollingDelay) >= 15 ? 1 : Math.min(15 - tinyDB.getInt("pollingDelayMinutes"), 10);
|
||||||
|
|
||||||
for(int i=0; i<notificationLoops; i++) {
|
for(int i=0; i<notificationLoops; i++) {
|
||||||
|
|
||||||
@ -73,23 +75,20 @@ public class NotificationsWorker extends Worker {
|
|||||||
assert response.body() != null;
|
assert response.body() != null;
|
||||||
|
|
||||||
List<NotificationThread> notificationThreads = response.body();
|
List<NotificationThread> notificationThreads = response.body();
|
||||||
Log.i("ReceivedNotifications", String.valueOf(notificationThreads.size()));
|
|
||||||
|
|
||||||
if(!notificationThreads.isEmpty()) {
|
if(!notificationThreads.isEmpty()) {
|
||||||
|
|
||||||
for(NotificationThread notificationThread : notificationThreads) {
|
sendNotification(notificationThreads);
|
||||||
|
|
||||||
sendNotification(notificationThread);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tinyDB.putString("previousRefreshTimestamp", AppUtil.getTimestampFromDate(context, new Date()));
|
tinyDB.putString("previousRefreshTimestamp", AppUtil.getTimestampFromDate(context, new Date()));
|
||||||
|
}
|
||||||
} else {
|
else {
|
||||||
|
|
||||||
Log.e("onError", String.valueOf(response.code()));
|
Log.e("onError", String.valueOf(response.code()));
|
||||||
}
|
}
|
||||||
} catch(Exception e) {
|
}
|
||||||
|
catch(Exception e) {
|
||||||
|
|
||||||
Log.e("onError", e.toString());
|
Log.e("onError", e.toString());
|
||||||
}
|
}
|
||||||
@ -100,60 +99,125 @@ public class NotificationsWorker extends Worker {
|
|||||||
|
|
||||||
Thread.sleep(60000 - (System.currentTimeMillis() - startPollingTime));
|
Thread.sleep(60000 - (System.currentTimeMillis() - startPollingTime));
|
||||||
}
|
}
|
||||||
} catch (InterruptedException ignored) {}
|
}
|
||||||
|
catch (InterruptedException ignored) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.success();
|
return Result.success();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendNotification(NotificationThread notificationThread) {
|
private void sendNotification(List<NotificationThread> notificationThreads) {
|
||||||
|
|
||||||
|
int summaryId = 0;
|
||||||
|
PendingIntent pendingIntent = getPendingIntent();
|
||||||
|
|
||||||
|
NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(context);
|
||||||
|
attachNotificationChannel(notificationManagerCompat);
|
||||||
|
|
||||||
|
Notification summaryNotification = new NotificationCompat.Builder(context, context.getPackageName())
|
||||||
|
.setContentTitle(context.getString(R.string.newMessages))
|
||||||
|
.setContentText(String.format(context.getString(R.string.youHaveGotNewNotifications), notificationThreads.size()))
|
||||||
|
.setSmallIcon(R.drawable.gitnex_transparent)
|
||||||
|
.setGroup(context.getPackageName())
|
||||||
|
.setGroupSummary(true)
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.setContentIntent(pendingIntent)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
notificationManagerCompat.notify(summaryId, summaryNotification);
|
||||||
|
|
||||||
|
for(NotificationThread notificationThread : notificationThreads) {
|
||||||
|
|
||||||
|
NotificationManagerCompat notificationManagerCompat1 = NotificationManagerCompat.from(context);
|
||||||
|
attachNotificationChannel(notificationManagerCompat1);
|
||||||
|
|
||||||
|
String subjectUrl = notificationThread.getSubject().getUrl();
|
||||||
|
String issueId = context.getResources().getString(R.string.hash) + subjectUrl.substring(subjectUrl.lastIndexOf("/") + 1);
|
||||||
|
String notificationHeader = issueId + " " + notificationThread.getSubject().getTitle() + " " + String.format(context.getResources().getString(R.string.notificationExtraInfo), notificationThread.getRepository().getFull_name(), notificationThread.getSubject().getType());
|
||||||
|
|
||||||
|
NotificationCompat.Builder builder1 = getBaseNotificationBuilder()
|
||||||
|
.setContentTitle(notificationHeader)
|
||||||
|
.setGroup(context.getPackageName())
|
||||||
|
.setContentIntent(pendingIntent);
|
||||||
|
|
||||||
|
pushNotification(notificationManagerCompat1, builder1.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pushNotification(NotificationManagerCompat notificationManagerCompat, Notification notification) {
|
||||||
|
|
||||||
|
int previousNotificationId = tinyDB.getInt("previousNotificationId", 0);
|
||||||
|
int nextPreviousNotificationId = previousNotificationId > 71951418 ? 0 : previousNotificationId + 1;
|
||||||
|
|
||||||
|
tinyDB.putInt("previousNotificationId", nextPreviousNotificationId);
|
||||||
|
notificationManagerCompat.notify(previousNotificationId, notification);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void attachNotificationChannel(NotificationManagerCompat notificationManagerCompat) {
|
||||||
|
|
||||||
|
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
|
||||||
|
NotificationChannel notificationChannel = new NotificationChannel(context.getPackageName(), context.getString(R.string.app_name),
|
||||||
|
NotificationManager.IMPORTANCE_DEFAULT);
|
||||||
|
|
||||||
|
notificationChannel.setDescription(context.getString(R.string.notificationChannelDescription));
|
||||||
|
|
||||||
|
if(tinyDB.getBoolean("notificationsEnableVibration", true)) {
|
||||||
|
|
||||||
|
notificationChannel.setVibrationPattern(VIBRATION_PATTERN);
|
||||||
|
notificationChannel.enableVibration(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
notificationChannel.enableVibration(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tinyDB.getBoolean("notificationsEnableLights", true)) {
|
||||||
|
|
||||||
|
notificationChannel.setLightColor(tinyDB.getInt("notificationsLightColor", Color.GREEN));
|
||||||
|
notificationChannel.enableLights(true);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
notificationChannel.enableLights(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
notificationManagerCompat.createNotificationChannel(notificationChannel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private NotificationCompat.Builder getBaseNotificationBuilder() {
|
||||||
|
|
||||||
|
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, context.getPackageName())
|
||||||
|
.setSmallIcon(R.drawable.gitnex_transparent)
|
||||||
|
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
|
||||||
|
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
|
||||||
|
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
|
||||||
|
.setAutoCancel(true);
|
||||||
|
|
||||||
|
if(tinyDB.getBoolean("notificationsEnableLights", true)) {
|
||||||
|
|
||||||
|
builder.setLights(tinyDB.getInt("notificationsLightColor", Color.GREEN), 1500, 1500);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tinyDB.getBoolean("notificationsEnableVibration", true)) {
|
||||||
|
|
||||||
|
builder.setVibrate(VIBRATION_PATTERN);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
builder.setVibrate(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PendingIntent getPendingIntent() {
|
||||||
|
|
||||||
Intent intent = new Intent(context, MainActivity.class);
|
Intent intent = new Intent(context, MainActivity.class);
|
||||||
intent.putExtra("launchFragment", "notifications");
|
intent.putExtra("launchFragment", "notifications");
|
||||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
|
|
||||||
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
|
return PendingIntent.getActivity(context, 0, intent, 0);
|
||||||
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
||||||
|
|
||||||
if(notificationManager != null) {
|
|
||||||
|
|
||||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
||||||
|
|
||||||
NotificationChannel notificationChannel = new NotificationChannel(context.getPackageName(), context.getString(R.string.app_name),
|
|
||||||
NotificationManager.IMPORTANCE_HIGH);
|
|
||||||
|
|
||||||
notificationChannel.enableLights(true);
|
|
||||||
notificationChannel.setLightColor(Color.GREEN);
|
|
||||||
notificationChannel.enableVibration(true);
|
|
||||||
notificationChannel.setVibrationPattern(VIBRATION_PATTERN);
|
|
||||||
|
|
||||||
notificationManager.createNotificationChannel(notificationChannel);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
String subjectUrl = notificationThread.getSubject().getUrl();
|
|
||||||
String issueId = context.getResources().getString(R.string.hash) + subjectUrl.substring(subjectUrl.lastIndexOf("/") + 1);
|
|
||||||
|
|
||||||
String notificationHeader = issueId + " " + notificationThread.getSubject().getTitle();
|
|
||||||
String notificationBody = String.format(context.getResources().getString(R.string.notificationBody),
|
|
||||||
notificationThread.getSubject().getType());
|
|
||||||
|
|
||||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, context.getPackageName())
|
|
||||||
.setSmallIcon(R.drawable.gitnex_transparent).setContentTitle(notificationHeader)
|
|
||||||
.setContentText(notificationBody)
|
|
||||||
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
|
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
|
||||||
.setContentIntent(pendingIntent).setVibrate(VIBRATION_PATTERN).setAutoCancel(true);
|
|
||||||
|
|
||||||
int previousNotificationId = tinyDB.getInt("previousNotificationId", 0);
|
|
||||||
int newPreviousNotificationId = previousNotificationId > 71951418 ? 0 : previousNotificationId + 1;
|
|
||||||
|
|
||||||
tinyDB.putInt("previousNotificationId", newPreviousNotificationId);
|
|
||||||
|
|
||||||
notificationManager.notify(previousNotificationId, builder.build());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
203
app/src/main/res/layout/activity_settings_notifications.xml
Normal file
203
app/src/main/res/layout/activity_settings_notifications.xml
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/layoutSettingsNotifications"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="?attr/primaryBackgroundColor">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/appbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:theme="@style/Widget.AppCompat.SearchView">
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?attr/primaryBackgroundColor"
|
||||||
|
android:theme="@style/AppTheme.AppBarOverlay"
|
||||||
|
tools:ignore="UnusedAttribute">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/close"
|
||||||
|
android:layout_width="@dimen/close_button_size"
|
||||||
|
android:layout_height="@dimen/close_button_size"
|
||||||
|
android:layout_marginRight="15dp"
|
||||||
|
android:layout_marginLeft="15dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:contentDescription="@string/close"
|
||||||
|
android:src="@drawable/ic_close" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/toolbar_title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:text="@string/pageTitleNotifications"
|
||||||
|
android:textColor="?attr/primaryTextColor"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textSize="20sp" />
|
||||||
|
|
||||||
|
</androidx.appcompat.widget.Toolbar>
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/enableNotificationsFrame"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="25dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/enableNotificationsHeader"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="44dp"
|
||||||
|
android:layout_marginEnd="24dp"
|
||||||
|
android:text="@string/enableNotificationsHeaderText"
|
||||||
|
android:textColor="?attr/primaryTextColor"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
android:id="@+id/enableNotificationsMode"
|
||||||
|
android:layout_toEndOf="@+id/enableNotificationsHeader"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:switchMinWidth="56dp"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="25dp"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:gravity="end"
|
||||||
|
android:layout_gravity="end" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/pollingDelayFrame"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/pollingDelayHeaderSelector"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:layout_marginStart="44dp"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
|
android:text="@string/notificationsPollingHeaderText"
|
||||||
|
android:textColor="?attr/primaryTextColor" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/pollingDelaySelected"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:layout_marginStart="44dp"
|
||||||
|
android:layout_marginEnd="4dp"
|
||||||
|
android:text="@string/pollingDelaySelectedText"
|
||||||
|
android:textColor="?attr/selectedTextColor" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/enableLightsFrame"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="25dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/enableLightsHeader"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:layout_marginStart="44dp"
|
||||||
|
android:layout_marginEnd="24dp"
|
||||||
|
android:text="@string/enableLightsHeaderText"
|
||||||
|
android:textColor="?attr/primaryTextColor" />
|
||||||
|
|
||||||
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
android:id="@+id/enableLightsMode"
|
||||||
|
android:layout_toEndOf="@+id/enableLightsHeader"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:switchMinWidth="56dp"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="25dp"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:gravity="end"
|
||||||
|
android:layout_gravity="end" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/chooseColorFrame"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="25dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/chooseColorHeader"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:layout_marginStart="44dp"
|
||||||
|
android:layout_marginEnd="24dp"
|
||||||
|
android:text="@string/chooseColorSelectorHeader"
|
||||||
|
android:textColor="?attr/primaryTextColor" />
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:id="@+id/chooseColorState"
|
||||||
|
android:layout_alignEnd="@id/chooseColorHeader"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_marginEnd="30dp"
|
||||||
|
android:gravity="end"
|
||||||
|
app:cardCornerRadius="15dp"
|
||||||
|
app:cardElevation="0dp" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:id="@+id/enableVibrationFrame"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="25dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/enableVibrationHeader"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:layout_marginStart="44dp"
|
||||||
|
android:layout_marginEnd="24dp"
|
||||||
|
android:text="@string/enableVibrationHeaderText"
|
||||||
|
android:textColor="?attr/primaryTextColor" />
|
||||||
|
|
||||||
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
android:id="@+id/enableVibrationMode"
|
||||||
|
android:layout_toEndOf="@+id/enableVibrationHeader"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:switchMinWidth="56dp"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="25dp"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:gravity="end"
|
||||||
|
android:layout_gravity="end" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -153,34 +153,4 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/pollingDelayFrame"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="10dp"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/pollingDelayHeaderSelector"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="16sp"
|
|
||||||
android:layout_marginTop="10dp"
|
|
||||||
android:layout_marginStart="44dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:text="@string/notificationsPollingHeaderText"
|
|
||||||
android:textColor="?attr/primaryTextColor"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/pollingDelaySelected"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:textSize="14sp"
|
|
||||||
android:layout_marginStart="44dp"
|
|
||||||
android:layout_marginEnd="4dp"
|
|
||||||
android:text="@string/pollingDelaySelectedText"
|
|
||||||
android:textColor="?attr/selectedTextColor"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -177,6 +177,39 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/notificationsFrame"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="25dp"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/notificationsHeader"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:drawablePadding="24dp"
|
||||||
|
android:paddingStart="12dp"
|
||||||
|
android:paddingEnd="12dp"
|
||||||
|
android:text="@string/pageTitleNotifications"
|
||||||
|
android:textColor="?attr/primaryTextColor"
|
||||||
|
android:textSize="16sp"
|
||||||
|
app:drawableStartCompat="@drawable/ic_notifications" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/notificationsHintText"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:paddingStart="60dp"
|
||||||
|
android:paddingEnd="12dp"
|
||||||
|
android:text="@string/notificationsHintText"
|
||||||
|
android:textColor="?attr/primaryTextColor"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/languagesFrame"
|
android:id="@+id/languagesFrame"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -642,7 +642,7 @@
|
|||||||
|
|
||||||
<string name="appearanceHintText">Themes, fonts, badges</string>
|
<string name="appearanceHintText">Themes, fonts, badges</string>
|
||||||
<string name="fileViewerHintText">PDF mode, source code theme</string>
|
<string name="fileViewerHintText">PDF mode, source code theme</string>
|
||||||
<string name="securityHintText">SSL certificates, cache, polling delay</string>
|
<string name="securityHintText">SSL certificates, cache</string>
|
||||||
<string name="languagesHintText">Languages</string>
|
<string name="languagesHintText">Languages</string>
|
||||||
<string name="reportsHintText">Crash reports</string>
|
<string name="reportsHintText">Crash reports</string>
|
||||||
<string name="rateAppHintText">If you like GitNex you can give it a thumbs up</string>
|
<string name="rateAppHintText">If you like GitNex you can give it a thumbs up</string>
|
||||||
@ -662,18 +662,23 @@
|
|||||||
<!-- Notifications -->
|
<!-- Notifications -->
|
||||||
<string name="pageTitleNotifications">Notifications</string>
|
<string name="pageTitleNotifications">Notifications</string>
|
||||||
<string name="noDataNotifications">No notifications found</string>
|
<string name="noDataNotifications">No notifications found</string>
|
||||||
|
|
||||||
<string name="notificationBody">You have received a new notification. (%s)</string>
|
|
||||||
|
|
||||||
<string name="notificationsPollingHeaderText">Notifications Polling Delay</string>
|
<string name="notificationsPollingHeaderText">Notifications Polling Delay</string>
|
||||||
<string name="pollingDelaySelectedText">%d Minutes</string>
|
<string name="pollingDelaySelectedText">%d Minutes</string>
|
||||||
<string name="pollingDelayDialogHeaderText">Select Polling Delay</string>
|
<string name="pollingDelayDialogHeaderText">Select Polling Delay</string>
|
||||||
<string name="pollingDelayDialogDescriptionText">Choose a minutely delay in which GitNex tries to poll new notifications</string>
|
<string name="pollingDelayDialogDescriptionText">Choose a minutely delay in which GitNex tries to poll new notifications</string>
|
||||||
|
|
||||||
<string name="markAsRead">Mark as Read</string>
|
<string name="markAsRead">Mark as Read</string>
|
||||||
<string name="markAsUnread">Mark as Unread</string>
|
<string name="markAsUnread">Mark as Unread</string>
|
||||||
<string name="pinNotification">Pin Notification</string>
|
<string name="pinNotification">Pin Notification</string>
|
||||||
<string name="markedNotificationsAsRead">Successfully marked all notifications as read</string>
|
<string name="markedNotificationsAsRead">Successfully marked all notifications as read</string>
|
||||||
|
<string name="notificationsHintText">Polling delay, light, vibration</string>
|
||||||
|
<string name="enableNotificationsHeaderText">Enable Notifications</string>
|
||||||
|
<string name="enableLightsHeaderText">Enable Light</string>
|
||||||
|
<string name="enableVibrationHeaderText">Enable Vibration</string>
|
||||||
|
<string name="chooseColorSelectorHeader">Choose Color</string>
|
||||||
|
<string name="newMessages">New messages</string>
|
||||||
|
<string name="youHaveGotNewNotifications">You\'ve got %d new notifications.</string>
|
||||||
|
<string name="notificationChannelDescription" translatable="false">This is the main notification channel of GitNex.</string>
|
||||||
|
<string name="notificationExtraInfo" translatable="false">- %s (%s)</string>
|
||||||
|
|
||||||
<string name="isRead">Read</string>
|
<string name="isRead">Read</string>
|
||||||
<string name="isUnread">Unread</string>
|
<string name="isUnread">Unread</string>
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
package org.mian.gitnex.helpers;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Author opyale
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class PathsHelperTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testJoin() {
|
||||||
|
|
||||||
|
assertEquals(PathsHelper.join("test", "/test", "test/", "/test/"), "/test/test/test/test/");
|
||||||
|
assertEquals(PathsHelper.join("test", "test", "test", "test"), "/test/test/test/test/");
|
||||||
|
assertEquals(PathsHelper.join("/test", "/test", "/test", "/test"), "/test/test/test/test/");
|
||||||
|
assertEquals(PathsHelper.join("/test/", "/test/", "test/", "/test/"), "/test/test/test/test/");
|
||||||
|
assertEquals(PathsHelper.join("test", "test", "/test", "/test"), "/test/test/test/test/");
|
||||||
|
assertEquals(PathsHelper.join("test/", "test", "/test", "/test"), "/test/test/test/test/");
|
||||||
|
|
||||||
|
assertEquals(PathsHelper.join("test/test/test/test"), "/test/test/test/test/");
|
||||||
|
assertEquals(PathsHelper.join("/test/test/test/test"), "/test/test/test/test/");
|
||||||
|
assertEquals(PathsHelper.join("test/test/test/test/"), "/test/test/test/test/");
|
||||||
|
|
||||||
|
assertEquals(PathsHelper.join("test"), "/test/");
|
||||||
|
assertEquals(PathsHelper.join("test/"), "/test/");
|
||||||
|
assertEquals(PathsHelper.join("/test/"), "/test/");
|
||||||
|
assertEquals(PathsHelper.join("/test"), "/test/");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,13 +1,13 @@
|
|||||||
package org.mian.gitnex.helpers;
|
package org.mian.gitnex.helpers;
|
||||||
|
|
||||||
/**
|
|
||||||
* Author 6543
|
|
||||||
*/
|
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Author 6543
|
||||||
|
*/
|
||||||
|
|
||||||
public class VersionTest {
|
public class VersionTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
# The setting is particularly useful for tweaking memory settings.
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
org.gradle.jvmargs=-Xmx1536m
|
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||||
# When configured, Gradle will run in incubating parallel mode.
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
# This option should only be used with decoupled projects. More details, visit
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
|
Loading…
x
Reference in New Issue
Block a user