Files
Reddit-Widget/Reddit Widget.scriptable
T
2022-04-30 18:18:54 +02:00

12 lines
20 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"always_run_in_app" : false,
"icon" : {
"color" : "red",
"glyph" : "robot"
},
"name" : "Reddit Widget 1",
"script" : "\n\/\/ =========== CONFIG ===========\nconst USERNAME = 'xyz-1234'\/\/without 'u\/'\nconst PASSWORD = 'xyz-1234'\n\nconst CLIENT_ID = 'xyz-1234'\nconst CLIENT_SECRET = 'xyz-1234'\n\nconst showNotifyBadge = true \/\/smallwidget\nconst showCoinBalance = true \/\/smallwidget, mediumwidget\nconst showCakedayConfetti = true \/\/smallwidget, mediumwidget\nconst showUserTitle = true \/\/mediumwidget, largewidget\nconst cornerRadiusProfileImg = 0 \/\/Set this to +50 for a rounded Image\nconst standardRedditClient = 'Apollo'\/\/ Apollo or Reddit\n\/\/ ==============================\n\nconst widgetSize = config.widgetFamily;\nconst df = new DateFormatter()\n df.dateFormat = 'MMMM dd, yyyy'\n\nconst txtBGColor = Color.dynamic(new Color('#D5D7DCA6'), new Color('#242424A6'))\nconst txtColor = Color.dynamic(Color.black(), Color.white());\n \nconst top = Color.dynamic(new Color('#ffffff'), new Color('#0F2D60'));\nconst middle = Color.dynamic(new Color('#EDEDED'), new Color('#000427'));\nconst bottom = Color.dynamic(new Color('#D4D4D4'), new Color('#000000'));\nconst bgGradient = new LinearGradient()\n bgGradient.locations = [0, 0.4, 1]\n bgGradient.colors = [top, middle, bottom]\n \nconst appIcon = {\nReddit: 'https:\/\/is5-ssl.mzstatic.com\/image\/thumb\/Purple126\/v4\/e8\/a6\/65\/e8a66539-19c0-2748-3f7d-2b0797ca602d\/source\/512x512bb.png',\nApollo: 'https:\/\/is2-ssl.mzstatic.com\/image\/thumb\/Purple126\/v4\/d8\/d8\/f4\/d8d8f4a8-41fb-4cef-2167-0d3589c25b5d\/source\/512x512bb.png'}\n'shortcut for downloading app icons from app-store: https:\/\/routinehub.co\/shortcut\/11635\/'\n\n\/\/ GET ACCESS-TOKEN FOR JSON API REQUEST\nlet reqToken = new Request('https:\/\/www.reddit.com\/api\/v1\/access_token')\n reqToken.method = 'POST'\n reqToken.headers = {'Authorization': 'Basic ' + btoa(CLIENT_ID + \":\" + CLIENT_SECRET)}\n reqToken.body = `grant_type=password&username=${USERNAME}&password=${PASSWORD}`\n\nlet resToken = await reqToken.loadJSON()\n\/\/console.warn(JSON.stringify(resToken, null, 2))\n\n\/\/ GET USER-PROFILE JSON FROM API\/V1\/ME\nlet myReq = new Request('https:\/\/oauth.reddit.com\/api\/v1\/me')\n myReq.headers = {\n 'User-Agent': 'getKarmaForHRB7\/v1.0',\/\/The User-Agent content has no effect. You can write whatever you want here (e.g. 'ABC-123-XYZ-idk')\n 'Authorization': `${resToken.token_type} ${resToken.access_token}`\n }\n\nlet data = await myReq.loadJSON()\n\/\/console.warn(JSON.stringify(data, null, 2))\n\nvar wParameter = await args.widgetParameter\n if (wParameter == null) {\n refresh = 60\n iconURL = appIcon.Reddit\n profileURL = `https:\/\/reddit.com\/user\/${USERNAME}`\n} else if (wParameter.match(\/reddit\/i)) {\n wParameter.split(';')\n refresh = wParameter[1]\n iconURL = appIcon.Apollo\n profileURL = `apollo:\/\/reddit.com\/user\/${USERNAME}`\n} else if (wParameter.match(\/apollo\/i)) {\n wParameter.split(';')\n refresh = wParameter[1]\n iconURL = appIcon.Apollo\n profileURL = `apollo:\/\/reddit.com\/user\/${USERNAME}`\n}\n\n\/\/ CALC THE TIME SINCE CREATING ACCOUNT\nfunction minutesDiff() {\n let created = new Date(data.created*1000).getTime()\n let now = new Date(Date.now()).getTime()\n let minutesDiff = Math.floor((now - created) \/ 1000 \/ 60)\n return minutesDiff\n}\n\nif (minutesDiff() < 525600) { \/\/525600min = one year\n since = Math.abs(minutesDiff()\/60\/24).toFixed(0)\n time = \" d\"\n} else {\n since = Math.abs(minutesDiff()\/60\/24\/7\/4\/12).toFixed(1)\n time = \" y\"\n}\n\n\/\/ FORMATING NUMBERS\nvar arr = [data.total_karma, data.link_karma, data.comment_karma, data.awarder_karma, data.awardee_karma, data.coins];\n\narr.forEach((item, index) => {\n arr[index] = Intl.NumberFormat('de-DE').format(item).toString(2)\/\/de-DE: 1000=1.000; en-GB: 1000=1,000;\n if (item >= 1_000_000) {\n arr[index] += 'M'\n} else if (item >= 1_000) {\n arr[index] += 'k'\n }\n});\n\n\/\/ DECLARE VARIABLES\nvar totalKarma = arr[0];\nvar postKarma = arr[1];\nvar commentKarma = arr[2];\nvar awarderKarma = arr[3];\nvar awardeeKarma = arr[4];\nvar rCoins = arr[5];\nvar profileImg = data.icon_img.split('?')\nvar bannerImg = data.subreddit.banner_img.split('?')\nvar userName = data.subreddit.display_name_prefixed\nvar userTitle = data.subreddit.title\nvar puplicDescription = data.subreddit.public_description\nvar goldExpiration = data.gold_expiration \/\/End of Reddit Premium\nvar isGold = data.is_gold \/\/might be a gold membership\nvar inboxCount = data.inbox_count \/\/post inbox\nvar dateCreated = df.string(new Date(data.created*1000))\/\/date of creating account\nvar accountAge = since + time\n\n\/\/ GET IMAGES FROM GITHUB OR ICLOUD\nconst fm = FileManager.iCloud()\nconst dir = fm.joinPath(fm.documentsDirectory(), \"Reddit-Widget\")\nconst imgURL = 'https:\/\/raw.githubusercontent.com\/iamrbn\/Reddit-Widget\/main\/Images\/'\nasync function saveImages() {\n console.log(\"loading & saving images\")\n var imgs = [\"karma.png\", \"coins.png\", \"cakedayConfetti.png\", \"cakedayApollo.png\"]\/\/, \"coins2.png\", \"cakedayReddit.png\"]\/\/alternative symbols\n for(img of imgs) {\n let imgPath = fm.joinPath(dir, img);\n if(!fm.fileExists(imgPath)) {\n console.log(\"Loading image: \" + img)\n let request = new Request(imgURL + img);\n image = await request.loadImage();\n fm.writeImage(imgPath, image);\n }\n }\n}\n\nasync function getImageFor(name) {\n let imgPath = fm.joinPath(dir, name + \".png\")\n await fm.downloadFileFromiCloud(imgPath)\n img = await fm.readImage(imgPath)\n return img\n}\n\n\n\/\/ ******** CREATE SMALL WIDGET *********\nasync function createSmallWidget(data) {\n var refreshDate = Date.now() + 1000*60*refresh\n let widget = new ListWidget()\n widget.setPadding(7, 7, 4, 7)\n widget.url = profileURL\n widget.refreshAfterDate = new Date(refreshDate)\n if (df.string(new Date()).slice(0, -4) == dateCreated.slice(0, -4) && showCakedayConfetti) {\n userName += ' 🍰 '\n widget.backgroundImage = await getImageFor(\"cakedayConfetti\")\n} else if (df.string(new Date()).slice(0, -4) == dateCreated.slice(0, -4) && !showCakedayConfetti) {\n userName += ' 🍰 '\n widget.backgroundGradient = bgGradient\n } else {\n widget.backgroundGradient = bgGradient\n }\n \n widget.addSpacer(5)\n \n let mainHeaderStack = widget.addStack()\n \n \/\/Left Header\n let leftMainHeaderStack = mainHeaderStack.addStack()\n leftMainHeaderStack.backgroundColor = txtBGColor\n leftMainHeaderStack.cornerRadius = 11\n leftMainHeaderStack.setPadding(0, 5, 4, 6)\n \n let leftHeaderStackL = leftMainHeaderStack.addStack()\n leftHeaderStackL.layoutVertically()\n leftHeaderStackL.setPadding(5, 0, 0, 0)\n \n let rightHeaderStackL = leftMainHeaderStack.addStack()\n rightHeaderStackL.layoutVertically()\n rightHeaderStackL.setPadding(4, 5, 0, 0)\n \n let rightMainHeaderStack = mainHeaderStack.addStack()\n \n \/\/Header Right\n let leftHeaderStackR = rightMainHeaderStack.addStack()\n leftHeaderStackR.layoutVertically()\n \n let rightHeaderStackR = rightMainHeaderStack.addStack()\n rightHeaderStackR.layoutVertically()\n rightHeaderStackR.cornerRadius = 6 \n\n let appIcon = await loadAppIcon();\n let appIconElement = leftHeaderStackL.addImage(appIcon)\n appIconElement.imageSize = new Size(30, 30);\n appIconElement.cornerRadius = 6\n appIconElement.centerAlignImage()\n \n widget.addSpacer(5)\n leftMainHeaderStack.addSpacer(5)\n \n let wTitle = rightHeaderStackL.addText('Reddit')\n wTitle.font = Font.blackSystemFont(14)\n wTitle.textColor = txtColor\n wTitle.centerAlignText()\n \n if (userName.length > 13) {\n let wSubtitle = rightHeaderStackL.addText(userName)\n wSubtitle.font = Font.lightSystemFont(12)\n wSubtitle.textColor = txtColor\n wSubtitle.centerAlignText()\n wSubtitle.minimumScaleFactor = 0.8\n wSubtitle.lineLimit = 1\n} else {\n wSubtitle = rightHeaderStackL.addText(userName)\n wSubtitle.font = Font.lightSystemFont(12)\n wSubtitle.textColor = txtColor\n wSubtitle.centerAlignText()\n wSubtitle.minimumScaleFactor = 0.9\n wSubtitle.lineLimit = 1\n }\n \n if (showNotifyBadge && inboxCount > 0) {\n let badgeSymbol = SFSymbol.named(`${inboxCount}.circle`)\n let badgeSymbolElement = rightHeaderStackR.addImage(badgeSymbol.image)\n badgeSymbolElement.imageSize = new Size(15, 15)\n badgeSymbolElement.tintColor = Color.red()\n }\n \n widget.addSpacer(4)\n \n let mainStack = widget.addStack()\n mainStack.backgroundColor = txtBGColor\n mainStack.layoutVertically()\n mainStack.cornerRadius = 11\n mainStack.setPadding(5, 5, 5, 25)\n\n let lineOneStack = mainStack.addStack()\n lineOneStack.setPadding(0, 0, 0, 0)\n lineOneStack.centerAlignContent()\n \n let bodyTxt = mainStack.addStack()\n bodyTxt.layoutVertically()\n bodyTxt.setPadding(0, 0, 0, 0)\n \n let karmaImage = lineOneStack.addImage(await getImageFor(\"karma\"))\n karmaImage.imageSize = new Size(14, 14)\n \n lineOneStack.addSpacer(5)\n \n let karmaTxt = lineOneStack.addText(totalKarma)\n karmaTxt.font = Font.lightRoundedSystemFont(11)\n karmaTxt.textColor = txtColor\n\nif (showCoinBalance) {\n lineOneStack.addSpacer(4)\n let line = lineOneStack.addText('|')\n line.font = Font.lightRoundedSystemFont(11)\n line.textColor = txtColor\n line.textOpacity = 0.5\n lineOneStack.addSpacer(4)\n let coinsImage = lineOneStack.addImage(await getImageFor(\"coins\"))\n coinsImage.imageSize = new Size(12, 12)\n lineOneStack.addSpacer(5)\n let coinsTxt = lineOneStack.addText(rCoins)\n coinsTxt.font = Font.lightRoundedSystemFont(11)\n coinsTxt.textColor = txtColor\n}\n\n bodyTxt.addSpacer(3)\n \n let line3 = bodyTxt.addText(\"Post Karma: \" + postKarma)\n line3.font = Font.lightRoundedSystemFont(11)\n line3.textColor = txtColor\n \n let line4 = bodyTxt.addText(\"Comment Karma: \" + commentKarma)\n line4.font = Font.lightRoundedSystemFont(11)\n line4.textColor = txtColor\n \n let line5 = bodyTxt.addText(\"Awarder Karma: \" + awarderKarma)\n line5.font = Font.lightRoundedSystemFont(11)\n line5.textColor = txtColor\n \n let line6 = bodyTxt.addText(\"Awardee Karma: \" + awardeeKarma)\n line6.font = Font.lightRoundedSystemFont(11)\n line6.textColor = txtColor\n \n widget.addSpacer(5)\n \n df.useShortTimeStyle()\n let footer = widget.addText(\"Last Refresh \" + df.string(new Date()))\n footer.font = Font.mediumSystemFont(8);\n footer.textOpacity = 0.4\n footer.centerAlignText()\n \n return widget\n}\n\n\n\/\/********** CEEATE MEDIUM WIDGET *********\nasync function createMediumWidget(data) {\n var refreshDate = Date.now() + 1000*60*refresh\n let widget = new ListWidget()\n widget.setPadding(15, 15, 3, 15)\n widget.refreshAfterDate = new Date(refreshDate)\n \n if (df.string(new Date()).slice(0, -4) == dateCreated.slice(0, -4) && showCakedayConfetti) {\n userName += ' 🍰 '\n widget.backgroundImage = await getImageFor(\"cakedayConfetti\")\n} else if (df.string(new Date()).slice(0, -4) == dateCreated.slice(0, -4) && !showCakedayConfetti) {\n userName += ' 🍰 '\n widget.backgroundGradient = bgGradient\n } else {\n widget.backgroundGradient = bgGradient\n }\n\n let widgetStack = widget.addStack()\n widgetStack.setPadding(0, 0, 0, -15)\n \n let widgetStackL = widgetStack.addStack()\n widgetStackL.setPadding(0, 0, 0, 0)\n widgetStackL.layoutVertically()\n \n let mainHeaderStackLeft = widgetStackL.addStack()\n mainHeaderStackLeft.backgroundColor = txtBGColor\n mainHeaderStackLeft.setPadding(3, 5, 2, 7)\n mainHeaderStackLeft.cornerRadius = 10\n mainHeaderStackLeft.url = profileURL\n \n let leftHeaderStack = mainHeaderStackLeft.addStack()\n leftHeaderStack.layoutVertically()\n \n let rightHeaderStack = mainHeaderStackLeft.addStack()\n rightHeaderStack.layoutVertically()\n rightHeaderStack.setPadding(0, 5, 0, 0)\n \n let appIcon = await loadAppIcon();\n let appIconElement = leftHeaderStack.addImage(appIcon)\n appIconElement.imageSize = new Size(31, 31);\n appIconElement.cornerRadius = 7\n \n let wTitle = rightHeaderStack.addText('Reddit')\n wTitle.font = Font.blackSystemFont(15)\n wTitle.textColor = txtColor\n wTitle.centerAlignText()\n \n if (showUserTitle && userTitle != '') {\n let wSubtitle = rightHeaderStack.addText(userName + ' - ' + userTitle)\n wSubtitle.font = Font.lightSystemFont(12)\n wSubtitle.textColor = txtColor\n spacer = 0\n} else if (!showUserTitle || userTitle == \"\") {\n let wSubtitle = rightHeaderStack.addText(userName)\n wSubtitle.font = Font.lightSystemFont(12)\n wSubtitle.textColor = txtColor\n spacer = 70\n }\n \n let leftTextStack = widgetStackL.addStack()\n leftTextStack.layoutVertically()\n leftTextStack.setPadding(5, 9, -5, 0)\n \n let rightImageStack = widgetStack.addStack()\n rightImageStack.layoutVertically()\n rightImageStack.setPadding(25, spacer, 0, 0)\n\n let line1 = leftTextStack.addText(\"Total Karma: \" + totalKarma)\n line1.font = Font.lightRoundedSystemFont(13)\n line1.textColor = txtColor\n \n let line2 = leftTextStack.addText(\"Comment Karma: \" + commentKarma)\n line2.font = Font.lightRoundedSystemFont(13)\n line2.textColor = txtColor\n \n let line3 = leftTextStack.addText(\"Post Karma: \" + postKarma)\n line3.font = Font.lightRoundedSystemFont(13)\n line3.textColor = txtColor\n \n let line4 = leftTextStack.addText(\"Awarder Karma: \" + awarderKarma)\n line4.font = Font.lightRoundedSystemFont(13)\n line4.textColor = txtColor\n \n let line5 = leftTextStack.addText(\"Awardee Karma: \" + awardeeKarma)\n line5.font = Font.lightRoundedSystemFont(13)\n line5.textColor = txtColor\n \n let profileImage = rightImageStack.addImage(await loadProfileImage())\n profileImage.imageSize = new Size(77, 77)\n profileImage.cornerRadius = cornerRadiusProfileImg\n profileImage.rightAlignImage()\n profileImage.url = profileURL\n \n if (showCoinBalance) {\n let coinsStack = rightImageStack.addStack()\n coinsStack.setPadding(2, 15, 2, 0)\n coinsStack.cornerRadius = 5\n let coinsImage = coinsStack.addImage(await getImageFor(\"coins\"))\n coinsImage.imageSize = new Size(11, 15)\n coinsStack.addSpacer(5)\n let coinsNumber = coinsStack.addText(rCoins)\n coinsNumber.font = Font.lightRoundedSystemFont(12) \n coinsNumber.textColor = txtColor\n}\n \n leftTextStack.addSpacer()\n\n df.useShortTimeStyle()\n df.useShortDateStyle()\n let footer = widget.addText(\"Last Widget Refresh \" + df.string(new Date())) \n footer.font = Font.lightSystemFont(9)\n footer.textColor = txtColor\n footer.textOpacity = 0.4\n footer.centerAlignText()\n \n return widget\n}\n\n\n\/\/********** CEEATE LARGE WIDGET *********\nasync function createLargeWidget(data) {\n let widget = new ListWidget()\n widget.setPadding(20, 15, 3, 14)\n widget.backgroundGradient = bgGradient\n \n var refreshDate = Date.now() + 1000*60*refresh\n widget.refreshAfterDate = new Date(refreshDate)\n \n widget.addSpacer()\n \n let profileImage = widget.addImage(await loadProfileImage())\n profileImage.imageSize = new Size(88, 88)\n profileImage.cornerRadius = cornerRadiusProfileImg\n profileImage.url = profileURL\n \n widget.addSpacer(10)\n \n let headerStack = widget.addStack()\n \n if (showUserTitle && userTitle != '') {\n let headerTitle = headerStack.addText(userTitle)\n headerTitle.font = Font.mediumSystemFont(22) \n headerTitle.textColor = txtColor\n headerTitle.url = profileURL\n\n let headerUsername = widget.addText(`${userName} • ${totalKarma} Karma • ${rCoins} Coin Balance \\n${accountAge} • ${dateCreated}`)\n headerUsername.font = Font.thinSystemFont(14) \n headerUsername.textColor = txtColor\n headerUsername.textOpacity = 0.8\n \n } else if (!showUserTitle || userTitle == \"\") {\n let headerTitle = headerStack.addText(userName)\n headerTitle.font = Font.mediumSystemFont(22) \n headerTitle.textColor = txtColor\n headerTitle.url = profileURL\n\n let headerUsername = widget.addText(`${totalKarma} Karma • ${rCoins} Coin Balance \\n${accountAge} • ${dateCreated}`)\n headerUsername.font = Font.thinSystemFont(14)\n headerUsername.textOpacity = 0.8\n }\n \n if (df.string(new Date()).slice(0, -4) == dateCreated.slice(0, -4)) {\n headerStack.addSpacer(7)\n headerTitleCakeDay = headerStack.addImage(await getImageFor(`cakeday${standardRedditClient}`))\n headerTitleCakeDay.imageSize = new Size(25, 25)\n}\n\n let headerDescription = widget.addText(puplicDescription)\n headerDescription.font = Font.thinSystemFont(14) \n headerDescription.textColor = txtColor\n headerDescription.textOpacity = 0.8\n headerDescription.lineLimit = 1\n headerDescription.minimumScaleFactor = 0.9\n \n widget.addSpacer()\n \n let mainBodyStack = widget.addStack()\n mainBodyStack.layoutVertically()\n \n let line2 = mainBodyStack.addText(\"Post Karma: \" + postKarma)\n line2.font = Font.lightSystemFont(17)\n line2.textColor = txtColor\n \n let line3 = mainBodyStack.addText(\"Comment Karma: \" + commentKarma)\n line3.font = Font.lightSystemFont(17)\n line3.textColor = txtColor\n \n let line4 = mainBodyStack.addText(\"Awarder Karma: \" + awarderKarma)\n line4.font = Font.lightSystemFont(17)\n line4.textColor = txtColor\n \n let line5 = mainBodyStack.addText(\"Awardee Karma: \" + awardeeKarma)\n line5.font = Font.lightSystemFont(17)\n line5.textColor = txtColor \n \n widget.addSpacer()\n \n df.useShortTimeStyle()\n df.useShortDateStyle()\n let footer = widget.addText(\"Last Widget Refresh \" + df.string(new Date())) \n footer.font = Font.lightSystemFont(11)\n footer.textColor = txtColor\n footer.textOpacity = 0.3\n footer.centerAlignText()\n \n return widget\n}\n\nasync function loadAppIcon() {\n let req = new Request(iconURL)\n return req.loadImage()\n}\n\nasync function loadProfileImage() {\n let req = new Request(profileImg[0])\n return req.loadImage()\n}\n\nawait saveImages()\ntry {saveData(data)}\ncatch {}\n\nif (config.runsInApp) {\n await presentMenu()\n} else if (config.runsInWidget) {\n switch(widgetSize) {\n case \"small\": widget = await createSmallWidget(data);\n break;\n case \"medium\": widget = await createMediumWidget(data);\n break;\n case \"large\": widget = await createLargeWidget(data);\n break;\n default: widget = await createSmallWidget(data);\n }\n Script.setWidget(widget)\n}\n\nasync function presentMenu(data) {\n let alert = new Alert(data)\n alert.title = \"Reddit Widget: \" + userName\n alert.message = `Total Karma: ${totalKarma} | Coins: ${rCoins} | Inbox: ${inboxCount}`\n alert.addAction(\"Small\")\n alert.addAction(\"Medium\")\n alert.addAction(\"Large\")\n alert.addDestructiveAction(\"Open Profile ↗\")\n alert.addCancelAction(\"Cancel\")\n let idx = await alert.presentSheet(data)\n if (idx == 0) {\n let widget = await createSmallWidget(data)\n await widget.presentSmall()\n } else if (idx == 1) {\n let widget = await createMediumWidget(data)\n await widget.presentMedium()\n } else if (idx == 2) {\n let widget = await createLargeWidget(data)\n await widget.presentLarge()\n } else if (idx == 3) {\n Safari.open(`${standardRedditClient}:\/\/reddit.com\/user\/${USERNAME}\/`)\n }\n}",
"share_sheet_inputs" : [
]
}