From 73d29ebbcca1e1e00ad54b7a2f43982dad81e1c2 Mon Sep 17 00:00:00 2001 From: nea Date: Mon, 16 Aug 2021 23:01:35 +0200 Subject: Initial commit --- Settings.jsx | 44 ++++++++++++ index.js | 43 ++++++++++++ jsconig.json | 7 ++ manifest.json | 7 ++ timezones.json | 198 +++++++++++++++++++++++++++++++++++++++++++++++++++++ transformation.jsx | 40 +++++++++++ tz.js | 10 +++ util.js | 19 +++++ 8 files changed, 368 insertions(+) create mode 100644 Settings.jsx create mode 100644 index.js create mode 100644 jsconig.json create mode 100644 manifest.json create mode 100644 timezones.json create mode 100644 transformation.jsx create mode 100644 tz.js create mode 100644 util.js diff --git a/Settings.jsx b/Settings.jsx new file mode 100644 index 0000000..b13da96 --- /dev/null +++ b/Settings.jsx @@ -0,0 +1,44 @@ +const { React } = require('powercord/webpack'); +const { + Category, + SwitchItem, + TextInput, + RadioGroup, + SelectInput +} = require('powercord/components/settings'); +const tz = require('./tz'); + + + module.exports = class Settings extends React.Component { + constructor (props) { + super(props); + this.state = { + timezone: this.props.getSetting('timezone', 'GMT') + }; + } + + render () { + return
+ { + this.props.updateSetting('timezone', e.value); + this.setState({ timezone: e.value }); + }} + value={this.state.timezone} + options={[ + ...tz.timezones.map(it => ({ + value: it.code, + label: `${it.name} (${it.offset})` + })) + ]} + > + My timezone + +
; + } + +}; +; + + diff --git a/index.js b/index.js new file mode 100644 index 0000000..7cb98dd --- /dev/null +++ b/index.js @@ -0,0 +1,43 @@ +const { Plugin } = require('powercord/entities'); +const Settings = require('./Settings.jsx'); +const manifest = require('./manifest.json'); +const { getModule } = require('powercord/webpack'); +const { + inject, + uninject +} = require('powercord/injector'); +const { lookup } = require('./tz'); + +const { transformMessageArray } = require('./transformation.jsx'); + +const PLUGIN_ID = 'timezone-powercord'; +const INJECTION_ID_MESSAGE_RENDER = PLUGIN_ID + '-message-render'; + +const MessageContent = getModule((m) => m.type && m.type.displayName === 'MessageContent', false); + + +module.exports = class TimezonePowercord extends Plugin { + async startPlugin () { + inject(INJECTION_ID_MESSAGE_RENDER, MessageContent, 'type', (args) => { + let x = transformMessageArray( + () => lookup(this.settings.get('timezone', 'GMT')))(args); + console.log(x); + return x; + }, true); + powercord.api.notices.sendAnnouncement('timezone-request-tz', { + color: 'green', + message: 'Timezone Powercord Plugin has been loaded.' + }); + powercord.api.settings.registerSettings(PLUGIN_ID, { + category: this.entityID, + label: 'Timezone Powercord Plugin', + render: Settings + }); + } + + async pluginWillUnload () { + uninject(INJECTION_ID_MESSAGE_RENDER); + powercord.api.settings.unregisterSettings(this.entityID); + } + +}; diff --git a/jsconig.json b/jsconig.json new file mode 100644 index 0000000..75ef438 --- /dev/null +++ b/jsconig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "paths": { + "powercord/*": [ "../../../fake_node_modules/powercord/*" ] + } + } +} diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..c74a6a7 --- /dev/null +++ b/manifest.json @@ -0,0 +1,7 @@ +{ + "name": "Timezone Powercord", + "version": "1.0.0", + "description": "Translate timestamps to different timezones", + "author": "nea89", + "license": "LGPL 3" +} diff --git a/timezones.json b/timezones.json new file mode 100644 index 0000000..40760d4 --- /dev/null +++ b/timezones.json @@ -0,0 +1,198 @@ +{ + "__comment": "This timezone list is very barren, however i am not willing to put much more energy into it rn. Contributions welcome.", + "__original_source": "The first iteration of this list was sourced from https://publib.boulder.ibm.com/tividd/td/TWS/SC32-1274-02/en_US/HTML/SRF_mst273.htm", + "timezones": [ + { + "code": "GMT", + "name": "Greenwich Mean Time", + "offset": "GMT", + "offsetminutes": 0 + }, + { + "code": "UTC", + "name": "Universal Coordinated Time", + "offset": "GMT", + "offsetminutes": 0 + }, + { + "code": "ECT", + "name": "European Central Time", + "offset": "GMT+1:00", + "offsetminutes": 60 + }, + { + "code": "EET", + "name": "Eastern European Time", + "offset": "GMT+2:00", + "offsetminutes": 120 + }, + { + "code": "ART", + "name": "(Arabic) Egypt Standard Time", + "offset": "GMT+2:00", + "offsetminutes": 120 + }, + { + "code": "EAT", + "name": "Eastern African Time", + "offset": "GMT+3:00", + "offsetminutes": 180 + }, + { + "code": "MET", + "name": "Middle East Time", + "offset": "GMT+3:30", + "offsetminutes": 210 + }, + { + "code": "NET", + "name": "Near East Time", + "offset": "GMT+4:00", + "offsetminutes": 240 + }, + { + "code": "PLT", + "name": "Pakistan Lahore Time", + "offset": "GMT+5:00", + "offsetminutes": 300 + }, + { + "code": "IST", + "name": "India Standard Time", + "offset": "GMT+5:30", + "offsetminutes": 330 + }, + { + "code": "BST", + "name": "Bangladesh Standard Time", + "offset": "GMT+6:00", + "offsetminutes": 360 + }, + { + "code": "VST", + "name": "Vietnam Standard Time", + "offset": "GMT+7:00", + "offsetminutes": 420 + }, + { + "code": "CTT", + "name": "China Taiwan Time", + "offset": "GMT+8:00", + "offsetminutes": 480 + }, + { + "code": "JST", + "name": "Japan Standard Time", + "offset": "GMT+9:00", + "offsetminutes": 540 + }, + { + "code": "ACT", + "name": "Australia Central Time", + "offset": "GMT+9:30", + "offsetminutes": 570 + }, + { + "code": "AET", + "name": "Australia Eastern Time", + "offset": "GMT+10:00", + "offsetminutes": 600 + }, + { + "code": "SST", + "name": "Solomon Standard Time", + "offset": "GMT+11:00", + "offsetminutes": 660 + }, + { + "code": "NST", + "name": "New Zealand Standard Time", + "offset": "GMT+12:00", + "offsetminutes": 720 + }, + { + "code": "MIT", + "name": "Midway Islands Time", + "offset": "GMT-11:00", + "offsetminutes": -660 + }, + { + "code": "HST", + "name": "Hawaii Standard Time", + "offset": "GMT-10:00", + "offsetminutes": -600 + }, + { + "code": "AST", + "name": "Alaska Standard Time", + "offset": "GMT-9:00", + "offsetminutes": -540 + }, + { + "code": "PST", + "name": "Pacific Standard Time", + "offset": "GMT-8:00", + "offsetminutes": -480 + }, + { + "code": "PNT", + "name": "Phoenix Standard Time", + "offset": "GMT-7:00", + "offsetminutes": -420 + }, + { + "code": "MST", + "name": "Mountain Standard Time", + "offset": "GMT-7:00", + "offsetminutes": -420 + }, + { + "code": "CST", + "name": "Central Standard Time", + "offset": "GMT-6:00", + "offsetminutes": -360 + }, + { + "code": "EST", + "name": "Eastern Standard Time", + "offset": "GMT-5:00", + "offsetminutes": -300 + }, + { + "code": "IET", + "name": "Indiana Eastern Standard Time", + "offset": "GMT-5:00", + "offsetminutes": -300 + }, + { + "code": "PRT", + "name": "Puerto Rico and US Virgin Islands Time", + "offset": "GMT-4:00", + "offsetminutes": -240 + }, + { + "code": "CNT", + "name": "Canada Newfoundland Time", + "offset": "GMT-3:30", + "offsetminutes": -210 + }, + { + "code": "AGT", + "name": "Argentina Standard Time", + "offset": "GMT-3:00", + "offsetminutes": -180 + }, + { + "code": "BET", + "name": "Brazil Eastern Time", + "offset": "GMT-3:00", + "offsetminutes": -180 + }, + { + "code": "CAT", + "name": "Central African Time", + "offset": "GMT-1:00", + "offsetminutes": -60 + } + ] +} diff --git a/transformation.jsx b/transformation.jsx new file mode 100644 index 0000000..a355f97 --- /dev/null +++ b/transformation.jsx @@ -0,0 +1,40 @@ +const { splitSegments } = require('./util'); +const { React } = require('powercord/webpack'); +const { + timezones, + lookup +} = require('./tz'); + +const timezonePattern = new RegExp('(\\d+):(\\d+) *(' + timezones.map(it => `(?:${it.code})`).join('|') + ')', 'g'); + +function transformMessage (userTimezoneProvider, msgConstruct) { + if (!('content' in msgConstruct)) { + return msgConstruct; + } + return Object.assign({}, msgConstruct, { + content: msgConstruct.content.flatMap(it => transformPart(userTimezoneProvider, it)) + }); +} + +function transformPart (userTimezoneProvider, part) { + if (typeof part === 'string') { + return splitSegments(part, timezonePattern).map(it => { + if (typeof it === 'string') { + return it; + } + let [ _, hour, minute, tz ] = it.match; + let timezone = lookup(tz); + let time = hour * 60 + minute; + let userTimezone = userTimezoneProvider(); + let offset = userTimezone.offsetminutes - timezone.offsetminutes; + let adjusted = (time + offset) % (24 * 60); + return (<> + {hour}:{minute} {timezone.code} -> {adjusted / 60}:{adjusted % 60} {userTimezone.code} + ); + }); + } + return [ part ]; +} + +exports.transformMessageArray = userTimezoneProvider => args => + args.map(it => transformMessage(userTimezoneProvider, it)); diff --git a/tz.js b/tz.js new file mode 100644 index 0000000..59c75bb --- /dev/null +++ b/tz.js @@ -0,0 +1,10 @@ +const { timezones } = require('./timezones.json'); +module.exports = { + lookup (name) { + const casefolded = name.toLowerCase(); + return timezones.find(it => it.code.toLowerCase() === casefolded); + }, + timezones +}; + + diff --git a/util.js b/util.js new file mode 100644 index 0000000..934ccf5 --- /dev/null +++ b/util.js @@ -0,0 +1,19 @@ +/* Adapted from: https://stackoverflow.com/a/45502134/5401763 under CC BY-SA 4.0 */ +exports.splitSegments = function (string, pattern) { + let segments = []; + let match; + let lastIndex = 0; + pattern.lastIndex = 0; + + while (match = pattern.exec(string)) { + if (match.index > lastIndex) { + segments.push(string.substring(lastIndex, match.index)); + } + segments.push({ match }); + lastIndex = match.index + match[0].length; + } + if (lastIndex < string.length) { + segments.push(string.substr(lastIndex)); + } + return segments; +}; -- cgit