Add simple Sourcehut-based theme

This commit is contained in:
Drew DeVault 2019-12-12 13:54:57 -05:00
parent b24cc85fb1
commit d0355fa0d8
11 changed files with 5967 additions and 4 deletions

View file

@ -3,10 +3,10 @@
<h1>koushin</h1>
<form method="post" action="/login">
<p>Username:</p>
<input type="text" name="username">
<p>Password:</p>
<input type="password" name="password">
<label for="username">Username:</label>
<input type="text" name="username" id="username"/>
<label for="password">Password:</label>
<input type="password" name="password" id="password"/>
<br><br>
<input type="submit" value="Login">
</form>

View file

@ -0,0 +1,9 @@
SRHT_PATH?=/usr/lib/python3.8/site-packages/srht
assets/style.css: scss/*.scss ${SRHT_PATH}/scss/*.scss
@mkdir -p assets/
sassc -I${SRHT_PATH}/scss scss/main.scss $@
all: assets/style.css
.DEFAULT_GOAL=all

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 192 512"><path d="M192 127.338v257.324c0 17.818-21.543 26.741-34.142 14.142L29.196 270.142c-7.81-7.81-7.81-20.474 0-28.284l128.662-128.662c12.599-12.6 34.142-3.676 34.142 14.142z"/></svg>

After

Width:  |  Height:  |  Size: 241 B

View file

@ -0,0 +1,79 @@
{{template "head.html"}}
{{template "nav.html"}}
<div class="container-fluid">
<div class="row">
<div class="col-md-12 header-tabbed">
<h2>INBOX</h2>
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link" href="/mailbox/INBOX" >Mail</a>
</li>
<li class="nav-item">
<a class="nav-link active" href="/compose">Compose</a>
</li>
</ul>
</div>
</div>
</div>
<div class="container">
<form method="post" class="col-md-12">
<input type="hidden" name="in_reply_to" value="{{.Message.InReplyTo}}">
<div class="row">
<div class="form-group col-md-6">
<label for="from">From</label>
<input
type="email"
name="from"
id="from"
class="form-control"
value="{{.Message.From}}" />
</div>
<div class="form-group col-md-6">
<label for="to">To</label>
<input
type="email"
name="to"
id="to"
class="form-control"
value="{{.Message.ToString}}"
multiple
{{ if not .Message.To }}
autofocus
{{ end }} />
</div>
</div>
<div class="form-group">
<label for="subject">Subject</label>
<input
type="text"
name="subject"
id="subject"
class="form-control"
value="{{.Message.Subject}}"
{{ if .Message.To }}
autofocus
{{ end }} />
</div>
<div class="form-group">
<textarea
name="text"
class="form-control"
cols="80"
rows="20"
>{{.Message.Text}}</textarea>
</div>
<div class="pull-right">
<a
href="/mailbox/INBOX"
class="btn btn-default"
>Cancel</a>
<button
type="submit"
class="btn btn-primary"
>Send email</button>
</div>
</form>
</div>
{{template "foot.html"}}

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#ffffff">
<title>koushin webmail</title>
<link rel="stylesheet" href="/themes/sourcehut/assets/style.css">
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QIGCC8n92KyhQAAAj1QTFRFAAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////anIwUQAAAL50Uk5TAAECAwQFBgcICQoLDA4PEBESExQVFhcYGRobHB0eHyAhIyQmJygpKistLzAzNDU2Nzg5Ozw9QEFDREZHSElLTE1OT1BRVFdYWVpbXF1eX2BhZGZnaGltbnBxdHV3eHp7fn+AgYKDhIWGh4iJio2TlJucnqGio6Smp6ipqqusrbCxsrO0tre4ury9vr/Cw8TFxsfIycrMzc7P0dLT1dbY2dvf4OLj5OXm5+jq6+zt7u/w8fL09fb3+Pn6+/z9/gNzyOkAAAABYktHRL6k3IPDAAAFwUlEQVQYGe3B+VtUVQAG4G9i0TQZZyA1S0JxydzDNFTUqXBfcylzS8UE21TMyjAQUQnFEi0BHQU3cAc0UGbm+9v65Zw7y70zc++dc3qenof3xZAhQ4b8T+V/uGn/kdrm1psdHTdbm2uP7Ns434//yLD5e+u7aOH+6T0ludBszGf1L5jC87rNBdDm9XXnw0wrfG71cOhQ9N0z2vTk20Ko9t5PYToQOj4FKr17IkKHwtUToMobVQN0of/rkVDik7t06c5yZC7/V1rqajq6f9vKQFlZYNW2A0cvdNPSL35kaPEDmgxerFiSjwQFZQebQzTpKkUmsg4xUX/Nijwk4V15aoAJIhVZcM13ngnatuQhJe/WNiY464VLE28xXsMCD9LyLDzLeMEiuDLzIeM0zIRNs88xTvcMuFDSx1htC+FA6XXG6pkLx0qeM8aLHdlwJGfnP4zRNw8OzexjjOaJcGzSn4zR8z4cmfiQUZF9WXAhuyLCqO4iOOC7xahni+BSWQ+jgl7YlnWeUR3FcG1qJ6MasmDXIUZdexMZGNvGqAOwaTGjrnqREd/fNERKYUvBAxqueZEhXzsNXX7Y8SsNHW8iY+M6afgZNnxKw7NiKDCtl4YA0nrjHqXIIiixjIY7I5FOFQ37oEglDZVIo+glpeYsKJJ9mdJAIVI7QenFRChT3E+pGim9F6G0AwrtohSeglR+otSWDYVygpSqkUJRmNJCKLWEUmgCkvuOUgPU8vxO6TCSev0ZpZlQ7ANKj4YhmXWUGqBcI6UVSOY8pQVQbhGlM0hiTJhCmwfKeW5QCPlh7TNKW6DBdkobYa2eQn8eNPC9pPAbLA17QaEGWtRS6MuBlfmUVkCLtZTmwspeCoN50MIXprATVuopXIQmLRROwUoXhQpoUkXhNizkU1oCTZZRyoPZh5Tyock4SnNgtolCF3TxPKKwBmb7KTRBm0sUdsPsCIWj0OY4hR9gVkthP7SppHASZs0UtkGbLyg0wqyVwkpos4FCC8xuUghAm3IK7TDroFAGbQIUgjDroFAGbQIUgjC7SSEAbcoptMOslcIqaLOBQgvMmilsgzY7KDTCrJbCAWhTReEkzI5QOAptfqTwPcz2UbgAbS5R2AWzjRS6oYvnMYXVMJtPqQCavEVpNsz8lMqgyXJKo2DhPoWD0OQwhU5YOU2hGZpcoVADK3sohLzQwh+h8CWslFBaCS3WUZoDK7nPKZyCFnUUerNh6TSFAS808L+iUANrmylthQafU1oPawVhCm0eKOcJUhgcjSTOUVoI5RZTqkMyqymdhXJNlMqRzPAnlGZDsRJKD3OR1LeUzkEtTxOlSiRXGKL0EZRaSmlwPFI4Tul6DhTKvUXpGFKZEqa0EwrtoRQqRkrVlP6ZBGUmD1A6htQm9FP6IxuK5Fyl1P8O0viahgoo8g0NB5HOyDuUImVQ4mMabo9AWgEaeqZCgel9NCyFDb/Q0DkWGXv7Lg0nYIe/i4Y2HzKUf4OGe6NhS2mEhr98yEh+Kw3hBbCpglHt45CB8TcY9RXsyjrLqM5pcG36XUadfg22eYOM6l0Glz7uY9T1UXCg6AFjHMqGCznfMMb9Qjgyo4cxLhfDsclXGePpdDg0r48x+nflwJHcPQOM0TsLjs3rYazgEtjnWXqLsZ7Oggszuhnn9w9gU0kT49yfDleKgozXuMiDtDyLmxjveiFc8jYwwY3tPqTk/zzIBPWj4FpWRYQJXtau9SEJ/7q6V0wQ/uo1ZKK0iybhlqplYxHP89byw1ciNLm3ABny/0xLjy4dr/xiQ3kgUL5hR9WPlx7T0onRyFzgDl26vRRKjKwcoAv9B0dAlcLqMB0KH3sHKk2pDtGBwWPFUG3C4Ue06WHleOgwbMWZENMarCvPhTb+jb/1MYXemvWjoVnO3J2nbtNCZ82Xc7LxH8mbs2b3DycbW9qDwfaWxpPf71o9exSGDBky5P/pX9F6dsCMuJp+AAAAAElFTkSuQmCC" />
</head>
<body>

View file

@ -0,0 +1,37 @@
{{template "head.html"}}
<nav class="container navbar navbar-light navbar-expand-sm">
<div class="col-md-12">
<a class="navbar-brand" href="/">
koushin
<span class="text-danger">webmail</span>
</a>
</div>
</nav>
<div class="container">
<form method="post" action="/login" class="col-md-6">
<div class="form-group">
<label for="username">Username</label>
<input
class="form-control"
type="text"
name="username"
id="username"
autofocus />
</div>
<div class="form-group">
<label for="password">Password</label>
<input
class="form-control"
type="password"
name="password"
id="password" />
</div>
<button
type="submit"
class="btn btn-primary"
>Log in</button>
</form>
</div>
{{template "foot.html"}}

View file

@ -0,0 +1,84 @@
{{template "head.html"}}
{{template "nav.html"}}
<!-- TODO: Share tabs if reasonable -->
<div class="container-fluid">
<div class="row">
<div class="col-md-12 header-tabbed">
<h2>{{.Mailbox.Name}}</h2>
<ul class="nav nav-tabs">
<li class="nav-item">
<a
class="nav-link active"
href="/mailbox/{{.Mailbox.Name | pathescape }}"
>Mailbox</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/compose">Compose</a>
</li>
</ul>
</div>
</div>
</div>
<div class="container-fluid mailbox-container">
<div class="row">
<div class="col-md-2 mailboxes-column">
<ul class="nav flex-column">
{{$current := .Mailbox }}
{{range .Mailboxes}}
<li class="nav-item">
<a
{{ if eq $current.Name .Name }}
class="nav-link active"
{{ else }}
class="nav-link"
{{ end }}
href="/mailbox/{{.Name | pathescape}}"
>{{.Name}}</a>
</li>
{{end}}
</ul>
</div>
<div class="col-md-10 messages-column">
{{if .Messages}}
<ul class="nav flex-column">
{{range .Messages}}
<li class="nav-item">
<a
class="nav-link"
href="/message/{{$.Mailbox.Name | pathescape}}/{{.Uid}}?part={{.TextPartName}}"
>
<span class="text-muted date">
{{ .Envelope.Date.Format "Mon Jan 02 15:04" }}
</span>
<span class="text-normal from">
{{ range .Envelope.From }}
{{ .PersonalName }}
{{ end }}
</span>
{{if .Envelope.Subject}}
{{.Envelope.Subject}}
{{else}}
(No subject)
{{end}}
</a></li>
{{end}}
</ul>
<p>
{{if ge .PrevPage 0}}
<a href="?page={{.PrevPage}}">Prev</a>
{{end}}
{{if and (ge .PrevPage 0) (ge .NextPage 0)}}·{{end}}
{{if ge .NextPage 0}}
<a href="?page={{.NextPage}}">Next</a>
{{end}}
</p>
{{else}}
<p>Mailbox is empty.</p>
{{end}}
</div>
</div>
</div>
{{template "foot.html"}}

View file

@ -0,0 +1,86 @@
{{template "head.html"}}
{{template "nav.html"}}
<div class="container-fluid">
<div class="row">
<div class="col-md-12 header-tabbed">
<h2 style="margin-bottom: 1rem;" class="d-block">
{{if .Message.Envelope.Subject}}
{{.Message.Envelope.Subject}}
{{else}}
(No subject)
{{end}}
</h2>
<div class="container message-tabs">
<ul class="nav nav-tabs">
<li class="nav-item">
<a class="nav-link active" href="#">View message</a>
</li>
<li class="nav-item">
<a
class="nav-link"
href="{{.Message.Uid}}/reply?part={{.PartPath}}"
>Reply</a>
</li>
<li class="mr-auto d-none d-sm-flex"></li>
<li class="nav-item">
<a
class="nav-link"
href="/mailbox/{{.Mailbox.Name | pathescape}}?page={{.MailboxPage}}"
>
<span class="icon icon-caret-left">
{{template "caret-left.html"}}
</span>
Back
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
{{define "message-part-tree"}}
{{/* nested templates can't access the parent's context */}}
{{$ = index . 0}}
{{with index . 1}}
<a
class="nav-link"
{{if .IsText}}
href="{{$.Message.Uid}}?part={{.PathString}}"
{{else}}
href="{{$.Message.Uid}}/raw?part={{.PathString}}"
{{end}}
>
{{if eq $.PartPath .PathString}}<strong>{{end}}
{{.String}}
{{if eq $.PartPath .PathString}}</strong>{{end}}
</a>
{{if gt (len .Children) 0}}
<ul class="nav flex-column">
{{range .Children}}
<li class="nav-item">{{template "message-part-tree" (tuple $ .)}}</li>
{{end}}
</ul>
{{end}}
{{end}}
{{end}}
<div class="container message-container">
<div class="row">
<div class="col-md-10 body-column">
{{if .Body}}
<pre>{{.Body}}</pre>
{{else}}
<p>Can't preview this message part.</p>
<a href="{{.Message.Uid}}/raw?part={{.PartPath}}">Download</a>
{{end}}
</div>
<div class="col-md-2 parts-column">
{{template "message-part-tree" (tuple $ .Message.PartTree)}}
</div>
</div>
</div>
{{template "foot.html"}}

