persist received notifications
This commit is contained in:
parent
7234c0e45e
commit
97c13a3619
7 changed files with 161 additions and 11 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"></string>
|
||||
<string name="fa_lock" translatable="false"></string>
|
||||
|
|
Loading…
Add table
Reference in a new issue