Skip to content

Commit

Permalink
userscript: Init commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikarific committed May 28, 2024
1 parent 58fc4aa commit 1e5a1e1
Show file tree
Hide file tree
Showing 30 changed files with 570 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ This is the monorepo for the new Charity rewrite.
Packages:

- `app`
- `userscript`: The overlay userscript.
- `website`: Website is the web client.
- `service`
- `waiter`: Waiter is the service that manages/hosts templates, including JSON and images.
Expand Down
2 changes: 2 additions & 0 deletions app/userscript/.browserslistrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Chrome >= 57
Firefox >= 57
11 changes: 11 additions & 0 deletions app/userscript/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# http://editorconfig.org
root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
quote_type = single
3 changes: 3 additions & 0 deletions app/userscript/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/*
!/src
!/test
18 changes: 18 additions & 0 deletions app/userscript/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
],
plugins: ['@typescript-eslint'],
env: {
browser: true,
node: true,
},
rules: {
'@typescript-eslint/no-explicit-any': ['off'],
},
};
6 changes: 6 additions & 0 deletions app/userscript/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules
*.log
/.idea
/.nyc_output
/coverage
/types
1 change: 1 addition & 0 deletions app/userscript/.husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
npx lint-staged
2 changes: 2 additions & 0 deletions app/userscript/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
shamefully-hoist = true
strict-peer-dependencies = false
11 changes: 11 additions & 0 deletions app/userscript/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"arrowParens": "always",
"bracketSpacing": true,
"experimentalTernaries": true,
"jsxSingleQuote": true,
"printWidth": 120,
"semi": true,
"singleQuote": true,
"trailingComma": "all",
"useTabs": true
}
21 changes: 21 additions & 0 deletions app/userscript/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 Mikarific

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Binary file added app/userscript/assets/banner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/userscript/assets/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/userscript/assets/icon64.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions app/userscript/babel.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = {
presets: [
[
'@babel/preset-env',
{
modules: false,
loose: true,
},
],
'@babel/preset-typescript',
'babel-preset-solid',
],
};
150 changes: 150 additions & 0 deletions app/userscript/dist/CharityOverlay.user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
// ==UserScript==
// @name Charity Overlay
// @namespace faction.place
// @description The most widely used overlay system on r/place.
// @icon https://raw.githubusercontent.com/PlaceCharity/Charity/main/app/userscript/assets/icon.png
// @icon64 https://raw.githubusercontent.com/PlaceCharity/Charity/main/app/userscript/assets/icon64.png
// @version 0.1.0
// @author Mikarific
// @match http://localhost/*
// @match http://localhost:8193/*
// @match https://reddit.com/r/place/*
// @match https://www.reddit.com/r/place/*
// @match https://new.reddit.com/r/place/*
// @match https://sh.reddit.com/r/place/*
// @run-at document-start
// @connect *
// @allFrames true
// @downloadURL https://github.com/PlaceCharity/
// @updateURL https://github.com/PlaceCharity/
// @supportURL https://discord.gg/anBdazHcrH
// @homepageURL https://discord.gg/anBdazHcrH
// @license MIT
// @require https://cdn.jsdelivr.net/npm/@violentmonkey/dom@2
// @require https://cdn.jsdelivr.net/npm/@violentmonkey/[email protected]
// @require https://cdn.jsdelivr.net/npm/@violentmonkey/dom@2/dist/solid.min.js
// @grant GM.deleteValue
// @grant GM.getValue
// @grant GM.registerMenuCommand
// @grant GM.setValue
// @grant GM_addStyle
// ==/UserScript==

(async () => {
if(GM.info.scriptHandler === 'Greasemonkey') alert('Charity Overlay has dropped support for Greasemonkey!\n\nIn all honesty nobody should be using Greasemonkey in 2024.\n\nFor a lightweight, privacy focused alternative, my recommendation is to switch to FireMonkey.\n\nFor an open source, one size fits all solution, my recommendation is to switch to Violentmonkey.');
(function (web, ui) {
'use strict';

var css_248z = "*,:after,:before{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 transparent;--un-ring-shadow:0 0 transparent;--un-shadow-inset: ;--un-shadow:0 0 transparent;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }::backdrop{--un-rotate:0;--un-rotate-x:0;--un-rotate-y:0;--un-rotate-z:0;--un-scale-x:1;--un-scale-y:1;--un-scale-z:1;--un-skew-x:0;--un-skew-y:0;--un-translate-x:0;--un-translate-y:0;--un-translate-z:0;--un-pan-x: ;--un-pan-y: ;--un-pinch-zoom: ;--un-scroll-snap-strictness:proximity;--un-ordinal: ;--un-slashed-zero: ;--un-numeric-figure: ;--un-numeric-spacing: ;--un-numeric-fraction: ;--un-border-spacing-x:0;--un-border-spacing-y:0;--un-ring-offset-shadow:0 0 transparent;--un-ring-shadow:0 0 transparent;--un-shadow-inset: ;--un-shadow:0 0 transparent;--un-ring-inset: ;--un-ring-offset-width:0px;--un-ring-offset-color:#fff;--un-ring-width:0px;--un-ring-color:rgba(147,197,253,.5);--un-blur: ;--un-brightness: ;--un-contrast: ;--un-drop-shadow: ;--un-grayscale: ;--un-hue-rotate: ;--un-invert: ;--un-saturate: ;--un-sepia: ;--un-backdrop-blur: ;--un-backdrop-brightness: ;--un-backdrop-contrast: ;--un-backdrop-grayscale: ;--un-backdrop-hue-rotate: ;--un-backdrop-invert: ;--un-backdrop-opacity: ;--un-backdrop-saturate: ;--un-backdrop-sepia: }.panel{cursor:move!important;max-height:75%!important;max-width:75%!important;min-width:16rem!important}.panel-body{height:100%!important;width:100%!important}";

function windowIsEmbedded() {
return window.top !== window.self;
}
async function sleep(ms) {
await new Promise(resolve => setTimeout(resolve, ms));
}
function findJSONTemplateInParams(urlString) {
const urlSearchParams = new URLSearchParams(urlString);
return urlSearchParams.get('charity');
}
function findJSONTemplateInURL(url) {
return findJSONTemplateInParams(url.hash.substring(1)) || findJSONTemplateInParams(url.search.substring(1));
}
function findElementOfType(element, type) {
const rv = [];
if (element instanceof type) {
rv.push(element);
}

// find in Shadow DOM elements
if (element instanceof HTMLElement && element.shadowRoot) {
rv.push(...findElementOfType(element.shadowRoot, type));
}
// find in children
for (let c = 0; c < element.children.length; c++) {
rv.push(...findElementOfType(element.children[c], type));
}
return rv;
}

async function findCanvas() {
let canvasElements = [];
while (document.readyState !== 'complete') {
await sleep(1000);
}
let sleep$1 = 0;
while (canvasElements.length === 0) {
if ((await GM.getValue('canvasFound', false)) && !windowIsEmbedded()) return;
await sleep(1000 * sleep$1);
sleep$1++;
canvasElements = findElementOfType(document.documentElement, HTMLCanvasElement);
}
GM.setValue('canvasFound', true);
return canvasElements;
}
async function findTemplate() {
let jsonTemplate;
let sleep$1 = 0;
while (jsonTemplate === undefined) {
const scriptValue = await GM.getValue('jsonTemplate', '');
if (scriptValue === '') {
await sleep(1000 * sleep$1);
sleep$1++;
} else {
jsonTemplate = scriptValue;
break;
}
}
await GM.deleteValue('jsonTemplate');
return jsonTemplate;
}

var _tmpl$ = /*#__PURE__*/web.template(`<div>SETTINGS`);
const settingsPanel = ui.getPanel({
className: 'panel',
shadow: false,
theme: 'dark'
});
settingsPanel.setMovable(true);
settingsPanel.body.classList.add('panel-body');
function SettingsPanel() {
return _tmpl$();
}
web.render(SettingsPanel, settingsPanel.body);
let settingsPanelOpen = false;
function openSettings() {
if (!settingsPanelOpen) {
settingsPanel.show();
document.body.appendChild(settingsPanel.host);
const {
width,
height
} = settingsPanel.body.getBoundingClientRect();
const x = window.innerWidth / 2 - width / 2;
const y = window.innerHeight / 2 - height / 2;
settingsPanel.wrapper.style.inset = `${y}px auto auto ${x}px`;
settingsPanelOpen = !settingsPanelOpen;
}
}
if (typeof GM.registerMenuCommand !== 'undefined') {
GM.registerMenuCommand('Open Settings', openSettings, {
autoClose: true
});
}

