Skip to content
Closed
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
23 changes: 15 additions & 8 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="style.less">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<title>Convert to it!</title>

Expand Down Expand Up @@ -34,24 +34,31 @@ <h2>Click to add your file</h2>
<div id="format-containers">

<div id="from-container" class="format-container">
<h2>Convert from:</h2>
<input type="text" id="search-from" class="search" placeholder="Search">
<div id="from-list" class="format-list">
<div class="format-container-inner">
<h2>Convert from:</h2>
<input type="text" id="search-from" class="search" placeholder="Search">
<div id="from-list" class="format-list">

</div>
</div>
</div>

<div id="to-container" class="format-container">
<h2>Convert to:</h2>
<input type="text" id="search-to" class="search" placeholder="Search">
<div id="to-list" class="format-list">
<div class="format-container-inner">
<h2>Convert to:</h2>
<input type="text" id="search-to" class="search" placeholder="Search">
<div id="to-list" class="format-list">

</div>
</div>
</div>

</div>

<button id="convert-button" class="disabled">Convert</button>
<div id="convert-container">
<button id="back-button">←</button>
<button id="convert-button" class="disabled">Convert</button>
</div>

<div id="popup-bg"></div>
<div id="popup">
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"@types/opentype.js": "^1.3.9",
"electron": "^40.6.0",
"electron-builder": "^26.8.1",
"less": "^4.6.4",
"puppeteer": "^24.36.0",
"typescript": "~5.9.3",
"vite": "^7.2.4",
Expand Down
65 changes: 58 additions & 7 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,56 @@ const ui = {
inputSearch: document.querySelector("#search-from") as HTMLInputElement,
outputSearch: document.querySelector("#search-to") as HTMLInputElement,
popupBox: document.querySelector("#popup") as HTMLDivElement,
popupBackground: document.querySelector("#popup-bg") as HTMLDivElement
popupBackground: document.querySelector("#popup-bg") as HTMLDivElement,
formatContainers: document.querySelector("#format-containers") as HTMLDivElement,
mobileBackButton: document.querySelector("#back-button") as HTMLButtonElement
};

// Can be maybe moved to another util file - lmk
const isMobileView = () => window.matchMedia("(max-width: 800px)").matches;

const isOnMobileToStep = () => ui.formatContainers.classList.contains("mobile-step-to");

const updateConvertButton = () => {
const hasFromSelected = !!ui.inputList.querySelector(".selected");
const hasToSelected = !!ui.outputList.querySelector(".selected");

if (!isMobileView()) {
ui.convertButton.textContent = "Convert";
ui.convertButton.className = (hasFromSelected && hasToSelected) ? "" : "disabled";
return;
}

if (isOnMobileToStep()) {
ui.convertButton.textContent = "Convert";
ui.convertButton.className = hasToSelected ? "" : "disabled";
} else {
ui.convertButton.textContent = "Next";
ui.convertButton.className = hasFromSelected ? "" : "disabled";
}
};

window.addEventListener("resize", updateConvertButton);

/**
* Switches view to the format list of possible output formats
*/
const showMobileToStep = () => {
ui.formatContainers.classList.add("mobile-step-to");
ui.formatContainers.scrollIntoView({ behavior: "smooth", block: "start" });
updateConvertButton();
};

/**
* Shows the format list for the file uploaded (from)
*/
const showMobileFromStep = () => {
ui.formatContainers.classList.remove("mobile-step-to");
updateConvertButton();
};

ui.mobileBackButton.addEventListener("click", showMobileFromStep);

