diff options
-rw-r--r-- | Settings.jsx | 44 | ||||
-rw-r--r-- | index.js | 43 | ||||
-rw-r--r-- | jsconig.json | 7 | ||||
-rw-r--r-- | manifest.json | 7 | ||||
-rw-r--r-- | timezones.json | 198 | ||||
-rw-r--r-- | transformation.jsx | 40 | ||||
-rw-r--r-- | tz.js | 10 | ||||
-rw-r--r-- | util.js | 19 |
8 files changed, 368 insertions, 0 deletions
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 <div> + <SelectInput + searchable={true} + onChange={(e) => { + 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 + </SelectInput> + </div>; + } + +}; +; + + 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)); @@ -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 +}; + + @@ -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; +}; |