diff options
author | Jannis M. Hoffmann <jannis@fehcom.de> | 2023-08-17 11:36:55 +0200 |
---|---|---|
committer | Jannis M. Hoffmann <jannis@fehcom.de> | 2023-08-17 11:36:55 +0200 |
commit | 1229bb6a838e96eb52be7aa1cac8d692746bc783 (patch) | |
tree | 20a337622a62e43f9ac4baf6d609de5d3891cb84 | |
parent | 97d10a54426d2df2de1c765948989dfc88a316eb (diff) |
convert to bulma css framework
24 files changed, 779 insertions, 609 deletions
diff --git a/css/style.css b/css/style.css deleted file mode 100644 index fe26d46..0000000 --- a/css/style.css +++ /dev/null @@ -1,145 +0,0 @@ -@import "purecss/build/pure.css"; -@import "purecss/build/grids-responsive.css"; - -:root { - --jwm-color-back: #eee; - --jwm-color-front: #ddd; - --jwm-color-alt: #dede95; -} - -body { - padding: 1rem; -} - -a { - text-decoration-line: none; -} - -a:hover { - text-decoration-line: underline; -} - -footer { - text-align: center; - margin-top: 2rem; -} - -.pagination-box { - list-style: none; - padding-left: 0px; - display: flex; -} - .pagination-box > li > a, .pagination-box > li > span { - border: 1px solid blue; - text-decoration: none; - padding: 0.5em; - display: block; - margin-left: -1px; - background-color: white; - } - .pagination-box > li > a:hover { - background-color: #eee; - } - .pagination-box > li > a.disabled { - pointer-events: none; - cursor: default; - background-color: var(--jwm-color-back); - } - .pagination-box > li > a.current { - pointer-events: none; - cursor: default; - background-color: lightblue; - } - -.jwm-base { - background-color: var(--jwm-color-back); - border-radius: 5px; - max-width: 960px; - margin: 0 auto; - padding: 1rem; -} - - .jwm-base > nav { - margin-top: 1rem; - } - -.jwm-warning { - background-color: orange; - padding: 1rem; -} - -.jwm-post { - background-color: var(--jwm-color-front); - border-radius: 5px; - padding: 0.5rem 1rem; -} - -.jwm-nav { - background-color: var(--jwm-color-back); - border-radius: 5px; - padding: 0 1rem; - margin: 10px 0; -} - -.jwm-mail-header { - background-color: var(--jwm-color-front); - padding: 1rem; -} - -.jwm-mail-body { - width: 90%; - margin: 1rem auto; - padding: 10px; -} - -iframe.jwm-mail-body-text-html { - width: 100%; - height: 400px; -} - -.jwm-mail-body-text-plain { - background-color: var(--jwm-color-alt); - /* word-wrap: break-word; */ - padding: 5pt; -} - - .jwm-mail-body-text-plain > pre { - font-family: sans-serif; - overflow: auto; - } - -/* make sure this lines up with pure-md class */ -@media screen and (max-width: 48em) { - .hide-small { - display: none; - } -} - -#displayheaders { - max-width: 1280px; - margin: 0 auto; - padding: 1rem; -} - - #mail-headers { - width: 100%; - margin: 15px 0; - } - - #empty-folder { - text-align: center; - } - -#login { - max-width: 640px; -} - - #login > h1 { - text-align: center; - } - - #login > form { - background-color: var(--jwm-color-front); - padding-top: 1rem; - padding-left: 6px; - } diff --git a/lang/de.lang b/lang/de.lang deleted file mode 100644 index c508854..0000000 --- a/lang/de.lang +++ /dev/null @@ -1,52 +0,0 @@ -login = anmelden -userid = nuzerkennung -passwd = passwort -failed = fehlgeschlagen -about = über -mbox_size = Mailboxgröße -and = und -subject = betreff -version = version -from = von -to = für -cc = CC -date = datum -size = größe -content-type = inhaltsart -send_to = senden an -answer_to = Antworten gehen an -content = inhalt -check_all = alle markieren -move = verschieben -nr = nummer -status = mehrteilig -logout = abmelden -compose = schreiben -search = suche -of = von -messages = nachrichten -new = neu -mbox_size = mailboxgröße -home = Übersicht -no = nein -yes = ja -page = seite -next = nächste -last = letzte -first = erste -previous = vorherige -sender = gesendet von -back = zurück - -# Mailboxen -Queue = Warteschlange -Drafts = Vorlagen -Home = Wurzelverzeichnis - -# Fehler -no_session = Keine aktive Sitzung. -no_folder = Dieses Verzeichnis gibt es nicht. -error_send = Die Nachricht konnte nicht gesendet werden. -succ_send = Die Nachricht wurde verschikt. -succ_move = Nachrichten wurden verschoben. -empty_folder = Dies Verzeichnis ist leer. diff --git a/lang/en.lang b/lang/en.lang deleted file mode 100644 index 6d0d360..0000000 --- a/lang/en.lang +++ /dev/null @@ -1,52 +0,0 @@ -messages = messages -from = from -to = to -cc = cc - -failed = failed -search = search -move = move -and = and -content-type = content-type -send_to = send to -answer_to = answer to -content = content -check_all = check all -nr = number -mbox_size = Mailbox size -about = about -version = version -first = first -previous = previous -next = next -last = last -yes = yes -no = no -userid = user-id -passwd = password -login = login -of = of -new = new -compose = compose -logout = logout -page = page -status = multipart -date = date -sender = sender -subject = subject -size = size -home = home -back = back - -no_session = You have no active session! -no_folder = "no such folder" -error_send = 'Error when sending message' -succ_send = 'Message has been send' -succ_move = 'Messages have been moved' -empty_folder = This folder is empty. - -INBOX = inbox -SENT = sent -TRASH = trash -SAVED = saved -Home = home diff --git a/lang/i18n.pod b/lang/i18n.pod deleted file mode 100644 index 8f7035b..0000000 --- a/lang/i18n.pod +++ /dev/null @@ -1,87 +0,0 @@ -=encoding utf-8 - -=head1 SYNOPSIS - - @@ de.lang - yes = ja - no = nein - -=head1 DESCRIPTION - -Place your translation files here. -Use the two letter language naming convention. -Use lower case phrases as they will be capitalized by the templates. - -=head1 INTERNATIONALIZATION AND LOCALIZATION - -=head2 Single Words - - Phrase Description - -------------------------- - failed an operation failed - and - no - yes - messages mails - of page x *of* n - page a page consisting of multiple mails - login header name - userid form field label - passwd form field label - about about page name - mbox_size mail box size in byte - version version translation for JWebmail version - subject mail field subject - from mail field from - to mail field to - cc mail field cc - date mail field date - size mail size - content-type mail field content-type - sender mail field sender - answer_to mail field reply back to - send_to write mail to - content the mail body rendered as html - check_all tick/untick all mails for move - move move mails to a different folder - nr row number, column description - status whether a mail is multipart - logout close session - compose write an email - search search in mails - new amount of new mails - home back button to read the main folder - first first page - previous previous page - next next page - last last page - -=head2 Phrases - - succ_send tell the user the mail was send successfully - succ_move tell the user the mails where moved successfully - empty_folder tell the user the folder is empty - -=head2 Error Messages - - no_session the session has expired or did not exist at all - no_folder the selected mail folder does not exists - error_send error sending the message - -=head2 Formats - -Currently there are no formats. - -=head2 Other - - Common Mail Folders - --- - Queue - Drafts - Home - -=head1 SEE OTHER - -L<JWebmail::Plugin::I18N> - -=cut
\ No newline at end of file diff --git a/lib/JWebmail/Plugin/Paginate.pm b/lib/JWebmail/Plugin/Paginate.pm index 9b39617..b4564b7 100644 --- a/lib/JWebmail/Plugin/Paginate.pm +++ b/lib/JWebmail/Plugin/Paginate.pm @@ -79,11 +79,11 @@ sub paginate { } sub make_link { - my ($c, $txt, $to) = @_; + my ($c, $txt, $to, %args) = @_; return $c->link_to( $txt => $c->url_with->query({start => $c->stash('pgn')->{$to}[0]}), - class => ($c->param('start')//0) == $c->stash('pgn')->{$to}[0] ? 'disabled' : '', + class => ($c->param('start')//0) == $c->stash('pgn')->{$to}[0] ? join(' ', $args{class}, $args{class_disabled}) : $args{class}, ); } diff --git a/lib/JWebmail/View/RenderMail.pm b/lib/JWebmail/View/RenderMail.pm index 90534dc..387e586 100644 --- a/lib/JWebmail/View/RenderMail.pm +++ b/lib/JWebmail/View/RenderMail.pm @@ -112,7 +112,7 @@ sub render_message { warn "unkown mime-subtype $subtype" unless $subtype eq 'rfc822'; - my $R .= '<div clas="jwm-mail">'; + my $R .= '<div class="jwm-mail">'; $R .= '<dl class="jwm-mail-header">'; $R .= '<dt>' . xml_escape(uc $self->c->l('subject')) . '</dt>'; @@ -127,8 +127,6 @@ sub render_message { $R .= '<dd>' . to_mime_type($msg->{head}{mime}) . "</dd>\n"; $R .= "</dl>\n"; - #my $content = ref $msg->{body} && exists $msg->{body}{parts} ? $msg->{body}{parts} : $msg->{body}; - $R .= $self->mime_render(to_mime_types($msg->{head}{mime}), $msg->{body}, [@$path, 0]); return $R . "</div>\n"; @@ -149,7 +147,7 @@ sub mime_render { my $renderer = $MIME_Render_Subs{"$maintype/$subtype"} || $MIME_Render_Subs{$maintype}; unless ($renderer) { - return "<p>Unsupported MIME type of <code>$maintype/$subtype</code>.</p>\n"; + return qq(<p class="jwm-body-unsupported">Unsupported MIME type of <code>$maintype/$subtype</code>.</p>\n); } return $renderer->($self, $subtype, $content, $path); diff --git a/package-lock.json b/package-lock.json index 3b222a9..43774d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,12 +9,13 @@ "version": "1.2.2", "license": "GPL-3.0", "dependencies": { - "bulma": "^0.9.4", "crypto-js": "^4.1.1", "purecss": "^3.0.0" }, "devDependencies": { - "esbuild": "^0.17.12" + "bulma": "^0.9.4", + "esbuild": "^0.17.12", + "sass": "^1.60.0" } }, "node_modules/@esbuild/android-arm": { @@ -369,10 +370,72 @@ "node": ">=12" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/bulma": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.4.tgz", - "integrity": "sha512-86FlT5+1GrsgKbPLRRY7cGDg8fsJiP/jzTqXXVqiUZZ2aZT8uemEOHlU1CDU+TxklPEZ11HZNNWclRBBecP4CQ==" + "integrity": "sha512-86FlT5+1GrsgKbPLRRY7cGDg8fsJiP/jzTqXXVqiUZZ2aZT8uemEOHlU1CDU+TxklPEZ11HZNNWclRBBecP4CQ==", + "dev": true + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } }, "node_modules/crypto-js": { "version": "4.1.1", @@ -416,10 +479,167 @@ "@esbuild/win32-x64": "0.17.12" } }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/immutable": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", + "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==", + "dev": true + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/purecss": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/purecss/-/purecss-3.0.0.tgz", "integrity": "sha512-IdYbGwbmuA7Hy9ACIO1q7ks4xGLcJSVHxJT2BXIz2c4Ve1aSrNU5bAzA1ILT4Gmdy5K59ruWoRPf9WvJZU5fbA==" + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/sass": { + "version": "1.60.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.60.0.tgz", + "integrity": "sha512-updbwW6fNb5gGm8qMXzVO7V4sWf7LMXnMly/JEyfbfERbVH46Fn6q02BX7/eHTdKpE7d+oTkMMQpFWNUMfFbgQ==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } } }, "dependencies": { @@ -577,10 +797,52 @@ "dev": true, "optional": true }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "bulma": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.9.4.tgz", - "integrity": "sha512-86FlT5+1GrsgKbPLRRY7cGDg8fsJiP/jzTqXXVqiUZZ2aZT8uemEOHlU1CDU+TxklPEZ11HZNNWclRBBecP4CQ==" + "integrity": "sha512-86FlT5+1GrsgKbPLRRY7cGDg8fsJiP/jzTqXXVqiUZZ2aZT8uemEOHlU1CDU+TxklPEZ11HZNNWclRBBecP4CQ==", + "dev": true + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } }, "crypto-js": { "version": "4.1.1", @@ -617,10 +879,118 @@ "@esbuild/win32-x64": "0.17.12" } }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "immutable": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz", + "integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, "purecss": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/purecss/-/purecss-3.0.0.tgz", "integrity": "sha512-IdYbGwbmuA7Hy9ACIO1q7ks4xGLcJSVHxJT2BXIz2c4Ve1aSrNU5bAzA1ILT4Gmdy5K59ruWoRPf9WvJZU5fbA==" + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "sass": { + "version": "1.60.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.60.0.tgz", + "integrity": "sha512-updbwW6fNb5gGm8qMXzVO7V4sWf7LMXnMly/JEyfbfERbVH46Fn6q02BX7/eHTdKpE7d+oTkMMQpFWNUMfFbgQ==", + "dev": true, + "requires": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + } + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } } } } diff --git a/package.json b/package.json index db91a3f..ea2861a 100644 --- a/package.json +++ b/package.json @@ -2,12 +2,16 @@ "name": "jwebmail", "version": "1.2.2", "description": "JWebmail - A Webmail Server", - "directories": { - }, + "directories": {}, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "build": "esbuild --bundle css/style.css src/login_cram.js --outdir=public/", - "build-release": "esbuild --bundle --minify css/style.css src/login_cram.js --outdir=public/" + "build": "npm run build-js && npm run build-css && npm run build-sass", + "build-js": "esbuild --bundle src/login_cram.js src/displayheaders.js --outdir=public/src/", + "build-css": "esbuild --bundle css/my_pure.css --outdir=public/css/", + "build-sass": "sass --update --load-path=node_modules/ scss/my_bulma.scss public/css/my_bulma.css", + "build-release": "esbuild --bundle --minify css/*.css src/*.js --outdir=public/ && sass --update --no-source-maps --style=compress --load-path=node_modules/ scss/my_bulma.scss public/css/my_bulma.css", + "watch-sass": "sass --watch --load-path=node_modules/ scss/my_bulma.scss public/css/my_bulma.css", + "watch-esbuild": "esbuild --watch --bundle --sourcemap css/*.css src/*.js --outdir=public/" }, "repository": { "type": "git", @@ -25,10 +29,12 @@ }, "homepage": "https://github.com/D1CED/JWebmail#readme", "dependencies": { - "crypto-js": "^4.1.1", - "purecss": "^3.0.0" + "crypto-js": "^4.1.1" }, "devDependencies": { - "esbuild": "^0.17.12" + "bulma": "^0.9.4", + "esbuild": "^0.17.12", + "sass": "^1.60.0", + "purecss": "^3.0.0" } } diff --git a/scss/my_bulma.scss b/scss/my_bulma.scss new file mode 100644 index 0000000..01cdc4b --- /dev/null +++ b/scss/my_bulma.scss @@ -0,0 +1,46 @@ +@use "bulma/bulma"; + +.jwm-new-mail > .media-content { + @extend .has-text-weight-semibold; +} + +dl.jwm-mail-header { + $left-xx: 130px; + + & dt { + font-weight: bold; + @media screen and (min-width: bulma.$desktop) { + float: left; + clear: left; + text-align: right; + width: $left-xx; + } + } + & dd { + @media screen and (min-width: bulma.$desktop) { + margin-left: #{$left-xx + 10px}; + } + margin-left: bulma.$size-7; + } +} + +.jwm-mail { + @extend .box; +} + +.jwm-mail-header { + @extend .block; +} + +.jwm-mail-body { + @extend .block; +} + +iframe.jwm-mail-body-text-html { + width: 100%; + height: 400px; +} + +.jwm-mail-body-text-plain { + @extend .block; +} diff --git a/src/displayheaders.js b/src/displayheaders.js new file mode 100644 index 0000000..3c0936a --- /dev/null +++ b/src/displayheaders.js @@ -0,0 +1,35 @@ +function toggle_navbar() { + // Get the target from the "data-target" attribute + const target = this.dataset.target; + const $target = document.getElementById(target); + + // Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu" + this.classList.toggle('is-active'); + $target.classList.toggle('is-active'); +} + +function sort_select_submit() { + this.children[0].form.submit(); +} + +function check_all() { + const setTo = this.checked; + const chkbox = document.getElementsByClassName('jwm-mail-checkbox'); + + for (const m of chkbox) + m.checked = setTo; +} + +document.addEventListener("DOMContentLoaded", function() { + { + const sort_select = document.getElementById("sort"); + const current_option_name = new URL(document.location).searchParams.get("sort"); + if (current_option_name) + sort_select.value = current_option_name; + } + + document.getElementById("sort-select").addEventListener("change", sort_select_submit); + document.getElementById("navbar-toggle").addEventListener("click", toggle_navbar); + document.getElementById("check-all").addEventListener("click", check_all); +}); + diff --git a/templates/displayheaders/_bot_nav.html.ep b/templates/displayheaders/_bot_nav.html.ep index 454941b..a6d089c 100644 --- a/templates/displayheaders/_bot_nav.html.ep +++ b/templates/displayheaders/_bot_nav.html.ep @@ -1,36 +1,39 @@ -<div class="pure-g jwm-nav"> +<div class="columns"> - <div class="pure-u-3-4"> - <div class="pure-u-1 pure-u-md-1-2"> + <div class="column"> %= include 'displayheaders/_pagination1' - </div><div class="pure-u-1 pure-u-md-1-2"> + </div> + + <div class="column"> % if (grep {$_ ne $folder} @$mail_folders) { - %= form_for move => (id => 'move-mail') => (class => 'pure-form') => begin - <fieldset> - %= label_for 'select-folder' => l('move to') - %= select_field folder => [map { $_ ? $_ : l 'Home' } grep {$_ ne $folder} @$mail_folders] => (id => 'select-folder') - %= csrf_field - %= submit_button l('move') => (class => 'pure-button') - </fieldset> + %= form_for move => (id => 'move-mail') => begin + + <div class="field is-horizontal"> + <div class=field-label> + %= label_for 'select-folder' => l('move to') => (class => 'label') + </div> + <div class=field-body> + <div class="field is-grouped"> + <div class=control> + <div class='select'> + %= select_field folder => [map { $_ ? $_ : l 'Home' } grep {$_ ne $folder} @$mail_folders] + </div> + </div> + %= csrf_field + <div class=control> + %= submit_button l('move') => (class => 'button') + </div> + </div> + </div> + </div> + % end % } </div> - </div> - <div class="pure-u-1-4"> + <div class="column has-text-right"> <label for=allbox><%= l 'check all' %></label> - <input name=allbox type=checkbox onclick="check_all(this)"> + <input name=allbox type=checkbox id=check-all> </div> </div> - -<script type="text/javascript"> -function check_all(box) { - const setTo = box.checked; - const mails = document.getElementById('mail-headers').tBodies[0].rows; - - for (const m of mails) { - m.lastElementChild.children[0].checked = setTo; - } -} -</script> diff --git a/templates/displayheaders/_folders.html.ep b/templates/displayheaders/_folders.html.ep index b341768..457a838 100644 --- a/templates/displayheaders/_folders.html.ep +++ b/templates/displayheaders/_folders.html.ep @@ -1,29 +1,44 @@ -<div id=display-folders class="pure-g jwm-nav"> +<div class="columns"> - <div class="pure-u-1-1 pure-u-md-1-2"> - <nav class="pure-menu pure-menu-horizontal"> + <div class="column"> + <nav class="navbar"> - <strong class="pure-menu-heading"> - %= l($folder || '_mailbox_root') - </strong> + <div class="navbar-brand"> + <span class=navbar-item> + <%= l($folder || '_mailbox_root') %> + </span> + <a role="button" class="navbar-burger" data-target="navMenu" id=navbar-toggle> + <span aria-hidden="true"></span> + <span aria-hidden="true"></span> + <span aria-hidden="true"></span> + </a> + </div> - <ul class="pure-menu-list"> + <div class="navbar-menu" id="navMenu"> + <div class=navbar-start> % for (grep {$_ ne $folder} @$mail_folders) { - <li class="pure-menu-item"> - %= link_to '' => {folder => $_} => (class => 'bright') => begin + %= link_to '' => {folder => $_} => (class => 'navbar-item') => begin %= l($_ || '_mailbox_root') % end - </li> % } - </ul> - + </div> + </div> </nav> </div> - <p class="pure-u-1-1 pure-u-md-1-2"> - <%= l('[_1] of [_2] messages', $pgn->{this_page}[1] - $pgn->{this_page}[0], $pgn->{total_items}) %>\ - <%= l(', [_1] new', $total_new_mails) if $total_new_mails > 0 =%> - <%= l(' - mailbox size: [_1]', $v->print_sizes10($total_size)) if $total_size %> - </p> + <div class="column"> + <div class="columns is-multiline is-mobile"> + <span class="column is-half-mobile has-text-centered"><%= l('[_1] of [_2] messages', $pgn->{this_page}[1] - $pgn->{this_page}[0], $pgn->{total_items}) %> + </span> + <span class="column is-half-mobile has-text-centered"><%= l('[_1] new', $total_new_mails) if $total_new_mails > 0 =%> + </span> + <span class="column has-text-centered"> + % if ($total_size) { + %= l('mailbox size: ') + %= $v->print_sizes10($total_size) + % } + </span> + </div> + </div> </div> diff --git a/templates/displayheaders/_main_table.html.ep b/templates/displayheaders/_main_table.html.ep index 06bbbfc..e06e925 100644 --- a/templates/displayheaders/_main_table.html.ep +++ b/templates/displayheaders/_main_table.html.ep @@ -9,104 +9,43 @@ % end -<table id=mail-headers class="pure-table pure-table-horizontal"> +<section class="box"> - <thead> - <tr id=sort> - <th class="hide-small"> - # - </th> - - <th> - <div class="pure-g"> - - %# $sort_param->('status'); - - <div class="pure-u-1 pure-u-md-4-24"> - %= $sort_param->('date'); - </div> - -% if ($folder ne "SENT") { - <div class="pure-u-1 pure-u-md-8-24"> - %= $sort_param->('sender'); - </div> -% } -% else { - <th class=sort-param> - %= link_to url_with->query(sort => param('sort') ne '!sender' ? 'sender' : '!sender' ) => begin - %= ucfirst l 'recipient' - % if (param('sort') eq "sender") { - %= image '/down.gif' => (width => 12) => (height => 12) => (border => 0) => (alt => 'v') - % } - % elsif (param('sort') eq "recipient_rev") { - %= image '/up.gif' => (width => 12) => (height => 12) => (border => 0) => (alt => '^') - % } - % end - </th> -% } - - <div class="pure-u-1 pure-u-md-12-24"> - %= $sort_param->('subject'); - </div> - - </div> - </th> - - <th class="hide-small"> - %= $sort_param->('size'); - </th> - - <th> - <input type=checkbox checked=1 disabled=1> - </th> - </tr> - </thead> - - <tbody> % foreach my $msgnum ($pgn->{first_item} .. $pgn->{last_item}) { % my $msg = $msgs->[$msgnum - $pgn->{first_item}]; - %= tag tr => (class => $msg->{unread} ? 'new-mail' : '') => (id => $msg->{message_handle}) => begin - <td class="hide-small" style="text-align: right"> + %= tag div => (class => $msg->{unread} ? 'media jwm-new-mail' : 'media') => (id => $msg->{message_handle}) => begin + <div class="media-left is-hidden-mobile"> %= $msgnum + 1 - </td> - - <td> - <div class="pure-g"> - - <!-- - <div class="pure-u-1-4"> - %# ucfirst($msg->{head}{mime}{content_maintype} eq 'multipart' ? l('yes') : l('no')); - </div> - --> - - <div class="pure-u-1 pure-u-md-4-24"> - % my $date = $v->parse_iso_date($msg->{head}{date}); - %= join('/', $date->{mday}, $date->{month}, $date->{year}) . " $date->{hour}:$date->{min}"; - </div> - - <div class="pure-u-1 pure-u-md-8-24"> - <%= $msg->{head}{sender}[0]{display_name} || $msg->{head}{sender}[0]{address} || - $msg->{head}{from}[0]{display_name} || $msg->{head}{from}[0]{address}; %> - </div> + </div> - <div class="pure-u-1 pure-u-md-12-24"> - %= link_to $msg->{head}{subject} || '_' => read => {id => $msg->{message_handle}} + <div class="media-content"> + <div class=" columns is-gapless is-multiline"> + <div class="column is-10"> + <%= $msg->{head}{sender}[0]{display_name} || $msg->{head}{sender}[0]{address} || + $msg->{head}{from}[0]{display_name} || $msg->{head}{from}[0]{address}; %> + </div> + + <div class="column is-2"> + % my $date = $v->parse_iso_date($msg->{head}{date}); + %= join('/', $date->{mday}, $date->{month}, $date->{year}) . " $date->{hour}:$date->{min}"; + </div> + + <div class="column is-10"> + %= link_to $msg->{head}{subject} || '_' => read => {id => $msg->{message_handle}} + </div> + + <div class="column is-2"> + %= $v->print_sizes10($msg->{byte_size}); + </div> </div> - </div> - </td> - - <td class="hide-small" style="text-align: right; white-space: nowrap"> - %= $v->print_sizes10($msg->{byte_size}); - </td> - <td> - %= check_box mail => $msg->{message_handle} => (form => 'move-mail') - </td> + <div class=media-right> + %= check_box mail => $msg->{message_handle} => (form => 'move-mail') => (class => 'jwm-mail-checkbox') + </div> % end % } - </tbody> -</table> +</section> diff --git a/templates/displayheaders/_pagination1.html.ep b/templates/displayheaders/_pagination1.html.ep index a32afe1..6a22ba5 100644 --- a/templates/displayheaders/_pagination1.html.ep +++ b/templates/displayheaders/_pagination1.html.ep @@ -1,14 +1,14 @@ <nav> - <ul class="pagination-box"> + <ul class="pagination-list"> <li> - %= $c->_paginate->make_link('←', 'prev_page') + %= $c->_paginate->make_link('←', 'prev_page', class => 'pagination-link', class_disabled => 'is-disabled') <li> - %= $c->_paginate->make_link('↞', 'first_page') + %= $c->_paginate->make_link('↞', 'first_page', class => 'pagination-link', class_disabled => 'is-disabled') <li> - <span><%= l('page [_1] of [_2]', $pgn->{current_page}+1, $pgn->{total_pages}) %></span> + <span class="pagination-link is-current"><%= l('page [_1] of [_2]', $pgn->{current_page}+1, $pgn->{total_pages}) %></span> <li> - %= $c->_paginate->make_link('↠', 'last_page') + %= $c->_paginate->make_link('↠', 'last_page', class => 'pagination-link', class_disabled => 'is-disabled') <li> - %= $c->_paginate->make_link('→', 'next_page') + %= $c->_paginate->make_link('→', 'next_page', class => 'pagination-link', class_disabled => 'is-disabled') </ul> </nav> diff --git a/templates/displayheaders/_pagination3.html.ep b/templates/displayheaders/_pagination3.html.ep index fe573ce..846a285 100644 --- a/templates/displayheaders/_pagination3.html.ep +++ b/templates/displayheaders/_pagination3.html.ep @@ -1,6 +1,6 @@ % my $make_link_num = begin % my ($txt, $to) = @_; -%= link_to $txt => url_with->query({start => $to}) => (class => (param('start')//0) == $to ? 'current' : '') +%= link_to $txt => url_with->query({start => $to}) => (class => (param('start')//0) == $to ? 'pagination-link is-current' : 'pagination-link') % end % my $nbh = begin @@ -15,13 +15,13 @@ % } % end -<nav> - <ul class="pagination-box"> +<nav class="pagination is-centered"> + <ul class="pagination-list"> <li> - %= $c->_paginate->make_link('Prev' => 'prev_page') + %= $c->_paginate->make_link('Prev' => 'prev_page', class => 'pagination-link', class_disabled => 'is-disabled') </li> %= $nbh->() <li> - %= $c->_paginate->make_link('Next' => 'next_page') + %= $c->_paginate->make_link('Next' => 'next_page', class => 'pagination-link', class_disabled => 'is-disabled') </ul> </nav> diff --git a/templates/displayheaders/_top_nav.html.ep b/templates/displayheaders/_top_nav.html.ep index f4c66d2..e5eaab8 100644 --- a/templates/displayheaders/_top_nav.html.ep +++ b/templates/displayheaders/_top_nav.html.ep @@ -1,35 +1,52 @@ -<div class="pure-g"> +<div class="columns"> - <div class="pure-u-1 pure-u-md-1-4"> - <div class="pure-menu pure-menu-horizontal"> - <ul class="pure-menu-list"> - %# <a href="<%= url_with($prefsurl) %>"><%= TXT 'userconfig' %></a> - %# <a href="<%=$prefsurl%>?action=editaddresses&folder=<%=$folder%>&sessionid=<%=$thissession%>&sort=<%=$sort%>&firstmessage=<%=$firstmessage+1%>&lang=<%=$lang%>" ><%= TXT 'addressbook' %></a> - <li class="pure-menu-item"> - %= link_to ucfirst(l 'logout') => 'logout' - </li> - <li class="pure-menu-item"> - %= link_to ucfirst(l 'compose') => 'write' - </li> - </ul> + <nav class="column"> + %# <a href="<%= url_with($prefsurl) %>"><%= TXT 'userconfig' %></a> + %# <a href="<%=$prefsurl%>?action=editaddresses&folder=<%=$folder%>&sessionid=<%=$thissession%>&sort=<%=$sort%>&firstmessage=<%=$firstmessage+1%>&lang=<%=$lang%>" ><%= TXT 'addressbook' %></a> + %= link_to ucfirst(l 'logout') => 'logout' => (class => 'button') + %= link_to ucfirst(l 'compose') => 'write' => (class => 'button') + </nav> + + %# <td> <form action="<%= url_for('delete_msg') %>" name=Formdel onsubmit="return confirm('<%= TXT q(js_confirm_delete) %>')" > </form> </td> + + %= form_for '' => (class => 'column') => begin + <div class="field is-horizontal"> + <div class=field-label> + %= label_for search => ucfirst(l 'search') => (class => 'label') + </div> + <div class=field-body> + <div class=field> + <div class="control"> + %= search_field search => (size => 8) => (class => 'input') + </div> + </div> + </div> </div> - </div> + % end - <div class="pure-u-1 pure-u-md-1-4"> - %= form_for '' => (class => 'pure-form') => begin - %= label_for search => ucfirst(l 'search') - %= search_field search => (size => 8) - % end - </div> + %= form_for '' => (class => 'column') => begin + <div class="field is-horizontal"> + <div class=field-label> + %= label_for sort => ucfirst(l 'sort') => (class => 'label') + </div> + <div class=field-body> + <div class=field> + <div class="select" id=sort-select> + <select name=sort id=sort> + <option value="!date">Date - Descending</option> + <option value="date" >Date - Ascending</option> + <option value="!size">Size - Descending</option> + <option value="!sender">Sender - Descending</option> + <option value="sender" >Sender - Ascending</option> + </select> + </div> + </div> + </div> + </div> + % end - <div class="pure-u-1-1 pure-u-md-1-2"> + <div class="column"> %= include 'displayheaders/_pagination3'; </div> - <!-- delete button - <td> - %# <form action="<%= url_for('delete_msg') %>" name=Formdel onsubmit="return confirm('<%= TXT q(js_confirm_delete) %>')" > </form> - </td> - --> - </div> diff --git a/templates/layouts/mainlayout.html.ep b/templates/layouts/mainlayout.html.ep index 2cd4671..8cf822c 100644 --- a/templates/layouts/mainlayout.html.ep +++ b/templates/layouts/mainlayout.html.ep @@ -6,9 +6,7 @@ <meta charset=utf-8> <meta name="viewport" content="width=device-width, initial-scale=1"> - %# <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/purecss@3.0.0/build/pure-min.css" integrity="sha384-X38yfunGUhNzHpBaEBsWLO+A0HDYOQi8ufWDkZ0k9e0eXz/tH3II7uKZ9msv++Ls" crossorigin="anonymous"> - %# <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/purecss@3.0.0/build/grids-responsive-min.css"> - %= stylesheet '/css/style.css' + %= stylesheet '/css/my_bulma.css' <title> %= title || 'JWebmail' @@ -18,14 +16,16 @@ <body> %= content - <footer> - %= link_to about => begin - %= ucfirst l 'about' - JWebmail - % end - <br> - %= ucfirst l 'version' - %= $version + <footer class=footer> + <div class="content has-text-centered"> + %= link_to about => begin + %= ucfirst l 'about' + JWebmail + % end + <br> + %= ucfirst l 'version' + %= $version + </div> </footer> </body> diff --git a/templates/not_found.html.ep b/templates/not_found.html.ep new file mode 100644 index 0000000..a8eafc0 --- /dev/null +++ b/templates/not_found.html.ep @@ -0,0 +1,25 @@ +<html> + + <head> + <meta charset=utf-8> + <meta name="viewport" content="width=device-width, initial-scale=1"> + + <title>Not Found</title> + + %= stylesheet '/css/my_bulma.css' + </head> + + <body> + <section class=hero> + <div class=hero-body> + <h1 class=title> + Not the page you are looking for. + </h1> + <p> + Go back or go to the <%= link_to 'start page' => 'login' %>. + </p> + </div> + </section> + </body> + +</html> diff --git a/templates/not_found.production.html.ep b/templates/not_found.production.html.ep deleted file mode 100644 index b96e46e..0000000 --- a/templates/not_found.production.html.ep +++ /dev/null @@ -1,16 +0,0 @@ -<html> - - <head> - <title>Not Found</title> - </head> - - <body> - <p class=center> - Not the page you are looking for. - </p> - <p class=center> - Go back or go to the <%= link_to 'start page' => 'login' %>. - </p> - </body> - -</html> diff --git a/templates/webmail/about.html.ep b/templates/webmail/about.html.ep index 6221bcc..a5cd4a7 100644 --- a/templates/webmail/about.html.ep +++ b/templates/webmail/about.html.ep @@ -2,9 +2,9 @@ % layout 'mainlayout'; -<div class="jwm-base"> +<div class="section container"> - <div class="jwm-post"> + <article class=content> <h1>About JWebmail <%= $version %></h1> @@ -38,7 +38,7 @@ and currently maintained by <a href="mailto:jannis@fehcom.de">Jannis M. Hoffmann</a> </p> - + <p> <h3>Supported languages</h3> @@ -56,10 +56,12 @@ a complete rewrite of oMail-webmail. </p> - </div> + </article> - <nav> - %= link_to login => 'login' => (class => 'pure-button') + <nav class=navbar> + <div class=navbar-item> + %= link_to login => 'login' => (class => 'button') + </div> </nav> </div> diff --git a/templates/webmail/displayheaders.html.ep b/templates/webmail/displayheaders.html.ep index 3f650c0..8446e00 100644 --- a/templates/webmail/displayheaders.html.ep +++ b/templates/webmail/displayheaders.html.ep @@ -1,6 +1,8 @@ % layout 'mainlayout'; -<div id=displayheaders> +<section class="section container"> + + %= javascript '/src/displayheaders.js' => (defer => undef) %= include 'displayheaders/_folders'; @@ -16,11 +18,11 @@ %= include 'displayheaders/_main_table'; % } % else { - <p id=empty-folder> + <p class="section"> %= l 'This folder is empty!' </p> % } %= include 'displayheaders/_bot_nav'; -</div> +</section> diff --git a/templates/webmail/login.html.ep b/templates/webmail/login.html.ep index 706dc1c..54ab40a 100644 --- a/templates/webmail/login.html.ep +++ b/templates/webmail/login.html.ep @@ -2,38 +2,69 @@ % my $uses_cram = config->{session}{secure} eq 'cram'; -<div id=login class="jwm-base"> +<section class=section> + <div class="container is-max-desktop box"> - <h1> - JWebmail – <%= ucfirst l 'login' %> - </h1> + <h1 class=title> + <%= ucfirst l 'login' %> + </h1> + <h2 class=subtitle> + JWebmail + </h2> % if (my $msg = flash('message') || stash('warning')) { - <p class="jwm-warning"> - %= $msg - </p> + <div class="message is-warning"> + <div class=message-header> + %= $msg + </div> + </div> % } %= form_for login => (name => 'login1') => (method => 'post') => (class => 'pure-form pure-form-aligned jwm-round') => begin - <fieldset> - <div class="pure-control-group"> - %= label_for userid => ucfirst l 'userid' - %= text_field 'userid' => '' => (required => '') + + <div class="field is-horizontal"> + <div class=field-label> + %= label_for userid => ucfirst l 'userid' => (class => 'label') + </div> + <div class=field-body> + <div class=field> + <div class=control> + %= text_field 'userid' => '' => (required => undef) => (class => 'input') + </div> + </div> </div> - <div class="pure-control-group"> - %= label_for password => ucfirst l 'password' - %= password_field 'password' => (required => '') + </div> + + <div class="field is-horizontal"> + <div class=field-label> + %= label_for password => ucfirst l 'password' => (class => 'label') </div> + <div class=field-body> + <div class=field> + <div class=control> + %= password_field 'password' => (required => undef) => (class => 'input') + </div> + </div> + </div> + </div> % if ($uses_cram) { %= hidden_field challenge => rand % } - <div class="pure-controls"> - %= submit_button ucfirst l('login') => (class => 'pure-button pure-button-primary') => (name => 'submit_button') => $uses_cram ? (disabled => undef) : () + <div class="field is-horizontal"> + <div class=field-label> + </div> + <div class=field-body> + <div class=field> + <div class=control> + %= submit_button ucfirst l('login') => (class => 'button is-primary') => (name => 'submit_button') => $uses_cram ? (disabled => undef) : () + </div> + </div> </div> - </fieldset> + </div> % end -</div> + </div> +</section> % if ($uses_cram) { %= javascript '/src/login_cram.js' diff --git a/templates/webmail/readmail.html.ep b/templates/webmail/readmail.html.ep index 529bbe6..c9586ac 100644 --- a/templates/webmail/readmail.html.ep +++ b/templates/webmail/readmail.html.ep @@ -1,14 +1,14 @@ % layout 'mainlayout'; -<div class="jwm-base"> +<div class="section container"> - <h1>Read Mail</h1> + <h1 class=title>Read Mail</h1> %= $v->format_mail($msg) <nav> - <a href="javascript:history.back()" class="pure-button"> + <a href="javascript:history.back()" class="button"> %= l 'back' </a> </nav> diff --git a/templates/webmail/writemail.html.ep b/templates/webmail/writemail.html.ep index 9d148c1..95b9cf8 100644 --- a/templates/webmail/writemail.html.ep +++ b/templates/webmail/writemail.html.ep @@ -1,47 +1,80 @@ % layout 'mainlayout'; -<div class="jwm-base"> +<div class="section container"> - <h1>Write Message</h1> + <h1 class=title>Write Message</h1> % if (my $msg = stash('warning')) { - <p class=warn> <%= $msg %> </p> + <p class=message> <%= $msg %> </p> % } - %= form_for '' => (method => 'post') => (enctype => 'multipart/form-data') => (class => 'pure-form pure-form-stacked') => begin - <fieldset> - - %= label_for mail => ucfirst l 'send_to' - %= email_field 'to' => (id => 'mail') => (multiple => '') => (required => '') - - %= label_for subject => ucfirst l 'subject' - %= text_field 'subject' => (required => '') - - %= label_for cc => 'CC' - %= email_field 'cc' => (multiple => '') - - %= label_for bcc => 'BCC' - %= email_field 'bcc' => (multiple => '') - - %= label_for back_to => ucfirst l 'answer_to' - %= email_field 'back_to' - - %= label_for txt => ucfirst l 'content' - %# text_area body => (cols => 80) => (rows => 24) => (name => 'txt') - %= text_area body => (style => 'width: 100%') => (rows => 24) => (name => 'txt') - - %= label_for attach => ucfirst l 'attach file' - %= file_field 'attach' - - %= submit_button l('send') => (class => 'pure-button pure-button-primary') + %= form_for '' => (method => 'post') => (enctype => 'multipart/form-data') => (class => '') => begin + + <div class=field> + %= label_for mail => ucfirst l('send_to') => (class => 'label') + <div class=control> + %= email_field 'to' => (id => 'mail') => (multiple => '') => (required => '') => (class => 'input') + </div> + </div> + + <div class=field> + %= label_for subject => ucfirst l('subject') => (class => 'label') + <div class=control> + %= text_field 'subject' => (required => '') => (class => 'input') + </div> + </div> + + <div class=field> + %= label_for cc => 'CC' => (class => 'label') + <div class=control> + %= email_field 'cc' => (multiple => '') => (class => 'input') + </div> + </div> + + <div class=field> + %= label_for bcc => 'BCC' => (class => 'label') + <div class=control> + %= email_field 'bcc' => (multiple => '') => (class => 'input') + </div> + </div> + + <div class=field> + %= label_for back_to => ucfirst l('answer_to') => (class => 'label') + <div class=control> + %= email_field 'back_to' => (class => 'input') + </div> + </div> + + <div class=field> + %= label_for txt => ucfirst l('content') => (class => 'label') + %= text_area body => (rows => 24) => (name => 'txt') => (class => 'textarea') + </div> + + <div class=field> + <div class=file> + <label class=file-label> + %= file_field 'attach' => (class => 'file-input') + <div class="file-cta"> + %= tag span => (class => 'file-label') => begin + %= ucfirst l('attach file') + % end + </div> + </label> + </div> + </div> + + <div class=field> + <div class=control> + %= submit_button l('send') => (class => 'button') + </div> + </div> %= csrf_field - </fieldset> % end <nav> - <a href="javascript:history.back()" class="pure-button"> <%= ucfirst l 'back' %> </a> + <a href="javascript:history.back()" class="button"> <%= ucfirst l 'back' %> </a> </nav> </div> |