persist received notifications

This commit is contained in:
Akinwale Ariwodola 2020-07-22 15:00:00 +01:00
parent 7234c0e45e
commit 97c13a3619
7 changed files with 161 additions and 11 deletions

View file

@ -1,31 +1,38 @@
package io.lbry.browser;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import androidx.core.text.HtmlCompat;
import androidx.preference.PreferenceManager;
import android.text.Html;
import android.util.Log;
import com.google.firebase.analytics.FirebaseAnalytics;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
import io.lbry.browser.data.DatabaseHelper;
import io.lbry.browser.model.lbryinc.LbryNotification;
import io.lbry.browser.utils.LbryAnalytics;
import io.lbry.lbrysdk.LbrynetService;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
@ -67,6 +74,21 @@ public class LbrynetMessagingService extends FirebaseMessagingService {
sendNotification(title, body, type, url, name, contentTitle, channelUrl, publishTime);
}
// persist the notification data
try {
DatabaseHelper helper = DatabaseHelper.getInstance();
SQLiteDatabase db = helper.getWritableDatabase();
LbryNotification lnotification = new LbryNotification();
lnotification.setTitle(title);
lnotification.setDescription(body);
lnotification.setTargetUrl(url);
lnotification.setTimestamp(new Date());
DatabaseHelper.createNotification(lnotification, db);
} catch (Exception ex) {
// don't fail if any error occurs while saving a notification
Log.e(TAG, "could not save notification", ex);
}
}
}
@ -120,8 +142,8 @@ public class LbrynetMessagingService extends FirebaseMessagingService {
new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setColor(ContextCompat.getColor(this, R.color.lbryGreen))
.setSmallIcon(R.drawable.ic_lbry)
.setContentTitle(title)
.setContentText(messageBody)
.setContentTitle(HtmlCompat.fromHtml(messageBody, HtmlCompat.FROM_HTML_MODE_LEGACY))
.setContentText(HtmlCompat.fromHtml(messageBody, HtmlCompat.FROM_HTML_MODE_LEGACY))
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);

View file

