From 632be2acddc6cb3442a7b5614e57e90d5c34674a Mon Sep 17 00:00:00 2001 From: Damyan Ivanov Date: Sun, 31 Mar 2024 14:13:26 +0300 Subject: [PATCH 01/11] more pronounced day/month delimiters in the transaction list --- .../TransactionListDelimiterRowHolder.java | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListDelimiterRowHolder.java b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListDelimiterRowHolder.java index 390b4941..b5fe883d 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListDelimiterRowHolder.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionListDelimiterRowHolder.java @@ -1,5 +1,5 @@ /* - * Copyright © 2021 Damyan Ivanov. + * Copyright © 2024 Damyan Ivanov. * This file is part of MoLe. * MoLe is free software: you can distribute it and/or modify it * under the term of the GNU General Public License as published by @@ -19,9 +19,12 @@ package net.ktnx.mobileledger.ui.transaction_list; import android.view.View; +import androidx.constraintlayout.widget.ConstraintLayout; + import net.ktnx.mobileledger.App; import net.ktnx.mobileledger.databinding.TransactionDelimiterBinding; import net.ktnx.mobileledger.model.TransactionListItem; +import net.ktnx.mobileledger.utils.DimensionUtils; import net.ktnx.mobileledger.utils.Globals; import net.ktnx.mobileledger.utils.SimpleDate; @@ -46,15 +49,21 @@ class TransactionListDelimiterRowHolder extends TransactionRowHolderBase { b.transactionDelimiterMonth.setText( Globals.monthNames[cal.get(GregorianCalendar.MONTH)]); b.transactionDelimiterMonth.setVisibility(View.VISIBLE); - // holder.vDelimiterLine.setBackgroundResource(R.drawable - // .dashed_border_8dp); b.transactionDelimiterThick.setVisibility(View.VISIBLE); + ConstraintLayout.LayoutParams lp = + (ConstraintLayout.LayoutParams) b.transactionDelimiterThick.getLayoutParams(); + lp.height = DimensionUtils.dp2px(b.getRoot() + .getContext(), 4); + b.transactionDelimiterThick.setLayoutParams(lp); } else { b.transactionDelimiterMonth.setVisibility(View.GONE); - // holder.vDelimiterLine.setBackgroundResource(R.drawable - // .dashed_border_1dp); - b.transactionDelimiterThick.setVisibility(View.GONE); + ConstraintLayout.LayoutParams lp = + (ConstraintLayout.LayoutParams) b.transactionDelimiterThick.getLayoutParams(); + lp.height = DimensionUtils.dp2px(b.getRoot() + .getContext(), 1.3f); + b.transactionDelimiterThick.setLayoutParams(lp); + b.transactionDelimiterThick.setVisibility(View.VISIBLE); } } -- 2.39.2 From d2716a2305d7a6505f56aeb66f104c92f090ad21 Mon Sep 17 00:00:00 2001 From: Damyan Ivanov Date: Sun, 31 Mar 2024 18:06:47 +0300 Subject: [PATCH 02/11] store the 'Show zero-balance accounts' setting in the preferences --- app/src/main/java/net/ktnx/mobileledger/App.java | 13 ++++++++++++- .../ui/account_summary/AccountSummaryFragment.java | 4 ++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/net/ktnx/mobileledger/App.java b/app/src/main/java/net/ktnx/mobileledger/App.java index a9a416e7..b0c8e1f7 100644 --- a/app/src/main/java/net/ktnx/mobileledger/App.java +++ b/app/src/main/java/net/ktnx/mobileledger/App.java @@ -1,5 +1,5 @@ /* - * Copyright © 2021 Damyan Ivanov. + * Copyright © 2024 Damyan Ivanov. * This file is part of MoLe. * MoLe is free software: you can distribute it and/or modify it * under the term of the GNU General Public License as published by @@ -41,6 +41,7 @@ public class App extends Application { public static final String PREF_NAME = "MoLe"; public static final String PREF_THEME_HUE = "theme-hue"; public static final String PREF_PROFILE_ID = "profile-id"; + public static final String PREF_SHOW_ZERO_BALANCE_ACCOUNTS = "show-zero-balance-accounts"; public static App instance; private static ProfileDetailModel profileModel; private boolean monthNamesPrepared = false; @@ -68,6 +69,16 @@ public class App extends Application { SharedPreferences prefs = instance.getSharedPreferences(PREF_NAME, MODE_PRIVATE); return prefs.getInt(PREF_THEME_HUE, Colors.DEFAULT_HUE_DEG); } + public static boolean getShowZeroBalanceAccounts() { + SharedPreferences prefs = instance.getSharedPreferences(PREF_NAME, MODE_PRIVATE); + return prefs.getBoolean(PREF_SHOW_ZERO_BALANCE_ACCOUNTS, true); + } + public static void storeShowZeroBalanceAccounts(boolean value) { + SharedPreferences prefs = instance.getSharedPreferences(PREF_NAME, MODE_PRIVATE); + SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean(PREF_SHOW_ZERO_BALANCE_ACCOUNTS, value); + editor.apply(); + } private String getAuthURL() { if (profileModel != null) return profileModel.getUrl(); diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/account_summary/AccountSummaryFragment.java b/app/src/main/java/net/ktnx/mobileledger/ui/account_summary/AccountSummaryFragment.java index 807c16da..924f7afe 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/account_summary/AccountSummaryFragment.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/account_summary/AccountSummaryFragment.java @@ -36,6 +36,7 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import net.ktnx.mobileledger.App; import net.ktnx.mobileledger.R; import net.ktnx.mobileledger.async.GeneralBackgroundTasks; import net.ktnx.mobileledger.databinding.AccountSummaryFragmentBinding; @@ -118,6 +119,8 @@ public class AccountSummaryFragment extends MobileLedgerListFragment { Data.observeProfile(this, profile -> onProfileChanged(profile, Boolean.TRUE.equals( model.getShowZeroBalanceAccounts() .getValue()))); + model.getShowZeroBalanceAccounts() + .setValue(App.getShowZeroBalanceAccounts()); } @Override public void onCreateOptionsMenu(@NotNull Menu menu, @NotNull MenuInflater inflater) { @@ -138,6 +141,7 @@ public class AccountSummaryFragment extends MobileLedgerListFragment { .observe(this, v -> { menuShowZeroBalances.setChecked(v); onProfileChanged(Data.getProfile(), v); + App.storeShowZeroBalanceAccounts(v); }); super.onCreateOptionsMenu(menu, inflater); -- 2.39.2 From 39bedf0e728ce9c9682d3682330cb3455a4a00db Mon Sep 17 00:00:00 2001 From: Damyan Ivanov Date: Sun, 31 Mar 2024 18:07:28 +0300 Subject: [PATCH 03/11] drop a check that is always true --- .../ui/account_summary/AccountSummaryFragment.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/account_summary/AccountSummaryFragment.java b/app/src/main/java/net/ktnx/mobileledger/ui/account_summary/AccountSummaryFragment.java index 924f7afe..02d685ce 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/account_summary/AccountSummaryFragment.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/account_summary/AccountSummaryFragment.java @@ -107,8 +107,7 @@ public class AccountSummaryFragment extends MobileLedgerListFragment { mainActivity.fabShouldShow(); - if (mainActivity instanceof FabManager.FabHandler) - FabManager.handle(mainActivity, b.accountRoot); + FabManager.handle(mainActivity, b.accountRoot); Colors.themeWatch.observe(getViewLifecycleOwner(), this::themeChanged); b.accountSwipeRefreshLayout.setOnRefreshListener(() -> { -- 2.39.2 From ba939f9d8124a6dd6e7fbca3a8c1171c35e0af43 Mon Sep 17 00:00:00 2001 From: Damyan Ivanov Date: Sun, 9 Jun 2024 18:42:16 +0000 Subject: [PATCH 04/11] drop unused subcalsses of Observable/Observer now deprecated --- .../TransactionRowHolder.java | 3 - .../utils/ObservableAtomicInteger.java | 145 -------- .../mobileledger/utils/ObservableList.java | 325 ------------------ .../mobileledger/utils/ObservableValue.java | 83 ----- 4 files changed, 556 deletions(-) delete mode 100644 app/src/main/java/net/ktnx/mobileledger/utils/ObservableAtomicInteger.java delete mode 100644 app/src/main/java/net/ktnx/mobileledger/utils/ObservableList.java delete mode 100644 app/src/main/java/net/ktnx/mobileledger/utils/ObservableValue.java diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionRowHolder.java b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionRowHolder.java index 876430f5..e5161150 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionRowHolder.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/transaction_list/TransactionRowHolder.java @@ -40,12 +40,9 @@ import net.ktnx.mobileledger.model.TransactionListItem; import net.ktnx.mobileledger.utils.Colors; import net.ktnx.mobileledger.utils.Misc; -import java.util.Observer; - class TransactionRowHolder extends TransactionRowHolderBase { private final TransactionListRowBinding b; TransactionListItem.Type lastType; - private Observer lastUpdateObserver; public TransactionRowHolder(@NonNull TransactionListRowBinding binding) { super(binding.getRoot()); b = binding; diff --git a/app/src/main/java/net/ktnx/mobileledger/utils/ObservableAtomicInteger.java b/app/src/main/java/net/ktnx/mobileledger/utils/ObservableAtomicInteger.java deleted file mode 100644 index f804464c..00000000 --- a/app/src/main/java/net/ktnx/mobileledger/utils/ObservableAtomicInteger.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright © 2020 Damyan Ivanov. - * This file is part of MoLe. - * MoLe is free software: you can distribute it and/or modify it - * under the term of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your opinion), any later version. - * - * MoLe 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 terms for details. - * - * You should have received a copy of the GNU General Public License - * along with MoLe. If not, see . - */ - -package net.ktnx.mobileledger.utils; - -import android.os.Build; - -import androidx.annotation.RequiresApi; - -import java.util.Observable; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.IntBinaryOperator; -import java.util.function.IntUnaryOperator; - -public class ObservableAtomicInteger extends Observable { - private final AtomicInteger holder; - ObservableAtomicInteger() { - super(); - holder = new AtomicInteger(); - } - public ObservableAtomicInteger(int initialValue) { - this(); - holder.set(initialValue); - } - public int get() { - return holder.get(); - } - public void set(int newValue) { -// debug("atomic", "set"); - holder.set(newValue); - forceNotify(); - } - private void forceNotify() { - setChanged(); -// debug("atomic", String.format("notifying %d observers", countObservers())); - notifyObservers(); - } -// public void lazySet(int newValue) { -// holder.lazySet(newValue); -// forceNotify(); -// } - public int getAndSet(int newValue) { - int result = holder.getAndSet(newValue); - forceNotify(); - return result; - } - public boolean compareAndSet(int expect, int update) { - boolean result = holder.compareAndSet(expect, update); - if (result) forceNotify(); - return result; - } -// public boolean weakCompareAndSet(int expect, int update) { -// boolean result = holder.weakCompareAndSet(expect, update); -// if (result) forceNotify(); -// return result; -// } - public int getAndIncrement() { - int result = holder.getAndIncrement(); - forceNotify(); - return result; - } - public int getAndDecrement() { - int result = holder.getAndDecrement(); - forceNotify(); - return result; - } - public int getAndAdd(int delta) { - int result = holder.getAndAdd(delta); - forceNotify(); - return result; - } - public int incrementAndGet() { -// debug("atomic", "incrementAndGet"); - int result = holder.incrementAndGet(); - forceNotify(); - return result; - } - public int decrementAndGet() { -// debug("atomic", "decrementAndGet"); - int result = holder.decrementAndGet(); - forceNotify(); - return result; - } - public int addAndGet(int delta) { - int result = holder.addAndGet(delta); - forceNotify(); - return result; - } - @RequiresApi(Build.VERSION_CODES.N) - public int getAndUpdate(IntUnaryOperator updateFunction) { - int result = holder.getAndUpdate(updateFunction); - forceNotify(); - return result; - } - @RequiresApi(api = Build.VERSION_CODES.N) - public int updateAndGet(IntUnaryOperator updateFunction) { - int result = holder.updateAndGet(updateFunction); - forceNotify(); - return result; - } - @RequiresApi(api = Build.VERSION_CODES.N) - public int getAndAccumulate(int x, IntBinaryOperator accumulatorFunction) { - int result = holder.getAndAccumulate(x, accumulatorFunction); - forceNotify(); - return result; - } - @RequiresApi(api = Build.VERSION_CODES.N) - public int accumulateAndGet(int x, IntBinaryOperator accumulatorFunction) { - int result = holder.accumulateAndGet(x, accumulatorFunction); - forceNotify(); - return result; - } - public int intValue() { - return holder.intValue(); - } - public long longValue() { - return holder.longValue(); - } - public float floatValue() { - return holder.floatValue(); - } - public double doubleValue() { - return holder.doubleValue(); - } - public byte byteValue() { - return holder.byteValue(); - } - public short shortValue() { - return holder.shortValue(); - } -} diff --git a/app/src/main/java/net/ktnx/mobileledger/utils/ObservableList.java b/app/src/main/java/net/ktnx/mobileledger/utils/ObservableList.java deleted file mode 100644 index 4ca3e695..00000000 --- a/app/src/main/java/net/ktnx/mobileledger/utils/ObservableList.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright © 2020 Damyan Ivanov. - * This file is part of MoLe. - * MoLe is free software: you can distribute it and/or modify it - * under the term of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your opinion), any later version. - * - * MoLe 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 terms for details. - * - * You should have received a copy of the GNU General Public License - * along with MoLe. If not, see . - */ - -package net.ktnx.mobileledger.utils; - -import android.os.Build; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; - -import org.jetbrains.annotations.NotNull; - -import java.util.Collection; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Observable; -import java.util.Spliterator; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.function.Consumer; -import java.util.function.Predicate; -import java.util.function.UnaryOperator; -import java.util.stream.Stream; - -import static net.ktnx.mobileledger.utils.Logger.debug; - -public class ObservableList extends Observable implements List { - private List list; - private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); - private int notificationBlocks = 0; - private boolean notificationWasBlocked = false; - public ObservableList(List list) { - this.list = list; - } - private void forceNotify() { - if (notificationBlocked()) return; - setChanged(); - notifyObservers(); - } - private boolean notificationBlocked() { - return notificationWasBlocked = (notificationBlocks > 0); - } - private void forceNotify(int index) { - if (notificationBlocked()) return; - setChanged(); - notifyObservers(index); - } - public int size() { - try (LockHolder lh = lockForReading()) { - return list.size(); - } - } - public boolean isEmpty() { - try (LockHolder lh = lockForReading()) { - return list.isEmpty(); - } - } - public boolean contains(@Nullable Object o) { - try (LockHolder lh = lockForReading()) { - return list.contains(o); - } - } - @NonNull - public Iterator iterator() { - throw new RuntimeException("Iterators break encapsulation and ignore locking"); -// return list.iterator(); - } - @NotNull - public Object[] toArray() { - try (LockHolder lh = lockForReading()) { - return list.toArray(); - } - } - @Override - @NotNull - public T1[] toArray(@Nullable T1[] a) { - try (LockHolder lh = lockForReading()) { - return list.toArray(a); - } - } - public boolean add(T t) { - try (LockHolder lh = lockForWriting()) { - boolean result = list.add(t); - lh.downgrade(); - if (result) - forceNotify(); - return result; - } - } - public boolean remove(@Nullable Object o) { - try (LockHolder lh = lockForWriting()) { - boolean result = list.remove(o); - lh.downgrade(); - if (result) forceNotify(); - return result; - } - } - public T removeQuietly(int index) { - return list.remove(index); - } - public boolean containsAll(@NonNull Collection c) { - try (LockHolder lh = lockForReading()) { - return list.containsAll(c); - } - } - public boolean addAll(@NonNull Collection c) { - try (LockHolder lh = lockForWriting()) { - boolean result = list.addAll(c); - lh.downgrade(); - if (result) forceNotify(); - return result; - } - } - public boolean addAll(int index, @NonNull Collection c) { - try (LockHolder lh = lockForWriting()) { - boolean result = list.addAll(index, c); - lh.downgrade(); - if (result) forceNotify(); - return result; - } - } - public boolean addAllQuietly(int index, Collection c) { - return list.addAll(index, c); - } - public boolean removeAll(@NonNull Collection c) { - try (LockHolder lh = lockForWriting()) { - boolean result = list.removeAll(c); - lh.downgrade(); - if (result) forceNotify(); - return result; - } - } - public boolean retainAll(@NonNull Collection c) { - try (LockHolder lh = lockForWriting()) { - boolean result = list.retainAll(c); - lh.downgrade(); - if (result) forceNotify(); - return result; - } - } - @RequiresApi(api = Build.VERSION_CODES.N) - public void replaceAll(@NonNull UnaryOperator operator) { - try (LockHolder lh = lockForWriting()) { - list.replaceAll(operator); - lh.downgrade(); - forceNotify(); - } - } - @RequiresApi(api = Build.VERSION_CODES.N) - public void sort(@Nullable Comparator c) { - try (LockHolder lh = lockForWriting()) { - lock.writeLock().lock(); - list.sort(c); - lh.downgrade(); - forceNotify(); - } - } - public void clear() { - try (LockHolder lh = lockForWriting()) { - boolean wasEmpty = list.isEmpty(); - list.clear(); - lh.downgrade(); - if (!wasEmpty) forceNotify(); - } - } - public T get(int index) { - try (LockHolder lh = lockForReading()) { - return list.get(index); - } - } - public T set(int index, T element) { - try (LockHolder lh = lockForWriting()) { - T result = list.set(index, element); - lh.downgrade(); - forceNotify(); - return result; - } - } - public void add(int index, T element) { - try (LockHolder lh = lockForWriting()) { - list.add(index, element); - lh.downgrade(); - forceNotify(); - } - } - public T remove(int index) { - try (LockHolder lh = lockForWriting()) { - T result = list.remove(index); - lh.downgrade(); - forceNotify(); - return result; - } - } - public int indexOf(@Nullable Object o) { - try (LockHolder lh = lockForReading()) { - return list.indexOf(o); - } - } - public int lastIndexOf(@Nullable Object o) { - try (LockHolder lh = lockForReading()) { - return list.lastIndexOf(o); - } - } - @NotNull - public ListIterator listIterator() { - if (!lock.isWriteLockedByCurrentThread()) throw new RuntimeException( - "Iterators break encapsulation and ignore locking. Write-lock first"); - return list.listIterator(); - } - @NotNull - public ListIterator listIterator(int index) { - if (!lock.isWriteLockedByCurrentThread()) throw new RuntimeException( - "Iterators break encapsulation and ignore locking. Write-lock first"); - return list.listIterator(index); - } - @NotNull - public List subList(int fromIndex, int toIndex) { - try (LockHolder lh = lockForReading()) { - return list.subList(fromIndex, toIndex); - } - } - @NotNull - @RequiresApi(api = Build.VERSION_CODES.N) - public Spliterator spliterator() { - if (!lock.isWriteLockedByCurrentThread()) - throw new RuntimeException( - "Iterators break encapsulation and ignore locking. Write-lock first"); - return list.spliterator(); - } - @RequiresApi(api = Build.VERSION_CODES.N) - public boolean removeIf(@NotNull Predicate filter) { - try (LockHolder lh = lockForWriting()) { - boolean result = list.removeIf(filter); - lh.downgrade(); - if (result) - forceNotify(); - return result; - } - } - @NotNull - @RequiresApi(api = Build.VERSION_CODES.N) - public Stream stream() { - if (!lock.isWriteLockedByCurrentThread()) throw new RuntimeException( - "Iterators break encapsulation and ignore locking. Write-lock first"); - return list.stream(); - } - @NotNull - @RequiresApi(api = Build.VERSION_CODES.N) - public Stream parallelStream() { - if (!lock.isWriteLockedByCurrentThread()) - throw new RuntimeException( - "Iterators break encapsulation and ignore locking. Write-lock first"); - return list.parallelStream(); - } - @RequiresApi(api = Build.VERSION_CODES.N) - public void forEach(@NotNull Consumer action) { - try (LockHolder lh = lockForReading()) { - list.forEach(action); - } - } - public List getList() { - if (!lock.isWriteLockedByCurrentThread()) - throw new RuntimeException( - "Direct list access breaks encapsulation and ignore locking. Write-lock first"); - return list; - } - public void setList(List aList) { - try (LockHolder lh = lockForWriting()) { - list = aList; - lh.downgrade(); - forceNotify(); - } - } - public void triggerItemChangedNotification(T item) { - try (LockHolder lh = lockForReading()) { - int index = list.indexOf(item); - if (index == -1) { - debug("ObList", "??? not sending notifications for item not found in the list"); - return; - } - debug("ObList", "Notifying item change observers"); - triggerItemChangedNotification(index); - } - } - public void triggerItemChangedNotification(int index) { - forceNotify(index); - } - public LockHolder lockForWriting() { - ReentrantReadWriteLock.WriteLock wLock = lock.writeLock(); - wLock.lock(); - - ReentrantReadWriteLock.ReadLock rLock = lock.readLock(); - rLock.lock(); - - return new LockHolder(rLock, wLock); - } - public LockHolder lockForReading() { - ReentrantReadWriteLock.ReadLock rLock = lock.readLock(); - rLock.lock(); - return new LockHolder(rLock); - } - public void blockNotifications() { - notificationBlocks++; - } - public void unblockNotifications() { - notificationBlocks--; - if ((notificationBlocks == 0) && notificationWasBlocked) notifyObservers(); - } -} \ No newline at end of file diff --git a/app/src/main/java/net/ktnx/mobileledger/utils/ObservableValue.java b/app/src/main/java/net/ktnx/mobileledger/utils/ObservableValue.java deleted file mode 100644 index 326be072..00000000 --- a/app/src/main/java/net/ktnx/mobileledger/utils/ObservableValue.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright © 2020 Damyan Ivanov. - * This file is part of MoLe. - * MoLe is free software: you can distribute it and/or modify it - * under the term of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your opinion), any later version. - * - * MoLe 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 terms for details. - * - * You should have received a copy of the GNU General Public License - * along with MoLe. If not, see . - */ - -package net.ktnx.mobileledger.utils; - -import java.util.Observable; -import java.util.Observer; - -public class ObservableValue { - private final ObservableValueImpl impl = new ObservableValueImpl<>(); - public ObservableValue() {} - public ObservableValue(T initialValue) { - impl.setValue(initialValue, false); - } - public void set(T newValue) { - impl.setValue(newValue); - } - public T get() { - return impl.getValue(); - } - public void addObserver(Observer o) { - impl.addObserver(o); - } - public void deleteObserver(Observer o) { - impl.deleteObserver(o); - } - public void notifyObservers() { - impl.notifyObservers(); - } - public void notifyObservers(T arg) { - impl.notifyObservers(arg); - } - public void deleteObservers() { - impl.deleteObservers(); - } - public boolean hasChanged() { - return impl.hasChanged(); - } - public int countObservers() { - return impl.countObservers(); - } - public void forceNotifyObservers() { - impl.setChanged(); - impl.notifyObservers(); - } - private static class ObservableValueImpl extends Observable { - protected T value; - public void setValue(T newValue) { - setValue(newValue, true); - } - protected void setChanged() { - super.setChanged(); - } - private synchronized void setValue(T newValue, boolean notify) { - if ((newValue == null) && (value == null)) - return; - - if ((newValue != null) && newValue.equals(value)) return; - - T oldValue = value; - value = newValue; - setChanged(); - if (notify) notifyObservers(oldValue); - } - public T getValue() { - return value; - } - } -} \ No newline at end of file -- 2.39.2 From c61d7a1bbd4ee0393e436ec604dfc2fa3910bd47 Mon Sep 17 00:00:00 2001 From: Damyan Ivanov Date: Sun, 9 Jun 2024 18:49:20 +0000 Subject: [PATCH 05/11] bump target SDK version to 33 --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 71673f6e..442da8e0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -18,11 +18,11 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 31 + compileSdkVersion 33 defaultConfig { applicationId "net.ktnx.mobileledger" minSdkVersion 22 - targetSdkVersion 31 + targetSdkVersion 33 vectorDrawables.useSupportLibrary true versionCode 56 versionName '0.21.7' -- 2.39.2 From d2de702988bf60c997f46e059fb7c4fd66cd398d Mon Sep 17 00:00:00 2001 From: Damyan Ivanov Date: Sun, 9 Jun 2024 18:49:58 +0000 Subject: [PATCH 06/11] turn on enablOnBackInvokedCallback option in ap manifest --- app/src/main/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b17a1ecf..1674610e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -29,6 +29,7 @@ android:roundIcon="@drawable/app_icon_round" android:supportsRtl="true" android:backupAgent=".backup.MobileLedgerBackupAgent" + android:enableOnBackInvokedCallback="true" tools:ignore="GoogleAppIndexingWarning"> Date: Sun, 9 Jun 2024 18:54:00 +0000 Subject: [PATCH 07/11] add monochrome app icon, use slightly cleaner app icon --- .../main/res/drawable-anydpi-v26/app_icon.xml | 1 + .../main/res/drawable/launcher_foreground.xml | 97 +++++---- art/app-icon-adaptive.svg | 191 ++++++++++++++++++ 3 files changed, 251 insertions(+), 38 deletions(-) create mode 100644 art/app-icon-adaptive.svg diff --git a/app/src/main/res/drawable-anydpi-v26/app_icon.xml b/app/src/main/res/drawable-anydpi-v26/app_icon.xml index b82ac92d..cd0b7c71 100644 --- a/app/src/main/res/drawable-anydpi-v26/app_icon.xml +++ b/app/src/main/res/drawable-anydpi-v26/app_icon.xml @@ -19,4 +19,5 @@ + \ No newline at end of file diff --git a/app/src/main/res/drawable/launcher_foreground.xml b/app/src/main/res/drawable/launcher_foreground.xml index af159e2b..b78a67ed 100644 --- a/app/src/main/res/drawable/launcher_foreground.xml +++ b/app/src/main/res/drawable/launcher_foreground.xml @@ -1,5 +1,5 @@