Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 52 additions & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />

<meta name="theme-color" content="#14161A" />
<!-- Let the UA style built-in controls for both schemes; prefer dark first -->
<meta name="color-scheme" content="dark light" />

<meta
name="description"
content="Web site created using create-react-app"
Expand All @@ -25,6 +29,53 @@
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>AF Bullet Shaping Tool</title>

<!-- Dark-first default; flips if data-theme="light" -->
<style>
html, body { background: #14161A; color: #f2f3f5; }
html[data-theme="light"], html[data-theme="light"] body {
background: #ffffff; color: #111111;
}
</style>

<!-- Apply saved manual theme before React/CSS loads (no flash) -->
<script>
(function () {
try {
var docEl = document.documentElement;
var stored = localStorage.getItem('theme'); // 'light' | 'dark' | 'system' | null
var prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;

// Decide which colors to paint immediately
var chosen = (stored === 'light' || stored === 'dark')
? stored
: (prefersDark ? 'dark' : 'light');

// If the user explicitly chose light/dark, set the data attribute now.
if (stored === 'light' || stored === 'dark') {
docEl.setAttribute('data-theme', stored);
} else {
docEl.removeAttribute('data-theme'); // system
}

// Paint background/text to avoid any flash
var bg = chosen === 'dark' ? '#14161A' : '#ffffff';
var fg = chosen === 'dark' ? '#f2f3f5' : '#111111';
docEl.style.background = bg;
docEl.style.color = fg;
if (document.body) {
document.body.style.background = bg;
document.body.style.color = fg;
}

// Keep the browser UI (address bar) in sync
var metaTheme = document.querySelector('meta[name="theme-color"]');
if (metaTheme) metaTheme.setAttribute('content', bg);
} catch (e) {
/* no-op */
}
})();
</script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
Expand Down
18 changes: 7 additions & 11 deletions src/components/Bullets/Bullet.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ function Bullet({
const canvasRef = useRef(null);
const [outputTextLines, setOutputTextLines] = useState(() => [" "]);

const [color, setColor] = useState("inherit");
const [loading, setLoading] = useState(false);
const [optimStatus, setOptimStatus] = useState(STATUS.NOT_OPT);
const [rendering, setBulletRendering] = useState({ textLines: [""] });
Expand Down Expand Up @@ -67,15 +66,12 @@ function Bullet({
}, [rendering, enableOptim, text, widthPxAdjusted]);

//color effect
useEffect(() => {
if (loading) {
setColor("silver");
} else if (optimStatus === STATUS.FAILED_OPT) {
setColor("red");
} else {
setColor("black");
}
}, [loading, outputTextLines, optimStatus]);
// choose a theme-aware class for text color
const statusClass = loading
? "is-loading"
: optimStatus === STATUS.FAILED_OPT
? "has-text-danger"
: "";

// the style properties help lock the canvas in the same spot and make it essentially invisible.
//whitespace: pre-wrap is essential as it allows javascript string line breaks to appear properly.
Expand All @@ -91,9 +87,9 @@ function Bullet({
}}
/>
<div
className={statusClass}
style={{
minHeight: height,
color: color,
display: "flex",
flexDirection: "column",
}}
Expand Down
9 changes: 6 additions & 3 deletions src/components/Toolbars/Thesaurus.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class SynonymViewer extends PureComponent {

return (
<div className="card">
<header className="card-header has-background-light is-shadowless">
<header className="card-header is-shadowless">
<div className="card-header-title">
<span>Thesaurus{this.props.word ? ":" : ""}</span>
{this.props.word ? header : ""}
Expand All @@ -125,7 +125,6 @@ class SynonymViewer extends PureComponent {
}

class SynonymList extends PureComponent {

render() {
return (
<div>
Expand All @@ -141,7 +140,11 @@ class SynonymList extends PureComponent {
otherAbbrs={otherAbbrs}
/>
<a className="icon" onMouseDown={handleCardClick(word, this)}>
<FontAwesomeIcon icon={faPlus} size="xs" color="#51cf66" />
<FontAwesomeIcon
icon={faPlus}
size="xs"
className="thesaurus-plus"
/>
</a>
</span>
);
Expand Down
110 changes: 79 additions & 31 deletions src/components/Toolbars/Toolbars.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import React from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleDown } from "@fortawesome/free-solid-svg-icons";
import ImportTools from "./ImportTools";
import SaveTools from "./SaveTools";
// form width, space optimization, select text
function OutputTools({ onOptimChange, enableOptim, onWidthUpdate, width, onHighlightChange, handleEnableHighlight, enableHighlight }) {
function OutputTools({
onOptimChange,
enableOptim,
onWidthUpdate,
width,
onHighlightChange,
handleEnableHighlight,
enableHighlight,
}) {
const widthAWD = 202.321;
const widthEPR = 202.321;
const widthOPR = 201.041;
Expand Down Expand Up @@ -50,28 +59,30 @@ function OutputTools({ onOptimChange, enableOptim, onWidthUpdate, width, onHighl
OPR
</a>
</div>
</div>
<a
className={
"control button is-dark" + (enableOptim ? "" : "is-outlined")
}
onClick={onOptimChange}
id="enableOptim"
>
Auto-Space
</a>
<a
className={
"control button is-dark" +
(enableHighlight ? "is-success" : "is-outlined")
}
onClick={() => { onHighlightChange(); handleEnableHighlight() }}
id="enableHighlight"
>
Show Duplicates
</a>

</div>
<a
className={
"control button is-dark" + (enableOptim ? "" : "is-outlined")
}
onClick={onOptimChange}
id="enableOptim"
>
Auto-Space
</a>
<a
className={
"control button is-dark" +
(enableHighlight ? "is-success" : "is-outlined")
}
onClick={() => {
onHighlightChange();
handleEnableHighlight();
}}
id="enableHighlight"
>
Show Duplicates
</a>
</div>
);
}
// normalize spaces
Expand All @@ -83,17 +94,47 @@ function InputTools({ onTextNorm }) {
);
}

function Logo() {
function ThemeSelector() {
const [theme, setTheme] = React.useState(
() => localStorage.getItem("theme") || "system"
);

React.useEffect(() => {
const root = document.documentElement;
if (theme === "system") {
root.removeAttribute("data-theme"); // defer to prefers-color-scheme
localStorage.removeItem("theme");
} else {
root.setAttribute("data-theme", theme);
localStorage.setItem("theme", theme);
}
}, [theme]);

return (
<h1 className="title">
<span className="logo">AF </span>
<span className="logo">Bull</span>et
<span className="logo"> Sh</span>aping &amp;
<span className="logo"> i</span>teration
<span className="logo"> t</span>ool
</h1>
<div className="field has-addons is-align-items-center">
<span className="control">
<span className="button is-static">Theme</span>
</span>
<span className="control">
<div className="select">
<select
aria-label="Theme"
value={theme}
onChange={(e) => setTheme(e.target.value)}
>
<option value="system">System</option>
<option value="light">Light</option>
<option value="dark">Dark</option>
</select>
</div>
</span>
</div>
);
}

function Logo() {
return <h1 className="title">AF Bullet Shaping &amp; Iteration Tool</h1>;
}
function ThesaurusTools({ onHide }) {
return (
<a
Expand All @@ -111,7 +152,11 @@ function ThesaurusTools({ onHide }) {
}
function DocumentTools(props) {
return (
<nav className="navbar" role="navigation" aria-label="main navigation">
<nav
className="navbar is-wrap"
role="navigation"
aria-label="main navigation"
>
<div className="navbar-start">
<div className="navbar-item">
<SaveTools getSavedSettings={props.getSavedSettings} />
Expand Down Expand Up @@ -140,6 +185,9 @@ function DocumentTools(props) {
<div className="navbar-item">
<ThesaurusTools onHide={props.onThesaurusHide} />
</div>
<div className="navbar-item">
<ThemeSelector />
</div>
</div>
</nav>
);
Expand Down
Loading