diff --git a/api/resolvers/sub.js b/api/resolvers/sub.js index 8a5c09e9..f68c6909 100644 --- a/api/resolvers/sub.js +++ b/api/resolvers/sub.js @@ -1,11 +1,34 @@ export default { Query: { - sub: async (parent, { name }, { models }) => { + sub: async (parent, { name }, { models, me }) => { + if (me && name === 'jobs') { + models.user.update({ + where: { + id: me.id + }, + data: { + lastCheckedJobs: new Date() + } + }).catch(console.log) + } + return await models.sub.findUnique({ where: { name } }) + }, + subLatestPost: async (parent, { name }, { models, me }) => { + const latest = await models.item.findFirst({ + where: { + subName: name + }, + orderBy: { + createdAt: 'desc' + } + }) + + return latest.createdAt } } } diff --git a/api/typeDefs/sub.js b/api/typeDefs/sub.js index 3cc115ef..9e1ad04c 100644 --- a/api/typeDefs/sub.js +++ b/api/typeDefs/sub.js @@ -3,6 +3,7 @@ import { gql } from 'apollo-server-micro' export default gql` extend type Query { sub(name: ID!): Sub + subLatestPost(name: ID!): String } type Sub { diff --git a/api/typeDefs/user.js b/api/typeDefs/user.js index 83404857..701e3605 100644 --- a/api/typeDefs/user.js +++ b/api/typeDefs/user.js @@ -29,7 +29,7 @@ export default gql` setName(name: String!): Boolean setSettings(tipDefault: Int!, noteItemSats: Boolean!, noteEarning: Boolean!, noteAllDescendants: Boolean!, noteMentions: Boolean!, noteDeposits: Boolean!, - noteInvites:Boolean!): Boolean + noteInvites: Boolean!, noteJobIndicator: Boolean!): Boolean upsertBio(bio: String!): User! setWalkthrough(tipPopover: Boolean, upvotePopover: Boolean): Boolean } @@ -57,5 +57,7 @@ export default gql` noteMentions: Boolean! noteDeposits: Boolean! noteInvites: Boolean! + noteJobIndicator: Boolean! + lastCheckedJobs: String } ` diff --git a/components/header.js b/components/header.js index da953045..6847c6f5 100644 --- a/components/header.js +++ b/components/header.js @@ -13,6 +13,7 @@ import { useEffect, useState } from 'react' import { randInRange } from '../lib/rand' import { formatSats } from '../lib/format' import NoteIcon from '../svgs/notification-4-fill.svg' +import { useQuery, gql } from '@apollo/client' function WalletSummary ({ me }) { if (!me) return null @@ -26,6 +27,23 @@ export default function Header ({ sub }) { const [fired, setFired] = useState() const me = useMe() const prefix = sub ? `/~${sub}` : '' + const { data: subLatestPost } = useQuery(gql` + query subLatestPost($name: ID!) { + subLatestPost(name: $name) + } + `, { variables: { name: 'jobs' }, pollInterval: 600000, fetchPolicy: 'network-only' }) + + const [lastCheckedJobs, setLastCheckedJobs] = useState(new Date().getTime()) + useEffect(() => { + if (me) { + setLastCheckedJobs(me.lastCheckedJobs) + } else { + if (sub === 'jobs') { + localStorage.setItem('lastCheckedJobs', new Date().getTime()) + } + setLastCheckedJobs(localStorage.getItem('lastCheckedJobs')) + } + }) const Corner = () => { if (me) { @@ -103,6 +121,43 @@ export default function Header ({ sub }) { } } + const NavItems = ({ className }) => { + return ( + <> + + + recent + + + {!prefix && + + + top + + } + +
+ + + jobs + + + {sub !== 'jobs' && (!me || me.noteJobIndicator) && (!lastCheckedJobs || lastCheckedJobs < subLatestPost?.subLatestPost) && + + {' '} + } +
+
+ {me && + + + post + + } + + ) + } + return ( <> @@ -123,28 +178,7 @@ export default function Header ({ sub }) { - - - recent - - - {!prefix && - - - top - - } - - - jobs - - - {me && - - - post - - } + 6 ? 'd-none d-lg-flex' : ''}`}> @@ -156,28 +190,7 @@ export default function Header ({ sub }) { className={`${styles.navbarNav} justify-content-around`} activeKey={path} > - - - recent - - - {!prefix && - - - top - - } - - - jobs - - - {me && - - - post - - } + diff --git a/components/header.module.css b/components/header.module.css index 174c8e2b..c8d5ed59 100644 --- a/components/header.module.css +++ b/components/header.module.css @@ -27,6 +27,15 @@ fill: var(--theme-navLinkActive); } +.jobIndicator { + position: absolute; + padding: .25rem; + background-color: var(--primary); + top: 3px; + right: 0px; + border: 1px solid var(--theme-body); +} + .notification { position: absolute; padding: .25rem; diff --git a/fragments/users.js b/fragments/users.js index fae6ca29..51343d51 100644 --- a/fragments/users.js +++ b/fragments/users.js @@ -23,6 +23,8 @@ export const ME = gql` noteMentions noteDeposits noteInvites + noteJobIndicator + lastCheckedJobs } }` @@ -45,6 +47,8 @@ export const ME_SSR = gql` noteMentions noteDeposits noteInvites + noteJobIndicator + lastCheckedJobs } }` diff --git a/pages/settings.js b/pages/settings.js index ca4eceb9..831c57d6 100644 --- a/pages/settings.js +++ b/pages/settings.js @@ -21,10 +21,11 @@ export default function Settings () { gql` mutation setSettings($tipDefault: Int!, $noteItemSats: Boolean!, $noteEarning: Boolean!, $noteAllDescendants: Boolean!, $noteMentions: Boolean!, $noteDeposits: Boolean!, - $noteInvites: Boolean!) { + $noteInvites: Boolean!, $noteJobIndicator: Boolean!) { setSettings(tipDefault: $tipDefault, noteItemSats: $noteItemSats, noteEarning: $noteEarning, noteAllDescendants: $noteAllDescendants, - noteMentions: $noteMentions, noteDeposits: $noteDeposits, noteInvites: $noteInvites) + noteMentions: $noteMentions, noteDeposits: $noteDeposits, noteInvites: $noteInvites, + noteJobIndicator: $noteJobIndicator) }` ) @@ -39,7 +40,8 @@ export default function Settings () { noteAllDescendants: me?.noteAllDescendants, noteMentions: me?.noteMentions, noteDeposits: me?.noteDeposits, - noteInvites: me?.noteInvites + noteInvites: me?.noteInvites, + noteJobIndicator: me?.noteJobIndicator }} schema={SettingsSchema} onSubmit={async ({ tipDefault, ...values }) => { @@ -84,6 +86,11 @@ export default function Settings () { +
saturday newsletter
diff --git a/prisma/migrations/20220508141357_jobs_indicator/migration.sql b/prisma/migrations/20220508141357_jobs_indicator/migration.sql new file mode 100644 index 00000000..03c887de --- /dev/null +++ b/prisma/migrations/20220508141357_jobs_indicator/migration.sql @@ -0,0 +1,3 @@ +-- AlterTable +ALTER TABLE "users" ADD COLUMN "lastCheckedJobs" TIMESTAMP(3), +ADD COLUMN "noteJobIndicator" BOOLEAN NOT NULL DEFAULT true; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 7af988e4..0c40c252 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -11,34 +11,35 @@ generator client { } model User { - id Int @id @default(autoincrement()) - createdAt DateTime @default(now()) @map(name: "created_at") - updatedAt DateTime @default(now()) @updatedAt @map(name: "updated_at") - name String? @unique @db.Citext - email String? @unique - emailVerified DateTime? @map(name: "email_verified") - image String? - items Item[] @relation("UserItems") - fwdItems Item[] @relation("FwdItem") - mentions Mention[] - messages Message[] - actions ItemAct[] - invoices Invoice[] - withdrawls Withdrawl[] - invites Invite[] @relation(name: "Invites") - invite Invite? @relation(fields: [inviteId], references: [id]) - inviteId String? - bio Item? @relation(fields: [bioId], references: [id]) - bioId Int? - msats Int @default(0) - stackedMsats Int @default(0) - freeComments Int @default(5) - freePosts Int @default(2) - checkedNotesAt DateTime? - tipDefault Int @default(10) - pubkey String? @unique - trust Float @default(0) - lastSeenAt DateTime? + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) @map(name: "created_at") + updatedAt DateTime @default(now()) @updatedAt @map(name: "updated_at") + name String? @unique @db.Citext + email String? @unique + emailVerified DateTime? @map(name: "email_verified") + image String? + items Item[] @relation("UserItems") + fwdItems Item[] @relation("FwdItem") + mentions Mention[] + messages Message[] + actions ItemAct[] + invoices Invoice[] + withdrawls Withdrawl[] + invites Invite[] @relation(name: "Invites") + invite Invite? @relation(fields: [inviteId], references: [id]) + inviteId String? + bio Item? @relation(fields: [bioId], references: [id]) + bioId Int? + msats Int @default(0) + stackedMsats Int @default(0) + freeComments Int @default(5) + freePosts Int @default(2) + checkedNotesAt DateTime? + tipDefault Int @default(10) + pubkey String? @unique + trust Float @default(0) + lastSeenAt DateTime? + lastCheckedJobs DateTime? upvotePopover Boolean @default(false) tipPopover Boolean @default(false) @@ -50,6 +51,7 @@ model User { noteMentions Boolean @default(true) noteDeposits Boolean @default(true) noteInvites Boolean @default(true) + noteJobIndicator Boolean @default(true) Earn Earn[] @@index([createdAt])