diff --git a/api/resolvers/item.js b/api/resolvers/item.js
index ad420ae4..0e896e35 100644
--- a/api/resolvers/item.js
+++ b/api/resolvers/item.js
@@ -17,7 +17,7 @@ import uu from 'url-unshort'
import { actSchema, advSchema, bountySchema, commentSchema, discussionSchema, jobSchema, linkSchema, pollSchema, ssValidate } from '../../lib/validate'
import { sendUserNotification } from '../webPush'
import { defaultCommentSort, isJob, deleteItemByAuthor, getDeleteCommand, hasDeleteCommand } from '../../lib/item'
-import { notifyItemParents, notifyUserSubscribers, notifyZapped, notifyFounders } from '../../lib/push-notifications'
+import { notifyItemParents, notifyUserSubscribers, notifyZapped, notifyTerritorySubscribers } from '../../lib/push-notifications'
import { datePivot, whenRange } from '../../lib/time'
import { imageFeesInfo, uploadIdsFromText } from './image'
import assertGofacYourself from './ofac'
@@ -125,7 +125,8 @@ export async function itemQueryWithMeta ({ me, models, query, orderBy = '' }, ..
COALESCE("ItemAct"."meMsats", 0) as "meMsats",
COALESCE("ItemAct"."meDontLikeMsats", 0) as "meDontLikeMsats", b."itemId" IS NOT NULL AS "meBookmark",
"ThreadSubscription"."itemId" IS NOT NULL AS "meSubscription", "ItemForward"."itemId" IS NOT NULL AS "meForward",
- to_jsonb("Sub".*) || jsonb_build_object('meMuteSub', "MuteSub"."userId" IS NOT NULL) as sub
+ to_jsonb("Sub".*) || jsonb_build_object('meMuteSub', "MuteSub"."userId" IS NOT NULL)
+ || jsonb_build_object('meSubscription', "SubSubscription"."userId" IS NOT NULL) as sub
FROM (
${query}
) "Item"
@@ -136,6 +137,7 @@ export async function itemQueryWithMeta ({ me, models, query, orderBy = '' }, ..
LEFT JOIN "ItemForward" ON "ItemForward"."itemId" = "Item".id AND "ItemForward"."userId" = ${me.id}
LEFT JOIN "Sub" ON "Sub"."name" = "Item"."subName"
LEFT JOIN "MuteSub" ON "Sub"."name" = "MuteSub"."subName" AND "MuteSub"."userId" = ${me.id}
+ LEFT JOIN "SubSubscription" ON "Sub"."name" = "SubSubscription"."subName" AND "SubSubscription"."userId" = ${me.id}
LEFT JOIN LATERAL (
SELECT "itemId", sum("ItemAct".msats) FILTER (WHERE act = 'FEE' OR act = 'TIP') AS "meMsats",
sum("ItemAct".msats) FILTER (WHERE act = 'DONT_LIKE_THIS') AS "meDontLikeMsats"
@@ -1340,7 +1342,7 @@ export const createItem = async (parent, { forward, options, ...item }, { me, mo
notifyUserSubscribers({ models, item })
- notifyFounders({ models, item })
+ notifyTerritorySubscribers({ models, item })
item.comments = []
return item
diff --git a/api/resolvers/notifications.js b/api/resolvers/notifications.js
index 86e4b6f6..36d83658 100644
--- a/api/resolvers/notifications.js
+++ b/api/resolvers/notifications.js
@@ -107,16 +107,20 @@ export default {
LIMIT ${LIMIT}+$3`
)
- if (meFull.noteTerritoryPosts) {
- itemDrivenQueries.push(
- `SELECT "Item".*, "Item".created_at AS "sortTime", 'TerritoryPost' AS type
- FROM "Item"
- JOIN "Sub" ON "Item"."subName" = "Sub".name
- WHERE "Sub"."userId" = $1 AND "Item"."userId" <> $1
- ORDER BY "sortTime" DESC
- LIMIT ${LIMIT}+$3`
- )
- }
+ // Territory subscriptions
+ itemDrivenQueries.push(
+ `SELECT "Item".*, "Item".created_at AS "sortTime", 'TerritoryPost' AS type
+ FROM "Item"
+ JOIN "SubSubscription" ON "Item"."subName" = "SubSubscription"."subName"
+ ${whereClause(
+ '"SubSubscription"."userId" = $1',
+ '"Item"."userId" <> $1',
+ '"Item"."parentId" IS NULL',
+ '"Item".created_at >= "SubSubscription".created_at'
+ )}
+ ORDER BY "sortTime" DESC
+ LIMIT ${LIMIT}+$3`
+ )
// mentions
if (meFull.noteMentions) {
diff --git a/api/resolvers/sub.js b/api/resolvers/sub.js
index 048b3713..189d4560 100644
--- a/api/resolvers/sub.js
+++ b/api/resolvers/sub.js
@@ -259,6 +259,22 @@ export default {
await models.muteSub.create({ data: { ...lookupData } })
return true
}
+ },
+ toggleSubSubscription: async (sub, { name }, { me, models }) => {
+ if (!me) {
+ throw new GraphQLError('you must be logged in', { extensions: { code: 'UNAUTHENTICATED' } })
+ }
+
+ const lookupData = { userId: me.id, subName: name }
+ const where = { userId_subName: lookupData }
+ const existing = await models.subSubscription.findUnique({ where })
+ if (existing) {
+ await models.subSubscription.delete({ where })
+ return false
+ } else {
+ await models.subSubscription.create({ data: lookupData })
+ return true
+ }
}
},
Sub: {
@@ -281,6 +297,9 @@ export default {
if (typeof sub.ncomments !== 'undefined') {
return sub.ncomments
}
+ },
+ meSubscription: async (sub, args, { me, models }) => {
+ return sub.meSubscription || sub.SubSubscription?.length > 0
}
}
}
@@ -331,6 +350,13 @@ async function createSub (parent, data, { me, models, lnd, hash, hmac }) {
msats: cost,
type: 'BILLING'
}
+ }),
+ // notify 'em (in the future)
+ models.subSubscription.create({
+ data: {
+ userId: me.id,
+ subName: data.name
+ }
})
], { models, lnd, hash, hmac, me, enforceFee: billingCost })
diff --git a/api/typeDefs/sub.js b/api/typeDefs/sub.js
index 66615a02..99b6e39b 100644
--- a/api/typeDefs/sub.js
+++ b/api/typeDefs/sub.js
@@ -21,6 +21,7 @@ export default gql`
moderated: Boolean!, hash: String, hmac: String, nsfw: Boolean!): Sub
paySub(name: String!, hash: String, hmac: String): Sub
toggleMuteSub(name: String!): Boolean!
+ toggleSubSubscription(name: String!): Boolean!
}
type Sub {
@@ -46,6 +47,7 @@ export default gql`
nsfw: Boolean!
nposts(when: String, from: String, to: String): Int!
ncomments(when: String, from: String, to: String): Int!
+ meSubscription: Boolean!
optional: SubOptional!
}
diff --git a/api/typeDefs/user.js b/api/typeDefs/user.js
index 488f2243..8b808a51 100644
--- a/api/typeDefs/user.js
+++ b/api/typeDefs/user.js
@@ -73,7 +73,6 @@ export default gql`
nostrPubkey: String
nostrRelays: [String!]
noteAllDescendants: Boolean!
- noteTerritoryPosts: Boolean!
noteCowboyHat: Boolean!
noteDeposits: Boolean!
noteEarning: Boolean!
@@ -136,7 +135,6 @@ export default gql`
nostrPubkey: String
nostrRelays: [String!]
noteAllDescendants: Boolean!
- noteTerritoryPosts: Boolean!
noteCowboyHat: Boolean!
noteDeposits: Boolean!
noteEarning: Boolean!
diff --git a/api/webPush/index.js b/api/webPush/index.js
index c59ba84b..a380a03f 100644
--- a/api/webPush/index.js
+++ b/api/webPush/index.js
@@ -35,7 +35,6 @@ const createUserFilter = (tag) => {
// filter users by notification settings
const tagMap = {
REPLY: 'noteAllDescendants',
- TERRITORY_POST: 'noteTerritoryPosts',
MENTION: 'noteMentions',
TIP: 'noteItemSats',
FORWARDEDTIP: 'noteForwardedSats',
diff --git a/components/territory-header.js b/components/territory-header.js
index d98f70de..5617802c 100644
--- a/components/territory-header.js
+++ b/components/territory-header.js
@@ -10,6 +10,7 @@ import { useMe } from './me'
import Share from './share'
import { gql, useMutation } from '@apollo/client'
import { useToast } from './toast'
+import ActionDropdown from './action-dropdown'
export function TerritoryDetails ({ sub }) {
return (
@@ -79,7 +80,7 @@ export default function TerritoryHeader ({ sub }) {