feed filter: save the changed values to the DB, go to map if no location chosen, reload if necessary
This commit is contained in:
@@ -19,6 +19,7 @@ tasks :
|
|||||||
- .2 don't show a warning on a totally new project when the authorized agent is set
|
- .2 don't show a warning on a totally new project when the authorized agent is set
|
||||||
- .2 anchor hash into BTC
|
- .2 anchor hash into BTC
|
||||||
- .2 list the "show more" contacts alphabetically
|
- .2 list the "show more" contacts alphabetically
|
||||||
|
- .5 add back the explicit wait for browser subscription timing problems?
|
||||||
|
|
||||||
- .5 make Time Safari a share_target for images
|
- .5 make Time Safari a share_target for images
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,10 @@
|
|||||||
<p class="mb-4 font-bold">Show only activities that are…</p>
|
<p class="mb-4 font-bold">Show only activities that are…</p>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 gap-2">
|
<div class="grid grid-cols-1 gap-2">
|
||||||
<div class="flex items-center justify-between cursor-pointer">
|
<div
|
||||||
|
class="flex items-center justify-between cursor-pointer"
|
||||||
|
@click="toggleContacts()"
|
||||||
|
>
|
||||||
<!-- label -->
|
<!-- label -->
|
||||||
<div>From my contacts</div>
|
<div>From my contacts</div>
|
||||||
<!-- toggle -->
|
<!-- toggle -->
|
||||||
@@ -14,7 +17,7 @@
|
|||||||
<!-- input -->
|
<!-- input -->
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
v-model="isFromMyContacts"
|
v-model="isInMyContacts"
|
||||||
name="toggleFilterFromMyContacts"
|
name="toggleFilterFromMyContacts"
|
||||||
class="sr-only"
|
class="sr-only"
|
||||||
/>
|
/>
|
||||||
@@ -27,11 +30,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-center justify-between cursor-pointer">
|
<div
|
||||||
|
class="flex items-center justify-between cursor-pointer"
|
||||||
|
@click="
|
||||||
|
hasSearchBox
|
||||||
|
? toggleNearby()
|
||||||
|
: $router.push({ name: 'search-area' })
|
||||||
|
"
|
||||||
|
>
|
||||||
<!-- label -->
|
<!-- label -->
|
||||||
<div>Nearby</div>
|
<div>Nearby</div>
|
||||||
<!-- toggle -->
|
<!-- toggle -->
|
||||||
<div class="relative ml-2">
|
<div v-if="hasSearchBox" class="relative ml-2">
|
||||||
<!-- input -->
|
<!-- input -->
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
@@ -46,26 +56,32 @@
|
|||||||
class="dot absolute left-1 top-1 bg-slate-400 w-6 h-6 rounded-full transition"
|
class="dot absolute left-1 top-1 bg-slate-400 w-6 h-6 rounded-full transition"
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else class="relative ml-2">
|
||||||
|
<button class="ml-2 px-4 py-2 rounded-md bg-blue-200 text-blue-500">
|
||||||
|
Select Location
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<div class="grid grid-cols-1 sm:grid-cols-3 gap-2 mt-4">
|
||||||
class="block w-full text-center text-lg font-bold uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md mt-4"
|
|
||||||
@click="confirm"
|
|
||||||
>
|
|
||||||
Apply
|
|
||||||
</button>
|
|
||||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2 mt-2">
|
|
||||||
<button
|
<button
|
||||||
class="block w-full text-center text-md uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md"
|
class="block w-full text-center text-md uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md"
|
||||||
|
@click="setAll()"
|
||||||
|
>
|
||||||
|
Set All
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="block w-full text-center text-md uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md"
|
||||||
|
@click="clearAll()"
|
||||||
>
|
>
|
||||||
Clear All
|
Clear All
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
class="block w-full text-center text-md uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md"
|
class="block w-full text-center text-md uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md"
|
||||||
@click="cancel"
|
@click="done()"
|
||||||
>
|
>
|
||||||
Cancel
|
Done
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -81,6 +97,9 @@ import {
|
|||||||
LTileLayer,
|
LTileLayer,
|
||||||
} from "@vue-leaflet/vue-leaflet";
|
} from "@vue-leaflet/vue-leaflet";
|
||||||
|
|
||||||
|
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||||
|
import { db } from "@/db/index";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
LRectangle,
|
LRectangle,
|
||||||
@@ -90,20 +109,80 @@ import {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
export default class FeedFilters extends Vue {
|
export default class FeedFilters extends Vue {
|
||||||
visible = false;
|
callOnCloseIfChanged = () => {};
|
||||||
isFromMyContacts = false;
|
hasSearchBox = false;
|
||||||
|
isInMyContacts = false;
|
||||||
isNearby = false;
|
isNearby = false;
|
||||||
|
settingChanged = false;
|
||||||
|
visible = false;
|
||||||
|
|
||||||
async open() {
|
async open(callOnCloseIfChanged: () => void) {
|
||||||
|
this.callOnCloseIfChanged = callOnCloseIfChanged;
|
||||||
|
|
||||||
|
await db.open();
|
||||||
|
const settings = await db.settings.get(MASTER_SETTINGS_KEY);
|
||||||
|
this.isInMyContacts = !!settings?.filterFeedContacts;
|
||||||
|
this.isNearby = !!settings?.filterFeedNearby;
|
||||||
|
if (settings?.searchBoxes && settings.searchBoxes.length > 0) {
|
||||||
|
this.hasSearchBox = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.settingChanged = false;
|
||||||
this.visible = true;
|
this.visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleContacts() {
|
||||||
|
this.settingChanged = true;
|
||||||
|
this.isInMyContacts = !this.isInMyContacts;
|
||||||
|
db.settings.update(MASTER_SETTINGS_KEY, {
|
||||||
|
filterFeedContacts: this.isInMyContacts,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleNearby() {
|
||||||
|
this.settingChanged = true;
|
||||||
|
this.isNearby = !this.isNearby;
|
||||||
|
db.settings.update(MASTER_SETTINGS_KEY, {
|
||||||
|
filterFeedNearby: this.isNearby,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async clearAll() {
|
||||||
|
if (this.isInMyContacts || this.isNearby) {
|
||||||
|
this.settingChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
db.settings.update(MASTER_SETTINGS_KEY, {
|
||||||
|
filterFeedNearby: false,
|
||||||
|
filterFeedContacts: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.isInMyContacts = false;
|
||||||
|
this.isNearby = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async setAll() {
|
||||||
|
if (!this.isInMyContacts || !this.isNearby) {
|
||||||
|
this.settingChanged = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
db.settings.update(MASTER_SETTINGS_KEY, {
|
||||||
|
filterFeedNearby: true,
|
||||||
|
filterFeedContacts: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.isInMyContacts = true;
|
||||||
|
this.isNearby = true;
|
||||||
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
// close the dialog but don't change values (just in case some actions are added later)
|
if (this.settingChanged) {
|
||||||
|
this.callOnCloseIfChanged();
|
||||||
|
}
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel() {
|
done() {
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ export type Settings = {
|
|||||||
|
|
||||||
activeDid?: string; // Active Decentralized ID
|
activeDid?: string; // Active Decentralized ID
|
||||||
apiServer?: string; // API server URL
|
apiServer?: string; // API server URL
|
||||||
|
|
||||||
|
filterFeedNearby?: string; // filter by nearby
|
||||||
|
filterFeedContacts?: string; // filter by user contacts
|
||||||
|
|
||||||
firstName?: string; // User's first name
|
firstName?: string; // User's first name
|
||||||
isRegistered?: boolean;
|
isRegistered?: boolean;
|
||||||
lastName?: string; // deprecated - put all names in firstName
|
lastName?: string; // deprecated - put all names in firstName
|
||||||
|
|||||||
@@ -180,9 +180,9 @@
|
|||||||
<h2 class="text-xl font-bold">Latest Activity</h2>
|
<h2 class="text-xl font-bold">Latest Activity</h2>
|
||||||
<button
|
<button
|
||||||
@click="openFeedFilters()"
|
@click="openFeedFilters()"
|
||||||
class="block text-center text-sm uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-3 py-1.5 ml-auto rounded-md"
|
class="block text-center text-sm uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-3 py-1.5 ml-auto rounded-md"
|
||||||
>
|
>
|
||||||
Filter…
|
{{ resultsAreFiltered() ? "Filtered" : "Unfiltered" }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<InfiniteScroll @reached-bottom="loadMoreGives">
|
<InfiniteScroll @reached-bottom="loadMoreGives">
|
||||||
@@ -311,6 +311,8 @@ export default class HomeView extends Vue {
|
|||||||
feedPreviousOldestId?: string;
|
feedPreviousOldestId?: string;
|
||||||
feedLastViewedClaimId?: string;
|
feedLastViewedClaimId?: string;
|
||||||
isCreatingIdentifier = false;
|
isCreatingIdentifier = false;
|
||||||
|
isFeedFilteredByContacts = false;
|
||||||
|
isFeedFilteredByNearby = false;
|
||||||
isFeedLoading = true;
|
isFeedLoading = true;
|
||||||
isRegistered = false;
|
isRegistered = false;
|
||||||
showShortcutBvc = false;
|
showShortcutBvc = false;
|
||||||
@@ -335,7 +337,7 @@ export default class HomeView extends Vue {
|
|||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
async created() {
|
async mounted() {
|
||||||
try {
|
try {
|
||||||
await accountsDB.open();
|
await accountsDB.open();
|
||||||
const allAccounts = await accountsDB.accounts.toArray();
|
const allAccounts = await accountsDB.accounts.toArray();
|
||||||
@@ -347,6 +349,8 @@ export default class HomeView extends Vue {
|
|||||||
this.activeDid = settings?.activeDid || "";
|
this.activeDid = settings?.activeDid || "";
|
||||||
this.allContacts = await db.contacts.toArray();
|
this.allContacts = await db.contacts.toArray();
|
||||||
this.feedLastViewedClaimId = settings?.lastViewedClaimId;
|
this.feedLastViewedClaimId = settings?.lastViewedClaimId;
|
||||||
|
this.isFeedFilteredByContacts = !!settings?.filterFeedContacts;
|
||||||
|
this.isFeedFilteredByNearby = !!settings?.filterFeedNearby;
|
||||||
this.isRegistered = !!settings?.isRegistered;
|
this.isRegistered = !!settings?.isRegistered;
|
||||||
this.showShortcutBvc = !!settings?.showShortcutBvc;
|
this.showShortcutBvc = !!settings?.showShortcutBvc;
|
||||||
|
|
||||||
@@ -378,6 +382,10 @@ export default class HomeView extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resultsAreFiltered() {
|
||||||
|
return this.isFeedFilteredByContacts || this.isFeedFilteredByNearby;
|
||||||
|
}
|
||||||
|
|
||||||
notificationsSupported() {
|
notificationsSupported() {
|
||||||
return "Notification" in window;
|
return "Notification" in window;
|
||||||
}
|
}
|
||||||
@@ -408,6 +416,18 @@ export default class HomeView extends Vue {
|
|||||||
return headers;
|
return headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// only called when a setting was changed
|
||||||
|
async reloadFeedOnChange() {
|
||||||
|
await db.open();
|
||||||
|
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
|
||||||
|
this.isFeedFilteredByContacts = !!settings?.filterFeedContacts;
|
||||||
|
this.isFeedFilteredByNearby = !!settings?.filterFeedNearby;
|
||||||
|
|
||||||
|
this.feedData = [];
|
||||||
|
this.feedPreviousOldestId = undefined;
|
||||||
|
this.updateAllFeed();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data loader used by infinite scroller
|
* Data loader used by infinite scroller
|
||||||
* @param payload is the flag from the InfiniteScroll indicating if it should load
|
* @param payload is the flag from the InfiniteScroll indicating if it should load
|
||||||
@@ -587,7 +607,7 @@ export default class HomeView extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
openFeedFilters() {
|
openFeedFilters() {
|
||||||
(this.$refs.feedFilters as FeedFilters).open();
|
(this.$refs.feedFilters as FeedFilters).open(this.reloadFeedOnChange);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -208,9 +208,9 @@ export default class DiscoverView extends Vue {
|
|||||||
group: "alert",
|
group: "alert",
|
||||||
type: "success",
|
type: "success",
|
||||||
title: "Saved",
|
title: "Saved",
|
||||||
text: "That has been saved in your preferences.",
|
text: "That has been saved in your preferences. You can now filter by it on your home screen feed.",
|
||||||
},
|
},
|
||||||
-1,
|
7000,
|
||||||
);
|
);
|
||||||
this.$router.back();
|
this.$router.back();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@@ -246,6 +246,7 @@ export default class DiscoverView extends Vue {
|
|||||||
await db.open();
|
await db.open();
|
||||||
db.settings.update(MASTER_SETTINGS_KEY, {
|
db.settings.update(MASTER_SETTINGS_KEY, {
|
||||||
searchBoxes: [],
|
searchBoxes: [],
|
||||||
|
filterFeedNearby: false,
|
||||||
});
|
});
|
||||||
this.searchBox = null;
|
this.searchBox = null;
|
||||||
this.localCenterLat = 0;
|
this.localCenterLat = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user