View file

@ -0,0 +1,14 @@
<nav class="container-fluid navbar navbar-light navbar-expand-sm">
<a class="navbar-brand" href="/">
koushin
<span class="text-danger">webmail</span>
</a>
<ul class="navbar-nav mr-auto d-none d-sm-flex">
<!-- TODO: Does anything go here? -->
</ul>
<div class="login">
<span class="navbar-text">
<a href="/logout">Log out</a>
</span>
</div>
</nav>

View file

@ -0,0 +1,95 @@
@import "base";
html, body {
height: 100%;
min-height: 100%;
}
body {
display: flex;
flex-direction: column;
padding: 0;
}
.header-tabbed {
margin-bottom: 0;
h2 {
line-height: 1;
}
}
.nav.flex-column {
.nav-link {
padding: 0.1rem 15px 0.1rem 30px;
&:hover, &.active {
background: #ddd;
}
}
.nav.flex-column {
margin-left: 1rem;
}
}
.mailbox-container, .message-container {
padding: 0;
flex-grow: 1;
display: flex;
& > .row {
flex-grow: 1;
}
}
.mailboxes-column {
border-right: 3px #ddd solid;
padding: 0;
}
.messages-column {
padding: 0;
.nav.flex-column .nav-link {
padding: 0.1rem 15px 0.1rem 15px;
}
.date {
min-width: 11rem;
display: inline-block;
text-align: right;
}
.from {
min-width: 12rem;
display: inline-block;
}
}
.body-column {
border-right: 3px #ddd solid;
pre {
background: transparent;
max-width: 972px; // HACK
overflow-x: auto;
margin-bottom: 0;
}
}
.parts-column {
padding-left: 0;
.nav.flex-column .nav-link {
padding: 0.1rem 15px 0.1rem 15px;
}
}
.text-normal {
color: $black;
}
.message-tabs {
padding: 0;
}