lots of changes
Added a creation_time field to thinks - using the modified time on the filesystem wasn't reliable. Styled the login page. The index shows the most recent thinks at the top. Allow authentication by an Authorization header, with a token specified in settings.py. Lots of improvements to the editor, including showing the log, and a form to install Elm packages when editing .elm files. The Makefile for a project is automatically run each time a file is saved.
This commit is contained in:
parent
3d5c0c6c73
commit
500eb38774
13 changed files with 1474 additions and 396 deletions
|
@ -1,7 +1,19 @@
|
|||
import './code-editor.mjs';
|
||||
|
||||
export default async function init_app() {
|
||||
const flags = JSON.parse(document.getElementById('think-editor-data').textContent);
|
||||
flags.csrf_token = document.getElementById('csrftoken')?.textContent || '';
|
||||
const app = Elm.App.init({node: document.body, flags});
|
||||
}
|
||||
import './code-editor.mjs';
|
||||
|
||||
export default async function init_app() {
|
||||
const flags = JSON.parse(document.getElementById('think-editor-data').textContent);
|
||||
flags.csrf_token = document.getElementById('csrftoken')?.textContent || '';
|
||||
const app = Elm.App.init({node: document.body, flags});
|
||||
|
||||
app.ports.reload_preview.subscribe(() => {
|
||||
console.log('reload preview');
|
||||
const iframe = document.getElementById('preview-frame');
|
||||
if(iframe) {
|
||||
const src = iframe.src;
|
||||
iframe.src = "";
|
||||
setTimeout(() => {
|
||||
iframe.src = src;
|
||||
},10);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,201 +1,237 @@
|
|||
:root {
|
||||
--spacing: 1em;
|
||||
--half-spacing: calc(0.5 * var(--spacing));
|
||||
--double-spacing: calc(2 * var(--spacing));
|
||||
|
||||
--editor-size: 50%;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
min-height: 100vh;
|
||||
margin: 0;
|
||||
padding: var(--half-spacing);
|
||||
|
||||
& > header {
|
||||
padding: var(--spacing);
|
||||
& h1 {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
header {
|
||||
& #think-controls {
|
||||
display: flex;
|
||||
gap: var(--spacing);
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
#editor-size-input + output {
|
||||
width: 5em;
|
||||
}
|
||||
|
||||
.file-path {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
|
||||
.think-editor {
|
||||
display: flex;
|
||||
gap: var(--spacing);
|
||||
height: 100%;
|
||||
|
||||
& > #main-nav > nav {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing);
|
||||
|
||||
& #file-tree {
|
||||
margin: 0;
|
||||
overflow: auto;
|
||||
flex-grow: 1;
|
||||
|
||||
& > li {
|
||||
margin-top: var(--half-spacing);
|
||||
|
||||
& > a {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
& .dir {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
& .dir + .file {
|
||||
margin-top: var(--spacing);
|
||||
}
|
||||
}
|
||||
|
||||
& form {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 6em;
|
||||
align-content: start;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
& #make-log {
|
||||
& > pre {
|
||||
max-width: 20em;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& #log[open] {
|
||||
width: 80ch;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
& #editor {
|
||||
overflow: hidden;
|
||||
flex-grow: 1;
|
||||
flex-basis: var(--editor-size);
|
||||
max-height: 85vh;
|
||||
|
||||
& #editor-controls {
|
||||
display: flex;
|
||||
gap: var(--spacing);
|
||||
justify-content: space-between;
|
||||
|
||||
& > details {
|
||||
text-align: right;
|
||||
|
||||
& > summary {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
& button {
|
||||
margin: var(--half-spacing) 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& #code-editor {
|
||||
display: block;
|
||||
max-width: 50vw;
|
||||
padding-bottom: 10em;
|
||||
}
|
||||
}
|
||||
|
||||
& #preview {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&[open] {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
flex-basis: calc(100% - var(--editor-size));
|
||||
}
|
||||
|
||||
& > summary {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
& > iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
}
|
||||
|
||||
&[closed] > iframe {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#file-form {
|
||||
overflow: auto;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
@media (max-width: 100ch) {
|
||||
html {
|
||||
font-size: min(3vw, 16px);
|
||||
}
|
||||
.think-editor {
|
||||
flex-direction: column;
|
||||
overflow: visible;
|
||||
|
||||
& > * ~ * {
|
||||
border-top: medium solid #888;
|
||||
margin-top: var(--spacing);
|
||||
padding-top: var(--spacing);
|
||||
}
|
||||
|
||||
& nav {
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
|
||||
& form {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
& #file-tree {
|
||||
max-height: 7em;
|
||||
}
|
||||
}
|
||||
|
||||
& #editor {
|
||||
overflow: auto;
|
||||
& #code-editor {
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
|
||||
& #preview {
|
||||
height: 100vh;
|
||||
}
|
||||
}
|
||||
:root {
|
||||
--spacing: 1em;
|
||||
--half-spacing: calc(0.5 * var(--spacing));
|
||||
--double-spacing: calc(2 * var(--spacing));
|
||||
|
||||
--editor-size: 50%;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
color-scheme: light dark;
|
||||
font-family: sans-serif;
|
||||
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
min-height: 100vh;
|
||||
margin: 0;
|
||||
padding: var(--half-spacing);
|
||||
|
||||
& > header {
|
||||
padding: var(--spacing);
|
||||
& h1 {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body {
|
||||
background: black;
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
|
||||
header {
|
||||
& #think-controls {
|
||||
display: flex;
|
||||
gap: var(--spacing);
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
#editor-size-input + output {
|
||||
width: 5em;
|
||||
}
|
||||
|
||||
.file-path {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
|
||||
.think-editor {
|
||||
display: grid;
|
||||
gap: var(--spacing);
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
--col-1-width: auto;
|
||||
grid-template:
|
||||
"nav editor preview" min-content
|
||||
"log editor preview" 1fr
|
||||
/ var(--col-1-width) var(--editor-size) var(--preview-size)
|
||||
;
|
||||
|
||||
&:has(#main-nav[open], #log[open]) {
|
||||
--col-1-width: 20em;
|
||||
}
|
||||
|
||||
& > #main-nav {
|
||||
grid-area: nav;
|
||||
}
|
||||
& > #log {
|
||||
grid-area: log;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
& .dragging {
|
||||
background: red;
|
||||
}
|
||||
|
||||
& summary {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
& > #main-nav > nav {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing);
|
||||
|
||||
& #file-tree {
|
||||
margin: 0;
|
||||
overflow: auto;
|
||||
flex-grow: 1;
|
||||
|
||||
& > li {
|
||||
margin-top: var(--half-spacing);
|
||||
|
||||
& > a {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
& .dir {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
& .dir + .file {
|
||||
margin-top: var(--spacing);
|
||||
}
|
||||
}
|
||||
|
||||
& form {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 6em;
|
||||
align-content: start;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
& #make-log {
|
||||
& > pre {
|
||||
max-width: 20em;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& #editor {
|
||||
overflow: hidden;
|
||||
flex-grow: 1;
|
||||
flex-basis: var(--editor-size);
|
||||
max-height: 85vh;
|
||||
grid-area: editor;
|
||||
|
||||
& #editor-controls {
|
||||
display: flex;
|
||||
gap: var(--spacing);
|
||||
justify-content: space-between;
|
||||
|
||||
& > details {
|
||||
text-align: right;
|
||||
|
||||
& > summary {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
& button {
|
||||
margin: var(--half-spacing) 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& #code-editor {
|
||||
display: block;
|
||||
max-width: 50vw;
|
||||
padding-bottom: 10em;
|
||||
}
|
||||
}
|
||||
|
||||
& #preview {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
grid-area: preview;
|
||||
|
||||
&[open] {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
flex-basis: calc(100% - var(--editor-size));
|
||||
}
|
||||
|
||||
& > summary {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
& > iframe {
|
||||
width: 100%;
|
||||
height: calc(100% - 3em);
|
||||
border: none;
|
||||
}
|
||||
|
||||
&[closed] > iframe {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#file-form {
|
||||
overflow: auto;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
@media (max-width: 100ch) {
|
||||
html {
|
||||
font-size: min(3vw, 16px);
|
||||
}
|
||||
.think-editor {
|
||||
overflow: visible;
|
||||
grid-template:
|
||||
"nav"
|
||||
"log"
|
||||
"editor"
|
||||
"preview"
|
||||
;
|
||||
|
||||
& > * ~ * {
|
||||
border-top: medium solid #888;
|
||||
margin-top: var(--spacing);
|
||||
}
|
||||
|
||||
& nav {
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
|
||||
& form {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
& #file-tree {
|
||||
max-height: 7em;
|
||||
}
|
||||
}
|
||||
|
||||
& #editor {
|
||||
overflow: auto;
|
||||
& #code-editor {
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
|
||||
& #preview {
|
||||
height: 100vh;
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -18,6 +18,44 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
body.login {
|
||||
display: grid;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
height: 100svh;
|
||||
margin: 0;
|
||||
padding: var(--spacing);
|
||||
|
||||
& header {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
& form {
|
||||
display: grid;
|
||||
gap: var(--spacing);
|
||||
|
||||
& div {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-auto-flow: row;
|
||||
gap: var(--spacing);
|
||||
align-items: center;
|
||||
|
||||
& label {
|
||||
grid-column: 1;
|
||||
justify-self: end;
|
||||
}
|
||||
|
||||
& input {
|
||||
grid-column: 2;
|
||||
}
|
||||
}
|
||||
|
||||
grid-template-rows: 2em 2em 2em;
|
||||
}
|
||||
}
|
||||
|
||||
body.index {
|
||||
font-size: 20px;
|
||||
|
||||
|
@ -32,7 +70,7 @@ body.index {
|
|||
gap: var(--double-spacing);
|
||||
}
|
||||
|
||||
& #thinks-list {
|
||||
& .thinks-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--double-spacing);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue