some work

This commit is contained in:
Guy Sandler 2026-01-16 13:38:30 -08:00
parent f8741f335a
commit d37d2f565b
9 changed files with 148 additions and 32 deletions

View File

@ -1,8 +1,12 @@
![Better Canvas](/icon/icon-wide.png)
![Better Canvas](/icon/NEWtitle.png)
# Better Canvas
# Betterer Canvas
Enhancements to Canvas like dark mode, better todo list, GPA calculator, and more!
The developer got greedy and decided to make things paid and ruin the UI so I am taking this into my own hands.
They tried to change license but forgot to wipe the codebase for thier MIT licensed version, so this is a fully legal fork.
Enhancements to Canvas AND bettercanvas like dark mode, better todo list, GPA calculator, and more!
### Supported on
@ -12,12 +16,14 @@ Enhancements to Canvas like dark mode, better todo list, GPA calculator, and mor
## Inquiries
To contact me, please email ksucpea@gmail.com, or you can open an issue within the "Issues" tab on GitHub.
To contact me, please email sandlerguy5@gmail.com, or you can open an issue within the "Issues" tab on GitHub.
If you are ksucpea and want to take this down, you can't, and I have [proof of legality](#proof-of-legality)
## Table of Contents
- [Features](#features)
- [Installation](#installation)
- [Dev Installation](#dev-installation)
- [Usage](#usage)
- [Version Notes](#version-notes)
- [Color Reference](#color-reference)
@ -31,7 +37,7 @@ Better Canvas introduces improvements to the Canvas user interface:
- Fully customizable dark mode (choose from premade options or manually edit dark mode)
- Automatic scheduling for dark mode
- Dashboard card color palletes
- Themes created by users
- Themes created by users (broken due to fork)
- Assignments due list
- Dashboard notes
- Better todo list
@ -46,24 +52,24 @@ Better Canvas introduces improvements to the Canvas user interface:
- Browser wide popup assignment reminder
- Preview assignments and announcements from the dashboard
## Installation
## Dev Installation
To install, run, and build with this repository,
To install, run, and build with this repository locally,
- Clone the repository locally with
```bash
git clone https://github.com/ksucpea/bettercanvas.git
git clone https://github.com/GuySandler/betterercanvas
```
- Visit `chrome://extensions` in your browser.
- Visit `chrome://extensions` in your browser. (replace chrome with your version of chromium)
- Enable developer mode by toggling the switch in the upper right corner of the viewport.
- Click the "Load upacked" button in the header.
- When prompted to open a file, select the root directory of this repository.
## Usage
To use Better Canvas, select your browser below to install the extension.
To use Better Canvas, select your browser below to install the extension from a store.
[Chrome](https://chrome.google.com/webstore/detail/better-canvas/cndibmoanboadcifjkjbdpjgfedanolh)
@ -115,8 +121,6 @@ To use Better Canvas, select your browser below to install the extension.
To add a new feature, please follow these guidelines.
Note: I will probably make this automated in the future but it's a bit of work right now.
#### Identifier
- Should be a unqiue one/two word storage identifier to indicate its status. (ie "dark_mode" or "dashboard_grades")
@ -266,13 +270,24 @@ Learn more about tree commands for Linux/Unix [here](https://www.geeksforgeeks.o
Learn more about tree commands for Windows [here](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/tree).
## proof of legality
This is the version right before the monetization of bettercanvas, original license and all.
here is some proof the lisence was changed and this is based on the reverted MIT version 5.12.6
![case1](./proof-of-legality/case1.png)
![case2](./proof-of-legality/case2.png)
## Authors
#### Owner
#### Fork Owner
- [Guy](https://github.com/guysandler)
#### Original Owner
- [ksucpea](https://github.com/ksucpea)
#### Contributors
#### Original Contributors
- [fudgeu](https://github.com/fudgeu)
- [Tibo Geeraerts](https://github.com/tibogeeraerts)

View File

@ -1,3 +0,0 @@
files:
- source: /_locales/en/*.json
translation: /_locales/%locale%/%original_file_name%

View File

@ -18,6 +18,7 @@
<div class="main-left">
<div class="container">
<div class="welcome">
<h2 style="transform:rotate(-20deg);color:cyan;position:relative;top:-12px;left:120px;">-er</h2>
<h1>Welcome to <span class="bettercanvas">Better Canvas!</span></h1>
<div id="refresh-note">
<p style="font-weight:600;">Refresh your Canvas page to setup</p>
@ -43,7 +44,7 @@
</li>
</div>
<div class="contact-info">
<p style="margin-top: 5px">My email is <span style="font-weight:700">ksucpea@gmail.com</span> if you
<p style="margin-top: 5px">My email is <span style="font-weight:700">sandlerguy5@gmail.com</span> if you
have any issues/suggestions - any feedback is appreciated!</p>
</div>

View File

@ -696,7 +696,10 @@
The letter grade will be calculated as greater than or equal to the percentage given. <br><br>
If your school doesn't use the +/- system, you can enter 101 for those grades to remove them from the
calculation. (for example A+ = 101, A = 90, A- = 101)
<button class="big-button gpa-plus-minus">+/- GPA Scale</button>
<button class="big-button gpa-by-letter">By Letter GPA Scale</button>
</div>
</div>
</div>

BIN
icon/NEWtitle.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

99
icon/NEWtitle.svg Normal file
View File

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="170.44157mm"
height="25.759138mm"
viewBox="0 0 170.44158 25.759138"
version="1.1"
id="svg1"
inkscape:version="1.4.3 (0d15f75042, 2025-12-25)"
sodipodi:docname="NEWtitle.svg"
inkscape:export-filename="NEWtitle.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="1.2567484"
inkscape:cx="404.61558"
inkscape:cy="274.9158"
inkscape:window-width="1920"
inkscape:window-height="966"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1">
<rect
x="269.51614"
y="36.03157"
width="89.358299"
height="26.663363"
id="rect2" />
<linearGradient
id="linearGradient1"
inkscape:collect="always">
<stop
style="stop-color:#ff1818;stop-opacity:1;"
offset="0"
id="stop1" />
<stop
style="stop-color:#ff0ec0;stop-opacity:1;"
offset="1"
id="stop2" />
</linearGradient>
<rect
x="47.451294"
y="48.934147"
width="705.83801"
height="167.56238"
id="rect1" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient1"
id="linearGradient2"
x1="48.628906"
y1="55.182617"
x2="132.06641"
y2="55.182617"
gradientUnits="userSpaceOnUse" />
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,0.47914756)">
<text
xml:space="preserve"
transform="matrix(1.9327416,0,0,1.9327416,-93.120927,-94.167478)"
id="text1"
style="writing-mode:lr-tb;direction:ltr;white-space:pre;shape-inside:url(#rect1);display:inline;fill:url(#linearGradient2)"><tspan
x="47.451172"
y="59.550781"
id="tspan3">Better Canvas</tspan></text>
<text
xml:space="preserve"
transform="matrix(0.76760109,-0.21673916,0.21673916,0.76760109,-150.80119,32.093741)"
id="text2"
style="writing-mode:lr-tb;direction:ltr;white-space:pre;shape-inside:url(#rect2);display:inline;fill:#1845ff;fill-opacity:1"><tspan
x="269.51562"
y="46.648438"
id="tspan5"><tspan
style="font-family:'Source Code Pro';-inkscape-font-specification:'Source Code Pro'"
id="tspan4">-er</tspan></tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -496,7 +496,7 @@ function setup() {
document.getElementById("save-theme").addEventListener("click", saveCurrentTheme);
// activate submit theme button
document.getElementById("submit-theme-btn").addEventListener("click", submitTheme);
// document.getElementById("submit-theme-btn").addEventListener("click", submitTheme);
document.getElementById("submit-theme-btn-1").addEventListener("click", () => {
document.getElementById("submit-popup").classList.add("open");
@ -537,7 +537,7 @@ function setup() {
});
// activate theme browser opt in
document.getElementById("new_browser_in").addEventListener("click", registerUser);
// document.getElementById("new_browser_in").addEventListener("click", registerUser);
document.querySelectorAll(".theme-sort-btn").forEach(btn => {
btn.addEventListener("click", (e) => {
@ -560,7 +560,7 @@ function setup() {
document.getElementById("opt-in").style.display = "block";
});
document.getElementById("view-submissions-btn").addEventListener("click", displayMySubmissions);
// document.getElementById("view-submissions-btn").addEventListener("click", displayMySubmissions);
document.getElementById("submit-form-btn").addEventListener("click", displayThemeSubmissionForm);
}
@ -581,7 +581,7 @@ function displayThemeSubmissionForm() {
document.getElementById("view-submissions-btn").classList.remove("active");
}
async function displayMySubmissions() {
async function displayMySubmissions() { //TODO: remake
const sync = await chrome.storage.sync.get("id");
const res = await fetch(`${apiurl}/api/themes/submissions?id=${sync["id"]}`);
const data = await res.json();
@ -768,7 +768,7 @@ function shortScore(score) {
let fallback = false;
async function submitTheme() {
async function submitTheme() { //TODO: remake
const sync = await chrome.storage.sync.get(null);
@ -797,7 +797,7 @@ async function submitTheme() {
"theme": JSON.stringify(theme)
});
fetch(`${apiurl}/api/themes/submit`, {
fetch(`${apiurl}/api/themes/submit`, { //
"method": "POST",
"body": body,
"headers": {
@ -815,7 +815,7 @@ async function submitTheme() {
});
}
async function registerUser() {
async function registerUser() { // TODO: remake
try {
let id;
@ -919,7 +919,7 @@ function setLikeTimeout() {
}, 1000);
}
async function likeTheme(location, code, score) {
async function likeTheme(location, code, score) { // TODO: remake
if (likeThemeTimeout === true) return;
@ -966,7 +966,7 @@ async function likeTheme(location, code, score) {
}
}
async function getAndLoadTheme(code) {
async function getAndLoadTheme(code) { // todo: remake
const key = `themes/${code}`;
let output = {};
if (cache[key]) {
@ -981,7 +981,7 @@ async function getAndLoadTheme(code) {
importTheme(output);
}
async function displayThemeListNew(direction) {
async function displayThemeListNew(direction) { // TODO: remake
document.getElementById("theme-current-sort").textContent = current_sort;
if (direction === -1 && current_page_num > 1) current_page_num--;
@ -1041,12 +1041,13 @@ async function displayThemeListNew(direction) {
const themeBtn = createThemeButton(container, theme);
themeBtn.addEventListener("click", (e) => {
if (!e.target.classList.contains("clickable")) return;
getAndLoadTheme(theme.code)
// getAndLoadTheme(theme.code)
});
const liked = local["liked_themes"].includes(theme.code);
// TODO: remake
const likeBtn = createThemeLikeBtn(themeBtn, liked, theme.score, sync["browser_show_likes"]);
likeBtn.addEventListener("click" , (e) => likeTheme(likeBtn, theme.code, theme.score));
// likeBtn.addEventListener("click" , (e) => likeTheme(likeBtn, theme.code, theme.score));
});

BIN
proof-of-legality/case1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

BIN
proof-of-legality/case2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB