Remove local suppression store
This commit is contained in:
@@ -20,7 +20,7 @@ Logcat tags:
|
||||
## Using the feed UI
|
||||
- Tap the pinned LiveCard to open `FeedActivity`.
|
||||
- Swipe left/right to move through cards.
|
||||
- Tap a card to open its actions (Glass-style overlay); `DISMISS` / `SNOOZE_*` are stored locally and stay hidden across restarts.
|
||||
- Tap a card to open its actions (Glass-style overlay); `DISMISS` / `SNOOZE_*` remove the card from the current view and rely on the companion feed to keep it suppressed.
|
||||
|
||||
## FYI static cards (Weather)
|
||||
If the feed includes a card with `bucket="FYI"` and a `type` that equals `WEATHER_INFO` or contains `WEATHER` (e.g. `CURRENT_WEATHER`), the app publishes it as a Glass “static card” via an Android notification using a custom `RemoteViews` layout modeled after the “Google Now Weather” card style (see `app/src/main/res/layout/weather_static_card.xml` and `app/src/main/java/sh/nym/irisglass/WeatherStaticCardPublisher.java`).
|
||||
|
||||
@@ -17,7 +17,6 @@ public final class FeedActivity extends Activity {
|
||||
|
||||
private CardScrollView cardScrollView;
|
||||
private FeedAdapter adapter;
|
||||
private SuppressionStore suppressionStore;
|
||||
private FeedItem selectedItem;
|
||||
|
||||
private final HudState.Listener hudListener = new HudState.Listener() {
|
||||
@@ -37,8 +36,6 @@ public final class FeedActivity extends Activity {
|
||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
suppressionStore = new SuppressionStore(this);
|
||||
|
||||
cardScrollView = new CardScrollView(this);
|
||||
adapter = new FeedAdapter(this, makeWaitingCard());
|
||||
cardScrollView.setAdapter(adapter);
|
||||
@@ -85,15 +82,11 @@ public final class FeedActivity extends Activity {
|
||||
String action = data.getStringExtra(MenuActivity.EXTRA_ACTION);
|
||||
if (cardId == null || action == null) return;
|
||||
|
||||
long now = System.currentTimeMillis() / 1000L;
|
||||
if ("DISMISS".equals(action)) {
|
||||
suppressionStore.setSuppressed(cardId, now + (10L * 365L * 24L * 60L * 60L));
|
||||
adapter.removeById(cardId);
|
||||
} else if ("SNOOZE_2H".equals(action)) {
|
||||
suppressionStore.setSuppressed(cardId, now + 2L * 60L * 60L);
|
||||
adapter.removeById(cardId);
|
||||
} else if ("SNOOZE_24H".equals(action)) {
|
||||
suppressionStore.setSuppressed(cardId, now + 24L * 60L * 60L);
|
||||
adapter.removeById(cardId);
|
||||
} else if ("SAVE".equals(action)) {
|
||||
Toast.makeText(this, "Saved", Toast.LENGTH_SHORT).show();
|
||||
@@ -125,12 +118,10 @@ public final class FeedActivity extends Activity {
|
||||
List<FeedItem> items = env.activeItems();
|
||||
if (items.isEmpty()) return makeWaitingCard();
|
||||
|
||||
long now = System.currentTimeMillis() / 1000L;
|
||||
ArrayList<FeedItem> filtered = new ArrayList<FeedItem>();
|
||||
for (int i = 0; i < items.size(); i++) {
|
||||
FeedItem it = items.get(i);
|
||||
if (it == null) continue;
|
||||
if (it.id != null && suppressionStore.isSuppressed(it.id, now)) continue;
|
||||
filtered.add(it);
|
||||
}
|
||||
if (filtered.isEmpty()) return makeWaitingCard();
|
||||
|
||||
@@ -9,11 +9,9 @@ import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import java.util.HashSet;
|
||||
|
||||
@@ -33,9 +31,10 @@ public final class MenuActivity extends Activity {
|
||||
private boolean isMenuClosed;
|
||||
private boolean preparePanelCalled;
|
||||
private boolean fromLiveCardVoice;
|
||||
private boolean actionsReady;
|
||||
|
||||
private String cardId;
|
||||
private HashSet<String> allowedActions = new HashSet<String>();
|
||||
private final HashSet<String> allowedActions = new HashSet<String>();
|
||||
|
||||
public static Intent newIntent(Context context, FeedItem item) {
|
||||
Intent i = new Intent(context, MenuActivity.class);
|
||||
@@ -53,15 +52,6 @@ public final class MenuActivity extends Activity {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Increase contrast so menu labels are readable over underlying cards.
|
||||
try {
|
||||
WindowManager.LayoutParams lp = getWindow().getAttributes();
|
||||
lp.flags |= WindowManager.LayoutParams.FLAG_DIM_BEHIND;
|
||||
lp.dimAmount = 0.65f;
|
||||
getWindow().setAttributes(lp);
|
||||
} catch (Throwable ignored) {
|
||||
}
|
||||
|
||||
fromLiveCardVoice = getIntent().getBooleanExtra(LiveCard.EXTRA_FROM_LIVECARD_VOICE, false);
|
||||
if (fromLiveCardVoice) {
|
||||
getWindow().requestFeature(WindowUtils.FEATURE_VOICE_COMMANDS);
|
||||
@@ -74,6 +64,8 @@ public final class MenuActivity extends Activity {
|
||||
if (actions[i] != null) allowedActions.add(actions[i]);
|
||||
}
|
||||
}
|
||||
actionsReady = true;
|
||||
openMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -92,8 +84,7 @@ public final class MenuActivity extends Activity {
|
||||
@Override
|
||||
public boolean onCreatePanelMenu(int featureId, Menu menu) {
|
||||
if (isMyMenu(featureId)) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.feed_actions, menu);
|
||||
getMenuInflater().inflate(R.menu.feed_actions, menu);
|
||||
return true;
|
||||
}
|
||||
return super.onCreatePanelMenu(featureId, menu);
|
||||
@@ -103,6 +94,9 @@ public final class MenuActivity extends Activity {
|
||||
public boolean onPreparePanel(int featureId, View view, Menu menu) {
|
||||
preparePanelCalled = true;
|
||||
if (isMyMenu(featureId)) {
|
||||
if (!actionsReady) {
|
||||
return false;
|
||||
}
|
||||
// Enable only actions present on the tapped card.
|
||||
setOptionsMenuState(menu.findItem(R.id.action_dismiss), allowedActions.contains("DISMISS"));
|
||||
setOptionsMenuState(menu.findItem(R.id.action_snooze_2h), allowedActions.contains("SNOOZE_2H"));
|
||||
@@ -110,6 +104,8 @@ public final class MenuActivity extends Activity {
|
||||
setOptionsMenuState(menu.findItem(R.id.action_save), allowedActions.contains("SAVE"));
|
||||
// Always allow Back.
|
||||
setOptionsMenuState(menu.findItem(R.id.action_back), true);
|
||||
// Don't reopen menu once we are finishing. This is necessary
|
||||
// since voice menus reopen themselves while in focus.
|
||||
return !isMenuClosed;
|
||||
}
|
||||
return super.onPreparePanel(featureId, view, menu);
|
||||
@@ -129,7 +125,7 @@ public final class MenuActivity extends Activity {
|
||||
}
|
||||
|
||||
// Post for proper options menu animation (per timer sample guidance).
|
||||
handler.post(new Runnable() {
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Intent r = new Intent();
|
||||
@@ -151,21 +147,43 @@ public final class MenuActivity extends Activity {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Posts a {@link Runnable} at the end of the message loop, overridable for testing.
|
||||
*/
|
||||
protected void post(Runnable runnable) {
|
||||
handler.post(runnable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the touch or voice menu iff all the conditions are satisfied.
|
||||
*/
|
||||
private void openMenu() {
|
||||
if (!attachedToWindow) return;
|
||||
if (attachedToWindow && actionsReady) {
|
||||
if (fromLiveCardVoice) {
|
||||
if (preparePanelCalled) {
|
||||
// Invalidates the previously prepared voice menu now that we can properly
|
||||
// prepare it.
|
||||
getWindow().invalidatePanelMenu(WindowUtils.FEATURE_VOICE_COMMANDS);
|
||||
}
|
||||
} else {
|
||||
// Open the options menu for the touch flow.
|
||||
openOptionsMenu();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isMyMenu(int featureId) {
|
||||
return featureId == Window.FEATURE_OPTIONS_PANEL || featureId == WindowUtils.FEATURE_VOICE_COMMANDS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} when the {@code featureId} belongs to the options menu or voice
|
||||
* menu that are controlled by this menu activity.
|
||||
*/
|
||||
private boolean isMyMenu(int featureId) {
|
||||
return featureId == Window.FEATURE_OPTIONS_PANEL
|
||||
|| featureId == WindowUtils.FEATURE_VOICE_COMMANDS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a {@code MenuItem} visible and enabled state.
|
||||
*/
|
||||
private static void setOptionsMenuState(MenuItem menuItem, boolean enabled) {
|
||||
if (menuItem == null) return;
|
||||
menuItem.setVisible(enabled);
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
package sh.nym.irisglass;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
public final class SuppressionStore {
|
||||
private static final String KEY_PREFIX = "suppression_until_";
|
||||
|
||||
private final SharedPreferences prefs;
|
||||
|
||||
public SuppressionStore(Context context) {
|
||||
this.prefs = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
|
||||
}
|
||||
|
||||
public boolean isSuppressed(String id, long nowEpochSeconds) {
|
||||
if (id == null) return false;
|
||||
long until = prefs.getLong(KEY_PREFIX + id, 0L);
|
||||
if (until <= 0L) return false;
|
||||
if (until <= nowEpochSeconds) {
|
||||
prefs.edit().remove(KEY_PREFIX + id).apply();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setSuppressed(String id, long untilEpochSeconds) {
|
||||
if (id == null) return;
|
||||
prefs.edit().putLong(KEY_PREFIX + id, untilEpochSeconds).apply();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,10 @@
|
||||
</style>
|
||||
|
||||
<!-- Matches the GDK timer sample MenuTheme to get the correct Glass menu overlay behavior. -->
|
||||
<style name="Theme.IrisGlass.MenuOverlay" parent="@android:style/Theme.Holo">
|
||||
<style name="Theme.IrisGlass.MenuOverlay" parent="@android:style/Theme.DeviceDefault">
|
||||
<item name="android:windowBackground">@android:color/transparent</item>
|
||||
<item name="android:colorBackgroundCacheHint">@null</item>
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
<item name="android:windowAnimationStyle">@null</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowActionBar">false</item>
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user