GM_addStyle(css_248z);
(async () => {
if (!windowIsEmbedded()) {
var _utils$findJSONTempla;
GM.deleteValue('canvasFound');
GM.setValue('jsonTemplate', (_utils$findJSONTempla = findJSONTemplateInURL(window.location)) != null ? _utils$findJSONTempla : '');
}
const canvas = await findCanvas();
if (canvas === undefined) return;
console.log(`Found Canvas: ${canvas}`);
const jsonTemplate = await findTemplate();
if (jsonTemplate === undefined) return;
})();

})(VM.solid.web, VM);
})();
50 changes: 50 additions & 0 deletions app/userscript/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{
"name": "charity-overlay",
"version": "0.1.0",
"description": "",
"author": "Mikarific",
"license": "MIT",
"private": true,
"engines": {
"node": ">=18"
},
"scripts": {
"prepare": "husky",
"dev": "rollup -wc",
"clean": "del-cli dist",
"lint": "eslint --ext .ts,.tsx . && prettier --ignore-path .eslintignore --check .",
"lint:fix": "eslint --ext .ts,.tsx --fix . && prettier --ignore-path .eslintignore --write .",
"ci": "run-s lint:fix",
"build:js": "rollup -c",
"build": "cross-env NODE_ENV=production run-s ci clean build:js"
},
"dependencies": {
"@babel/runtime": "^7.24.1",
"@violentmonkey/dom": "^2.1.6",
"@violentmonkey/ui": "^0.7.8",
"solid-js": "^1.8.16"
},
"devDependencies": {
"@babel/plugin-transform-react-jsx": "^7.23.4",
"@gera2ld/plaid": "~2.7.0",
"@gera2ld/plaid-rollup": "~2.7.0",
"@types/firemonkey-browser": "^2.62.4",
"@unocss/postcss": "^0.58.6",
"@violentmonkey/types": "^0.1.7",
"babel-preset-solid": "^1.8.16",
"cross-env": "^7.0.3",
"del-cli": "^5.1.0",
"eslint-config-prettier": "^9.1.0",
"husky": "^9.0.11",
"lint-staged": "^15.2.2",
"prettier": "^3.2.5",
"rollup-plugin-userscript": "^0.3.2",
"unocss": "^0.58.6"
},
"lint-staged": {
"src/**": [
"eslint --fix",
"prettier --write"
]
}
}
7 changes: 7 additions & 0 deletions app/userscript/postcss.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
plugins: {
'postcss-calc': {},
'postcss-nested': {},
'@unocss/postcss': {},
},
};
47 changes: 47 additions & 0 deletions app/userscript/rollup.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { defineExternal, definePlugins } from '@gera2ld/plaid-rollup';
import { defineConfig } from 'rollup';
import userscript from 'rollup-plugin-userscript';
import pkg from './package.json' assert { type: 'json' };

