Skip to content

Commit

Permalink
Display release notes in new update dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
therealsujitk committed Nov 11, 2023
1 parent 00ad05f commit 21106fa
Show file tree
Hide file tree
Showing 8 changed files with 253 additions and 40 deletions.
2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ dependencies {

implementation 'commons-io:commons-io:2.6'

implementation 'io.noties.markwon:core:4.6.2'

implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'

debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.8.1'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,26 @@
import android.widget.EditText;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import com.google.firebase.analytics.FirebaseAnalytics;

import org.json.JSONObject;

import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.disposables.Disposable;
import tk.therealsuji.vtopchennai.BuildConfig;
import tk.therealsuji.vtopchennai.R;
import tk.therealsuji.vtopchennai.fragments.dialogs.UpdateDialogFragment;
import tk.therealsuji.vtopchennai.helpers.SettingsRepository;
import tk.therealsuji.vtopchennai.helpers.VTOPHelper;

public class LoginActivity extends AppCompatActivity {
SharedPreferences encryptedSharedPreferences, sharedPreferences;
CompositeDisposable compositeDisposable = new CompositeDisposable();
VTOPHelper vtopHelper;

public void signIn() {
Expand Down Expand Up @@ -95,6 +106,42 @@ public void onComplete() {
startMainActivity();
}
});

/*
Check for updates
*/
SettingsRepository.checkForUpdates()
.subscribe(new Observer<JSONObject>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
compositeDisposable.add(d);
}

@Override
public void onNext(@NonNull JSONObject about) {
try {
int versionCode = about.getInt("versionCode");
String versionName = about.getString("tagName");
String releaseNotes = about.getString("releaseNotes");

if (versionCode > BuildConfig.VERSION_CODE) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
transaction.add(android.R.id.content, new UpdateDialogFragment(versionName, releaseNotes)).addToBackStack(null).commit();
}
} catch (Exception ignored) {
}
}

@Override
public void onError(@NonNull Throwable e) {
}

@Override
public void onComplete() {
}
});
}

@Override
Expand Down Expand Up @@ -122,4 +169,10 @@ protected void onStop() {
super.onStop();
this.vtopHelper.unbind();
}

