Small improvements to the mobile interface #663
14 changed files with 1236 additions and 832 deletions
1875
Cargo.lock
generated
1875
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -20,8 +20,8 @@ heck = "0.3.0"
|
|||
lettre = "0.9.2"
|
||||
lettre_email = "0.9.2"
|
||||
num_cpus = "1.10"
|
||||
rocket = "0.4.2"
|
||||
rocket_contrib = { version = "0.4.2", features = ["json"] }
|
||||
rocket = "0.4.5"
|
||||
rocket_contrib = { version = "0.4.5", features = ["json"] }
|
||||
rocket_i18n = { git = "https://github.com/Plume-org/rocket_i18n", rev = "e922afa7c366038b3433278c03b1456b346074f2" }
|
||||
rpassword = "4.0"
|
||||
scheduled-thread-pool = "0.2.2"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM rust:1-stretch as builder
|
||||
FROM rust:1-buster as builder
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
|
|
@ -28,7 +28,7 @@ RUN cargo install --path ./ --force --no-default-features --features postgres
|
|||
RUN cargo install --path plume-cli --force --no-default-features --features postgres
|
||||
RUN cargo clean
|
||||
|
||||
FROM debian:stretch-slim
|
||||
FROM debian:buster-slim
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM rust:1-stretch
|
||||
FROM rust:1-buster
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
|
|
|
|||
|
|
@ -490,3 +490,30 @@ input:checked ~ .cw-container > .cw-text {
|
|||
display: inline;
|
||||
}
|
||||
}
|
||||
|
||||
// Small screens
|
||||
@media screen and (max-width: 600px) {
|
||||
#plume-editor header {
|
||||
flex-direction: column-reverse;
|
||||
|
||||
button {
|
||||
flex: 0 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
.popup {
|
||||
top: 10vh;
|
||||
bottom: 10vh;
|
||||
left: 1vw;
|
||||
right: 1vw;
|
||||
}
|
||||
|
||||
main article {
|
||||
margin: 2.5em .5em;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
main .article-meta > *, main .article-meta .comments, main .article-meta > .banner > * {
|
||||
margin: 0 5%;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -490,6 +490,10 @@ figure {
|
|||
|
||||
/// Small screens
|
||||
@media screen and (max-width: 600px) {
|
||||
body > main > *, .h-feed > * {
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
main .article-meta {
|
||||
> *, .comments {
|
||||
margin: 0 5%;
|
||||
|
|
@ -535,7 +539,7 @@ figure {
|
|||
margin: 0;
|
||||
|
||||
& > * {
|
||||
max-width: 100%;
|
||||
max-width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -221,3 +221,93 @@ body > header {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Small screens
|
||||
@media screen and (max-width: 600px) {
|
||||
@keyframes menuOpening {
|
||||
from {
|
||||
transform: scaleX(0);
|
||||
transform-origin: left;
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: scaleX(1);
|
||||
transform-origin: left;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
body > header {
|
||||
flex-direction: column;
|
||||
|
||||
nav#menu {
|
||||
display: inline-flex;
|
||||
z-index: 21;
|
||||
}
|
||||
|
||||
#content {
|
||||
display: none;
|
||||
appearance: none;
|
||||
text-align: center;
|
||||
z-index: 20;
|
||||
}
|
||||
}
|
||||
|
||||
body > header:focus-within #content, #content.show {
|
||||
position: fixed;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
animation: 0.2s menuOpening;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
transform: skewX(-10deg);
|
||||
top: 0;
|
||||
left: -20%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
z-index: -10;
|
||||
|
||||
background: $primary;
|
||||
}
|
||||
|
||||
> nav {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
|
||||
a {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
padding: 1rem 1.5rem;
|
||||
color: $background;
|
||||
font-size: 1.4em;
|
||||
font-weight: 300;
|
||||
|
||||
&.title { font-size: 1.8em; }
|
||||
|
||||
> *:first-child { width: 3rem; }
|
||||
> img:first-child { height: 3rem; }
|
||||
> *:last-child { margin-left: 1rem; }
|
||||
> nav hr {
|
||||
display: block;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
border: solid $background 0.1rem;
|
||||
}
|
||||
.mobile-label { display: initial; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ heck = "0.3.0"
|
|||
hex = "0.3"
|
||||
hyper = "0.12.33"
|
||||
openssl = "0.10.22"
|
||||
rocket = "0.4.0"
|
||||
rocket = "0.4.5"
|
||||
reqwest = "0.9"
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
|
|
|
|||
|
|
@ -269,7 +269,13 @@ pub fn init() -> Result<(), EditorError> {
|
|||
let editor_button = document().create_element("a")?;
|
||||
js! { @{&editor_button}.href = "#"; }
|
||||
editor_button.add_event_listener(|_: ClickEvent| {
|
||||
window().local_storage().remove("basic-editor");
|
||||
if window()
|
||||
.local_storage()
|
||||
.insert("basic-editor", "false")
|
||||
.is_err()
|
||||
{
|
||||
console!(log, "Failed to write into local storage");
|
||||
}
|
||||
window().history().go(0).ok(); // refresh
|
||||
});
|
||||
editor_button.append_child(
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ itertools = "0.8.0"
|
|||
lazy_static = "1.0"
|
||||
migrations_internals= "1.4.0"
|
||||
openssl = "0.10.22"
|
||||
rocket = "0.4.0"
|
||||
rocket = "0.4.5"
|
||||
rocket_i18n = { git = "https://github.com/Plume-org/rocket_i18n", rev = "e922afa7c366038b3433278c03b1456b346074f2" }
|
||||
reqwest = "0.9"
|
||||
scheduled-thread-pool = "0.2.2"
|
||||
|
|
@ -30,7 +30,7 @@ whatlang = "0.7.1"
|
|||
shrinkwraprs = "0.2.1"
|
||||
diesel-derive-newtype = "0.1.2"
|
||||
glob = "0.3.0"
|
||||
lindera-tantivy = { version = "0.1.2", optional = true }
|
||||
lindera-tantivy = { version = "0.1.3", optional = true }
|
||||
|
||||
[dependencies.chrono]
|
||||
features = ["serde"]
|
||||
|
|
|
|||
BIN
plume-models/plume.db-journal
Normal file
BIN
plume-models/plume.db-journal
Normal file
Binary file not shown.
BIN
plume-models/plume_tests.sqlite-journal
Normal file
BIN
plume-models/plume_tests.sqlite-journal
Normal file
Binary file not shown.
|
|
@ -5,10 +5,10 @@ use crate::{
|
|||
use chrono::Datelike;
|
||||
use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl};
|
||||
use itertools::Itertools;
|
||||
use std::{cmp, fs::create_dir_all, path::Path, sync::Mutex};
|
||||
use std::{cmp, fs::create_dir_all, io, path::Path, sync::Mutex};
|
||||
use tantivy::{
|
||||
collector::TopDocs, directory::MmapDirectory, schema::*, Index, IndexReader, IndexWriter,
|
||||
ReloadPolicy, Term,
|
||||
ReloadPolicy, TantivyError, Term,
|
||||
};
|
||||
use whatlang::{detect as detect_lang, Lang};
|
||||
|
||||
|
|
@ -18,6 +18,7 @@ pub enum SearcherError {
|
|||
WriteLockAcquisitionError,
|
||||
IndexOpeningError,
|
||||
IndexEditionError,
|
||||
InvalidIndexDataError,
|
||||
}
|
||||
|
||||
pub struct Searcher {
|
||||
|
|
@ -135,7 +136,19 @@ impl Searcher {
|
|||
.reader_builder()
|
||||
.reload_policy(ReloadPolicy::Manual)
|
||||
.try_into()
|
||||
.map_err(|_| SearcherError::IndexCreationError)?,
|
||||
.map_err(|e| {
|
||||
if let TantivyError::IOError(err) = e {
|
||||
let err: io::Error = err.into();
|
||||
if err.kind() == io::ErrorKind::InvalidData {
|
||||
// Search index was created in older Tantivy format.
|
||||
SearcherError::InvalidIndexDataError
|
||||
} else {
|
||||
SearcherError::IndexCreationError
|
||||
}
|
||||
} else {
|
||||
SearcherError::IndexCreationError
|
||||
}
|
||||
})?,
|
||||
index,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
27
src/main.rs
Normal file → Executable file
27
src/main.rs
Normal file → Executable file
|
|
@ -10,6 +10,7 @@ extern crate serde_json;
|
|||
#[macro_use]
|
||||
extern crate validator_derive;
|
||||
|
||||
use chrono::Utc;
|
||||
use clap::App;
|
||||
use diesel::r2d2::ConnectionManager;
|
||||
use plume_models::{
|
||||
|
|
@ -21,6 +22,8 @@ use plume_models::{
|
|||
};
|
||||
use rocket_csrf::CsrfFairingBuilder;
|
||||
use scheduled_thread_pool::ScheduledThreadPool;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::process::exit;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
|
|
@ -98,8 +101,30 @@ Then try to restart Plume.
|
|||
}
|
||||
let workpool = ScheduledThreadPool::with_name("worker {}", num_cpus::get());
|
||||
// we want a fast exit here, so
|
||||
let mut open_searcher =
|
||||
UnmanagedSearcher::open(&CONFIG.search_index, &CONFIG.search_tokenizers);
|
||||
if let Err(Error::Search(SearcherError::InvalidIndexDataError)) = open_searcher {
|
||||
if UnmanagedSearcher::create(&CONFIG.search_index, &CONFIG.search_tokenizers).is_err() {
|
||||
let current_path = Path::new(&CONFIG.search_index);
|
||||
let backup_path = format!("{}.{}", ¤t_path.display(), Utc::now().timestamp());
|
||||
let backup_path = Path::new(&backup_path);
|
||||
fs::rename(current_path, backup_path)
|
||||
.expect("main: error on backing up search index directory for recreating");
|
||||
if UnmanagedSearcher::create(&CONFIG.search_index, &CONFIG.search_tokenizers).is_ok() {
|
||||
if fs::remove_dir_all(backup_path).is_err() {
|
||||
eprintln!(
|
||||
"error on removing backup directory: {}. it remains",
|
||||
backup_path.display()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
panic!("main: error on recreating search index in new index format. remove search index and run `plm search init` manually");
|
||||
}
|
||||
}
|
||||
open_searcher = UnmanagedSearcher::open(&CONFIG.search_index, &CONFIG.search_tokenizers);
|
||||
}
|
||||
#[allow(clippy::match_wild_err_arm)]
|
||||
let searcher = match UnmanagedSearcher::open(&CONFIG.search_index, &CONFIG.search_tokenizers) {
|
||||
let searcher = match open_searcher {
|
||||
Err(Error::Search(e)) => match e {
|
||||
SearcherError::WriteLockAcquisitionError => panic!(
|
||||
r#"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue