diff --git a/websites/T/Typersguild/metadata.json b/websites/T/Typersguild/metadata.json new file mode 100644 index 000000000000..27d05d3d4d10 --- /dev/null +++ b/websites/T/Typersguild/metadata.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://schemas.premid.app/metadata/1.16", + "apiVersion": 1, + "author": { + "id": "620949166604156955", + "name": "heydathan" + }, + "service": "Typersguild", + "description": { + "en": "Practice typing by retyping entire books. Improve your speed with 100+ classics and real-time WPM tracking" + }, + "url": "typersguild.com", + "regExp": "^https?[:][/][/]([a-z0-9-]+[.])*typersguild[.]com[/]", + "version": "1.0.0", + "logo": "https://typersguild.com/android-chrome-512x512.png", + "thumbnail": "https://typersguild.com/books.webp", + "color": "#6366f1", + "category": "other", + "tags": [ + "typing", + "books", + "learning", + "productivity", + "practice", + "speed", + "reading", + "education" + ] +} diff --git a/websites/T/Typersguild/presence.ts b/websites/T/Typersguild/presence.ts new file mode 100644 index 000000000000..b44fbbe8ab51 --- /dev/null +++ b/websites/T/Typersguild/presence.ts @@ -0,0 +1,107 @@ +import { StatusDisplayType } from 'premid' + +const presence = new Presence({ + clientId: '1459578800223420416', +}) + +const browsingTimestamp = Math.floor(Date.now() / 1000) + +enum ActivityAssets { + Logo = 'https://typersguild.com/android-chrome-512x512.png', +} + +enum ContentType { + Book = 'book', + Wiki = 'wiki', + Browsing = 'browsing', +} + +enum ActivityStates { + Typing = 'Typing on Typersguild', + Browsing = 'Browsing', +} + +function getBookName(): string { + const presenceName = document + .querySelector('[data-presence-book-name]') + ?.getAttribute('data-presence-book-name') + ?.trim() + + return presenceName || 'a book' +} + +function getBookAuthor(): string { + const authorName = document + .querySelector('[data-presence-book-author]') + ?.getAttribute('data-presence-book-author') + ?.trim() + + return authorName || 'Unknown Author' +} + +function getBookCover(): string | null { + const coverUrl = document + .querySelector('[data-presence-book-cover]') + ?.getAttribute('data-presence-book-cover') + ?.trim() + + return coverUrl || null +} + +function getContentType(path: string): ContentType { + if (/^\/books\/[^/]+\/chapter\/\d+/.test(path)) { + return ContentType.Book + } + + if (/^\/my-books\/[^/]+\/chapter\/\d+/.test(path)) { + return ContentType.Book + } + + if (/^\/wiki\/[^/]+\/[^/]+/.test(path)) { + return ContentType.Wiki + } + + return ContentType.Browsing +} + +presence.on('UpdateData', async () => { + const { pathname } = document.location + const contentType = getContentType(pathname) + + const presenceData: PresenceData = { + statusDisplayType: StatusDisplayType.Name, + largeImageKey: ActivityAssets.Logo, + largeImageUrl: 'https://typersguild.com/books', + stateUrl: 'https://typersguild.com/books', + startTimestamp: browsingTimestamp, + } + + switch (contentType) { + case ContentType.Book: + { const bookCover = getBookCover() + if (bookCover) + presenceData.largeImageKey = bookCover + + presenceData.name = getBookName() + presenceData.details = `by ${getBookAuthor()}` + presenceData.state = ActivityStates.Typing + break + } + case ContentType.Wiki: + presenceData.name = getBookName() + presenceData.details = 'Wikipedia' + presenceData.state = ActivityStates.Typing + break + case ContentType.Browsing: + presenceData.details = 'Books, Wikis, and more' + presenceData.state = ActivityStates.Browsing + break + } + + if (presenceData.state) { + presence.setActivity(presenceData) + } + else { + presence.clearActivity() + } +})