@Override
protected void onDestroy() {
super.onDestroy();
compositeDisposable.dispose();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import androidx.core.view.WindowCompat;
import androidx.documentfile.provider.DocumentFile;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import com.google.android.material.badge.BadgeDrawable;
import com.google.android.material.bottomnavigation.BottomNavigationView;
Expand All @@ -27,10 +29,7 @@

import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
Expand All @@ -46,6 +45,7 @@
import tk.therealsuji.vtopchennai.fragments.HomeFragment;
import tk.therealsuji.vtopchennai.fragments.PerformanceFragment;
import tk.therealsuji.vtopchennai.fragments.ProfileFragment;
import tk.therealsuji.vtopchennai.fragments.dialogs.UpdateDialogFragment;
import tk.therealsuji.vtopchennai.helpers.AppDatabase;
import tk.therealsuji.vtopchennai.helpers.SettingsRepository;
import tk.therealsuji.vtopchennai.helpers.VTOPHelper;
Expand Down Expand Up @@ -361,47 +361,32 @@ public void onComplete() {
Check for updates
*/
Context context = this;
Observable.fromCallable(() -> {
try {
StringBuilder sb = new StringBuilder();
URL url = new URL(SettingsRepository.APP_ABOUT_URL + "?v=" + BuildConfig.VERSION_NAME);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream in = httpURLConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();

while (data != -1) {
char current = (char) data;
sb.append(current);
data = reader.read();
}

String result = sb.toString();
JSONObject about = new JSONObject(result);

return about.getInt("versionCode");
} catch (Exception ignored) {
return 0;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Integer>() {
SettingsRepository.checkForUpdates()
.subscribe(new Observer<JSONObject>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
compositeDisposable.add(d);
}

@Override
public void onNext(@NonNull Integer versionCode) {
if (versionCode > BuildConfig.VERSION_CODE) {
new MaterialAlertDialogBuilder(context)
.setMessage(R.string.update_message)
.setNegativeButton(R.string.cancel, (dialogInterface, i) -> dialogInterface.dismiss())
.setPositiveButton(R.string.update, (dialogInterface, i) -> SettingsRepository.openDownloadPage(context))
.setTitle(R.string.update_title)
.show();
} else if (SettingsRepository.isRefreshRequired(context)) {
public void onNext(@NonNull JSONObject about) {
try {
int versionCode = about.getInt("versionCode");
String versionName = about.getString("tagName");
String releaseNotes = about.getString("releaseNotes");

if (versionCode > BuildConfig.VERSION_CODE) {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
transaction.add(android.R.id.content, new UpdateDialogFragment(versionName, releaseNotes)).addToBackStack(null).commit();

return;
}
} catch (Exception ignored) {
}

if (SettingsRepository.isRefreshRequired(context)) {
new MaterialAlertDialogBuilder(context)
.setMessage(R.string.sync_message)
.setNegativeButton(R.string.cancel, (dialogInterface, i) -> dialogInterface.dismiss())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package tk.therealsuji.vtopchennai.fragments.dialogs;

import android.app.Dialog;
import android.os.Bundle;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.DialogFragment;

import io.noties.markwon.Markwon;
import tk.therealsuji.vtopchennai.R;
import tk.therealsuji.vtopchennai.helpers.SettingsRepository;

public class UpdateDialogFragment extends DialogFragment {
String versionName, releaseNotes;

public UpdateDialogFragment() {
// Required empty public constructor
}

public UpdateDialogFragment(String versionName, String releaseNotes) {
this.versionName = versionName;
this.releaseNotes = releaseNotes;
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View dialogFragment = inflater.inflate(R.layout.layout_dialog_update, container, false);

TextView description = dialogFragment.findViewById(R.id.text_view_description);
description.setText(Html.fromHtml(this.requireContext().getString(R.string.update_message, this.versionName), Html.FROM_HTML_MODE_LEGACY));

TextView releaseNotes = dialogFragment.findViewById(R.id.text_view_release_notes);
Markwon markwon = Markwon.create(this.requireContext());
markwon.setMarkdown(releaseNotes, this.releaseNotes);

dialogFragment.findViewById(R.id.button_cancel).setOnClickListener(view -> this.dismiss());
dialogFragment.findViewById(R.id.button_update).setOnClickListener(view -> SettingsRepository.openDownloadPage(this.requireContext()));

return dialogFragment;
}

@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
return dialog;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@
import com.google.android.material.color.DynamicColors;
import com.google.android.material.color.DynamicColorsOptions;

import org.json.JSONObject;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.text.ParseException;
Expand All @@ -46,7 +52,11 @@
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import tk.therealsuji.vtopchennai.BuildConfig;
import tk.therealsuji.vtopchennai.R;
import tk.therealsuji.vtopchennai.activities.WebViewActivity;
import tk.therealsuji.vtopchennai.fragments.RecyclerViewFragment;
Expand Down Expand Up @@ -193,6 +203,32 @@ public static boolean hasFileWritePermission(Context context) {
return hasPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
}

public static Observable<JSONObject> checkForUpdates() {
return Observable.fromCallable(() -> {
try {
StringBuilder sb = new StringBuilder();
URL url = new URL(SettingsRepository.APP_ABOUT_URL + "?v=" + BuildConfig.VERSION_NAME);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream in = httpURLConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();

while (data != -1) {
char current = (char) data;
sb.append(current);
data = reader.read();
}

String result = sb.toString();
return new JSONObject(result);
} catch (Exception ignored) {
return new JSONObject();
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}

public static void openDownloadPage(Context context) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(APP_BASE_URL));
context.startActivity(browserIntent);
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/res/drawable/ic_update_available.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#000000"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M23,12l-2.44,-2.78 0.34,-3.68 -3.61,-0.82 -1.89,-3.18L12,3 8.6,1.54 6.71,4.72l-3.61,0.81 0.34,3.68L1,12l2.44,2.78 -0.34,3.69 3.61,0.82 1.89,3.18L12,21l3.4,1.46 1.89,-3.18 3.61,-0.82 -0.34,-3.68L23,12zM18.49,14.11l0.26,2.79 -2.74,0.62 -1.43,2.41L12,18.82l-2.58,1.11 -1.43,-2.41 -2.74,-0.62 0.26,-2.8L3.66,12l1.85,-2.12 -0.26,-2.78 2.74,-0.61 1.43,-2.41L12,5.18l2.58,-1.11 1.43,2.41 2.74,0.62 -0.26,2.79L20.34,12l-1.85,2.11zM11,15h2v2h-2zM11,7h2v6h-2z" />
</vector>
69 changes: 69 additions & 0 deletions app/src/main/res/layout/layout_dialog_update.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?android:colorBackground"
android:fitsSystemWindows="true">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp"
android:orientation="vertical">

<TextView
android:id="@+id/text_view_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawablePadding="10dp"
android:text="@string/update_title"
android:textSize="25sp"
android:textStyle="bold"
app:drawableStartCompat="@drawable/ic_update_available"
app:drawableTint="?attr/colorPrimary" />

<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginVertical="20dp"
android:layout_weight="1">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">

<TextView
android:id="@+id/text_view_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/update_message"
android:textSize="16sp" />

<TextView
android:id="@+id/text_view_release_notes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:textSize="16sp" />
</LinearLayout>
</ScrollView>

<Button
android:id="@+id/button_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="15dp"
android:text="@string/download_update" />

<Button
android:id="@+id/button_cancel"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:paddingVertical="15dp"
android:text="@string/cancel_update" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
5 changes: 3 additions & 2 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,9 @@

<!-- Update Dialog Strings -->
<string name="update_title">Update Available</string>
<string name="update_message">A new version of &app_name; has been released! The Update button bellow will take you to the download page.</string>
<string name="update">Update</string>
<string name="update_message">A new version of &app_name; (&lt;b>%s&lt;/b>) has been released! The Update button bellow will take you to the download page.</string>
<string name="cancel_update">I\'ll do this later</string>
<string name="download_update">Download Update</string>

<!-- Sync Dialog Strings -->
<string name="sync_title">Data Sync Required</string>
Expand Down

0 comments on commit 21106fa

Please sign in to comment.