export default defineConfig(
Object.entries({
CharityOverlay: 'src/index.ts',
}).map(([name, entry]) => ({
input: entry,
plugins: [
...definePlugins({
esm: true,
minimize: false,
postcss: {
inject: false,
minimize: true,
},
extensions: ['.ts', '.tsx', '.mjs', '.js', '.jsx'],
}),
userscript((meta) =>
meta
.replace('process.env.AUTHOR', pkg.author)
.replace('process.env.VERSION', pkg.version)
.replace('process.env.LICENSE', pkg.license),
),
],
external: defineExternal(['@violentmonkey/ui', '@violentmonkey/dom', 'solid-js', 'solid-js/web']),
output: {
format: 'iife',
file: `dist/${name}.user.js`,
banner:
"(async () => {\nif(GM.info.scriptHandler === 'Greasemonkey') alert('Charity Overlay has dropped support for Greasemonkey!\\n\\nIn all honesty nobody should be using Greasemonkey in 2024.\\n\\nFor a lightweight, privacy focused alternative, my recommendation is to switch to FireMonkey.\\n\\nFor an open source, one size fits all solution, my recommendation is to switch to Violentmonkey.');",
footer: '})();',
globals: {
// Note:
// - VM.solid is just a third-party UMD bundle for solid-js since there is no official one
// - If you don't want to use it, just remove `solid-js` related packages from `external`, `globals` and the `meta.js` file.
'solid-js': 'VM.solid',
'solid-js/web': 'VM.solid.web',
'@violentmonkey/dom': 'VM',
'@violentmonkey/ui': 'VM',
},
indent: false,
},
})),
);
21 changes: 21 additions & 0 deletions app/userscript/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import globalCss from './styles.css';
import { findCanvas, findTemplate } from './lib/canvas';
import * as utils from './lib/utils';

import './meta.js?userscript-metadata';
import './ui/settings';

GM_addStyle(globalCss);

(async () => {
if (!utils.windowIsEmbedded()) {
GM.deleteValue('canvasFound');
GM.setValue('jsonTemplate', utils.findJSONTemplateInURL(window.location) ?? '');
}

const canvas = await findCanvas();
if (canvas === undefined) return;
console.log(`Found Canvas: ${canvas}`);
const jsonTemplate = await findTemplate();
if (jsonTemplate === undefined) return;
})();
Loading

0 comments on commit 1e5a1e1

Please sign in to comment.