@ -438,6 +438,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
// setup uri bar
setupUriBar();
initNotificationsPage();
// other
pendingSyncSetQueue = new ArrayList<>();
@ -502,6 +503,18 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
}
});
findViewById(R.id.wunderbar_notifications).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
View container = findViewById(R.id.notifications_container);
if (container.getVisibility() != View.VISIBLE) {
showNotifications();
} else {
hideNotifications();
}
}
});
findViewById(R.id.global_now_playing_card).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
@ -1059,7 +1072,7 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
View container = findViewById(R.id.url_suggestions_container);
View closeIcon = findViewById(R.id.wunderbar_close);
EditText wunderbar = findViewById(R.id.wunderbar);
wunderbar.setPadding(0, 0, visible ? getScaledValue(36) : 0, 0);
//wunderbar.setPadding(0, 0, visible ? getScaledValue(36) : 0, 0);
container.setVisibility(visible ? View.VISIBLE : View.GONE);
closeIcon.setVisibility(visible ? View.VISIBLE : View.GONE);
@ -1094,8 +1107,13 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
@Override
public void onFocusChange(View view, boolean hasFocus) {
if (hasFocus) {
hideNotifications();
findViewById(R.id.wunderbar_notifications).setVisibility(View.INVISIBLE);
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(view, 0);
} else {
findViewById(R.id.wunderbar_notifications).setVisibility(View.VISIBLE);
}
if (canShowUrlSuggestions()) {
@ -1629,6 +1647,10 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
private static final String CHANNEL_ID_PLAYBACK = "io.lbry.browser.LBRY_PLAYBACK_CHANNEL";
private static final int PLAYBACK_NOTIFICATION_ID = 3;
public void initNotificationsPage() {
findViewById(R.id.notification_list_empty_container).setVisibility(View.VISIBLE);
}
public void initPlaybackNotification() {
if (isBackgroundPlaybackEnabled()) {
playerNotificationManager.setPlayer(MainActivity.appPlayer);
@ -2063,13 +2085,25 @@ public class MainActivity extends AppCompatActivity implements SdkStatusListener
setBackgroundTint(Color.RED).setTextColor(Color.WHITE).show();
}
public void showNotifications() {
clearWunderbarFocus(findViewById(R.id.wunderbar));
findViewById(R.id.notifications_container).setVisibility(View.VISIBLE);
}
public void hideNotifications() {
findViewById(R.id.notifications_container).setVisibility(View.GONE);
}
@Override
public void onBackPressed() {
if (findViewById(R.id.url_suggestions_container).getVisibility() == View.VISIBLE) {
clearWunderbarFocus(findViewById(R.id.wunderbar));
return;
}
if (findViewById(R.id.notifications_container).getVisibility() == View.VISIBLE) {
hideNotifications();
return;
}
if (backPressInterceptor != null && backPressInterceptor.onBackPressed()) {
return;
}

View file

@ -4,7 +4,6 @@ import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.opengl.Visibility;
import java.math.BigDecimal;
import java.text.ParseException;
@ -13,16 +12,16 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import io.lbry.browser.exceptions.LbryUriException;
import io.lbry.browser.model.Tag;
import io.lbry.browser.model.UrlSuggestion;
import io.lbry.browser.model.ViewHistory;
import io.lbry.browser.model.lbryinc.LbryNotification;
import io.lbry.browser.model.lbryinc.Subscription;
import io.lbry.browser.utils.Helper;
import io.lbry.browser.utils.LbryUri;
public class DatabaseHelper extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 2;
public static final int DATABASE_VERSION = 3;
public static final String DATABASE_NAME = "LbryApp.db";
private static DatabaseHelper instance;
@ -48,7 +47,14 @@ public class DatabaseHelper extends SQLiteOpenHelper {
", thumbnail_url TEXT" +
", release_time INTEGER " +
", device TEXT" +
", timestamp TEXT NOT NULL)"
", timestamp TEXT NOT NULL)",
"CREATE TABLE notifications (" +
" id INTEGER PRIMARY KEY NOT NULL" +
", title TEXT" +
", description TEXT" +
", thumbnail_url TEXT" +
", target_url TEXT" +
", timestamp TEXT NOT NULL)",
};
private static final String[] SQL_CREATE_INDEXES = {
"CREATE UNIQUE INDEX idx_subscription_url ON subscriptions (url)",
@ -56,7 +62,8 @@ public class DatabaseHelper extends SQLiteOpenHelper {
"CREATE UNIQUE INDEX idx_url_history_url ON url_history (url)",
"CREATE UNIQUE INDEX idx_tag_name ON tags (name)",
"CREATE UNIQUE INDEX idx_view_history_url_device ON view_history (url, device)",
"CREATE INDEX idx_view_history_device ON view_history (device)"
"CREATE INDEX idx_view_history_device ON view_history (device)",
"CREATE INDEX idx_notification_timestamp ON notifications (timestamp)"
};
private static final String[] SQL_V1_V2_UPGRADE = {
@ -68,7 +75,10 @@ public class DatabaseHelper extends SQLiteOpenHelper {
" id INTEGER PRIMARY KEY NOT NULL" +
", title TEXT" +
", description TEXT" +
", thumbnail_url TEXT" +
", target_url TEXT" +
", timestamp TEXT NOT NULL)",
"CREATE INDEX idx_notification_timestamp ON notifications (timestamp)"
};
private static final String SQL_INSERT_SUBSCRIPTION = "REPLACE INTO subscriptions (channel_name, url) VALUES (?, ?)";
@ -81,6 +91,9 @@ public class DatabaseHelper extends SQLiteOpenHelper {
private static final String SQL_CLEAR_URL_HISTORY_BEFORE_TIME = "DELETE FROM url_history WHERE timestamp < ?";
private static final String SQL_GET_RECENT_URL_HISTORY = "SELECT value, url, type FROM url_history ORDER BY timestamp DESC LIMIT 10";
private static final String SQL_INSERT_NOTIFICATION = "INSERT INTO notifications (title, description, target_url, timestamp) VALUES (?, ?, ?, ?)";
private static final String SQL_GET_NOTIFICATIONS = "SELECT id, title, description, target_url, timestamp FROM notifications ORDER BY timestamp DESC LIMIT 500";
private static final String SQL_INSERT_VIEW_HISTORY =
"REPLACE INTO view_history (url, claim_id, claim_name, cost, currency, title, publisher_claim_id, publisher_name, publisher_title, thumbnail_url, device, release_time, timestamp) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
private static final String SQL_GET_VIEW_HISTORY =
@ -119,6 +132,11 @@ public class DatabaseHelper extends SQLiteOpenHelper {
db.execSQL(sql);
}
}
if (oldVersion < 3) {
for (String sql : SQL_V2_V3_UPGRADE) {
db.execSQL(sql);
}
}
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
@ -259,4 +277,35 @@ public class DatabaseHelper extends SQLiteOpenHelper {
return subscriptions;
}
public static void createNotification(LbryNotification notification, SQLiteDatabase db) {
db.execSQL(SQL_INSERT_NOTIFICATION, new Object[] {
notification.getTitle(),
notification.getDescription(),
notification.getTargetUrl(),
new SimpleDateFormat(Helper.ISO_DATE_FORMAT_PATTERN).format(notification.getTimestamp() != null ? notification.getTimestamp() : new Date())
});
}
public static List<LbryNotification> getNotifications(SQLiteDatabase db) {
List<LbryNotification> notifications = new ArrayList<>();
Cursor cursor = null;
try {
cursor = db.rawQuery(SQL_GET_NOTIFICATIONS, null);
while (cursor.moveToNext()) {
LbryNotification notification = new LbryNotification();
notification.setId(cursor.getLong(0));
notification.setTitle(cursor.getString(1));
notification.setDescription(cursor.getString(2));
notification.setTargetUrl(cursor.getString(3));
try {
notification.setTimestamp(new SimpleDateFormat(Helper.ISO_DATE_FORMAT_PATTERN).parse(cursor.getString(4)));
} catch (ParseException ex) {
// invalid timestamp (which shouldn't happen). Skip this item
continue;
}
}
} finally {
Helper.closeCursor(cursor);
}
return notifications;
}
}

View file

@ -1,12 +1,15 @@
package io.lbry.browser.model.lbryinc;
import java.util.Date;
import lombok.Data;
@Data
public class Notification {
public class LbryNotification {
private long id;
private String title;
private String description;
private String thumbnailUrl;
private String targetUrl;
private Date timestamp;
}

View file

@ -42,6 +42,7 @@
android:hint="@string/uri_placeholder"
android:imeOptions="actionGo"
android:inputType="textNoSuggestions"
android:paddingRight="36dp"
android:selectAllOnFocus="true"
android:singleLine="true"
android:textFontWeight="300"

View file

@ -33,6 +33,44 @@
android:layout_height="match_parent" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/notifications_container"
android:background="@color/pageBackground"
android:elevation="6dp"
android:fitsSystemWindows="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<LinearLayout
android:id="@+id/notification_list_empty_container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:padding="36dp"
android:visibility="gone">
<ImageView
android:layout_gravity="center_horizontal"
android:layout_width="160dp"
android:layout_height="300dp"
android:adjustViewBounds="true"
android:src="@drawable/gerbil_happy" />
<TextView
android:text="@string/no_notifications"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_gravity="center_horizontal"
android:fontFamily="@font/inter"
android:textSize="16sp"
android:textAlignment="center" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/notifications_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
<include layout="@layout/floating_wallet_balance" />
<RelativeLayout

View file

@ -603,6 +603,9 @@
<string name="cannot_find_lbrynet_log">The lbrynet.log file could not be found.</string>
<string name="cannot_share_lbrynet_log">The lbrynet.log file cannot be shared due to permission restrictions.</string>
<!-- Notifications -->
<string name="no_notifications">It\'s quiet here! New notifications will be displayed when you receive them.</string>
<!-- Font Awesome -->
<string name="fa_gift" translatable="false">&#xf06b;</string>
<string name="fa_lock" translatable="false">&#xf023;</string>