/**
* Filters a list of butttons to exclude those not matching a substring.
* @param list Button list (div) to filter.
Expand Down Expand Up @@ -261,12 +308,8 @@ async function buildOptionList () {
const previous = targetParent?.getElementsByClassName("selected")?.[0];
if (previous) previous.className = "";
event.target.className = "selected";
const allSelected = document.getElementsByClassName("selected");
if (allSelected.length === 2) {
ui.convertButton.className = "";
} else {
ui.convertButton.className = "disabled";
}

updateConvertButton();
};

if (format.from && addToInputs) {
Expand Down Expand Up @@ -307,6 +350,7 @@ async function buildOptionList () {

ui.modeToggleButton.addEventListener("click", () => {
simpleMode = !simpleMode;
showMobileFromStep();
if (simpleMode) {
ui.modeToggleButton.textContent = "Advanced mode";
document.body.style.setProperty("--highlight-color", "#1C77FF");
Expand Down Expand Up @@ -419,6 +463,13 @@ function downloadFile (bytes: Uint8Array, name: string) {

ui.convertButton.onclick = async function () {

if (isMobileView() && !isOnMobileToStep()) {
const inputButton = document.querySelector("#from-list .selected");
if (!inputButton) return;
showMobileToStep();
return;
}

const inputFiles = selectedFiles;

if (inputFiles.length === 0) {
Expand Down
141 changes: 119 additions & 22 deletions style.css → style.less
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
@accent: #0007;

* {
box-sizing: border-box;
font-family: system-ui, sans-serif;
}

body {
margin: 0;
font-family: sans-serif;
--highlight-color: #1C77FF;
--highlight-color-transparent: color-mix(in srgb, var(--highlight-color), transparent 70%);
}

#file-input {
Expand Down Expand Up @@ -77,7 +84,11 @@ body {
align-items: center;
width: 50vw;
min-height: 70vh;
padding: 0.8em 7em;
padding: 0.8em 2em;
}

.format-container-inner {
max-width: 500px;
}
.format-container h2 {
text-align: center;
Expand All @@ -92,9 +103,10 @@ body {
}

.search {
width: 100%;
padding: 0.8em 1em;
text-align: center;
margin-bottom: 30px;
padding: 10px 20px;
border: 0;
border-radius: 5px;
outline: none;
Expand All @@ -104,25 +116,41 @@ body {
.format-list {
display: flex;
flex-flow: column nowrap;
gap: 1em;
width: 100%;
align-items: center;
background-color: white;
border-radius: 10px;
padding: 30px;
padding: 1.5em;
margin-bottom: 5vw;
}

.format-list button {
width: 80%;
margin: 5px 0;
padding: 10px;
color: black;
background-color: lightgray;
border: 0;
border-radius: 10px;
font-family: monospace;
word-break: break-word;
cursor: pointer;
width: 100%;
font-family: 'Nimbus Mono PS', 'Courier New', monospace;
@border-col: lighten(@accent, 20);
@shiftdown: 3px;
@shadow1: 0 @shiftdown 0 2px @border-col;
@border-shadow: 0 0 0 2px @border-col;
border-radius: 4px;
outline: none;
border: none;
padding: .7em 1.3em;

box-shadow: @shadow1, @border-shadow;
transition:
box-shadow 0.1s ease-out,
transform 0.1s ease;
&:hover {
@shadow1: 0 3px 0 2px @border-col;
box-shadow: @shadow1, @border-shadow;
transform: translateY(@shiftdown);
}
&:active {
@shadow1: inset 3px 3px 0 2px @border-col;
box-shadow: @shadow1, @border-shadow;
transform: translateY(@shiftdown);
}
}

button.selected {
Expand All @@ -131,25 +159,69 @@ button.selected {
font-weight: bold;
}

#convert-button {
#convert-container {
position: fixed;
left: 50%;
bottom: 5%;
transform: translateX(-50%);
font-size: 1.5rem;
padding: 10px 20px;
border: 0;
border-radius: 10px;
background-color: var(--highlight-color);
color: white;
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
z-index: 10;
}

#convert-button {
background: white;
font-weight: 600;
color: #444;
font-size: 1.5em;
padding: .5em 1em;
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
border: 2px solid #0003;
&:hover {
box-shadow: 0 4px 6px -1px var(--highlight-color-transparent), 0 2px 4px -2px var(--highlight-color-transparent);
transform: translateY(-2px);
}
&:active {
transform: scale(0.99);
}
&.disabled {
background: #eee;
color: #777;
}
}

button {
cursor: pointer !important;
}

.disabled {
filter: grayscale(1);
pointer-events: none;
}

#back-button {
display: none;
padding: .6em !important;
&:hover {
transform: translateY(-2px);
}
&:active {
transform: scale(0.99);
}
}

#convert-button, #back-button {
border-radius: 10px;
opacity: 1;
transition: opacity .4s ease, transform 0.2s cubic-bezier(.27,.43,.66,1.44), box-shadow .4s ease;
}

body:has(#popup-bg:not([style*='display: none'])) :is(#convert-button, #back-button){
transform: translateY(5px);
opacity: 0;
}

#popup-bg {
position: fixed;
left: 0;
Expand Down Expand Up @@ -207,4 +279,29 @@ button.selected {
font-size: 0.8rem;
padding: 10px;
}

#format-containers #to-container {
display: none;
}
#format-containers.mobile-step-to #from-container {
display: none;
}
#format-containers.mobile-step-to #to-container {
display: flex;
}

#format-containers.mobile-step-to ~ #convert-container #back-button {
display: block;
font-size: 1.5rem;
padding: 10px 14px;
border: 0;
background-color: var(--highlight-color);
color: white;
cursor: pointer;
line-height: 1;
}
#back-button:active {
opacity: 0.8;
}
}