1
0
Fork 0
mirror of https://gitlab.com/Alamantus/Readlebee.git synced 2025-09-03 01:34:26 +02:00

Compare commits

...

8 commits

13 changed files with 219 additions and 92 deletions

View file

@ -2,14 +2,25 @@
"name": "English",
"locale": "en",
"home": {
"subtitle": "An attempt at a viable alternative to Goodreads",
"temp_left": "Still gotta figure out a design.",
"temp_right": "It's early days, my friends!"
"logged_out_subtitle": "All the Book Buzz in Once Place",
"logged_out_track_books": "Keep track of books you've read, want to read, and are currently reading.",
"logged_out_share_friends": "Share your thoughts about what you're reading and see what your friends think of their books.",
"logged_out_read_rate": "Rate, review, and recommmend books or something. I dunno. It's early days, my friends!",
"logged_out_community_header": "A Look Inside the Hive",
"logged_out_recent_reviews": "Recent Reviews",
"logged_out_recent_updates": "Recent Updates",
"logged_out_join_now": "Join Now!"
},
"login": {
"log_in": "Log In",
"email": "Email",
"password": "Password",
"login_button": "Log In!"
"login_button": "Log In!",
"create_account": "Create a New Account",
"confirm_password": "Confirm Password",
"username": "Username",
"display_name": "Display Name",
"create_account_button": "Create Account!"
},
"search": {
"header": "Search",
@ -22,6 +33,7 @@
"see_details_tooltip": "Opens Inventaire in a new tab/window"
},
"interaction": {
"reload": "Reload",
"heart": "Like",
"add": "Add to Shelf",
"average_rating": "Average Rating",

View file

@ -59,6 +59,7 @@ app.use((state, emitter) => {
state.currentView = 'home';
state.language = app.getSettingsItem('lang') ? app.getSettingsItem('lang') : (navigator.language || navigator.userLanguage).split('-')[0];
state.viewStates = {};
state.isLoggedIn = false;
}
// Listeners

View file

@ -1,3 +1,4 @@
// Picnic Overrides
body {
font-family: BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
}
@ -18,11 +19,9 @@ nav {
position: relative;
}
footer nav {
.links {
@extend .brand;
font-weight: unset;
}
.pseudo[data-tooltip]::after {
background-color: $picnic-black;
color: $picnic-white;
}
// External links
@ -35,11 +34,19 @@ a[href^="https://"]:after{
content: "\f08e";
}
// New components
.menu ul li {
display: inline-block;
list-style: none;
}
footer nav {
.links {
@extend .brand;
font-weight: unset;
}
}
.container {
display: block;
width: 75%;
@ -131,6 +138,7 @@ th {
}
}
// Handy Utilities
.paddingless {
padding: 0 !important;
}
@ -140,8 +148,11 @@ th {
.italic {
font-style: italic !important;
}
.large {
font-size: 1.5em;
}
.small {
font-size: 80%;
font-size: 0.8em;
}
.left-align {
text-align: left !important;

View file

@ -5,8 +5,8 @@
// Colors (from /themes/default/colors)
$picnic-white: #fff !default;
$picnic-black: #111 !default;
$picnic-white: $white !default;
$picnic-black: $black !default;
$picnic-primary: $teal !default;
$picnic-success: $green !default;
$picnic-info: $blue !default;

View file

@ -12,4 +12,8 @@ export class ViewController {
}
this.state = this.appState.viewStates[viewName];
}
get isLoggedIn () {
return this.appState.isLoggedIn;
}
}

View file

@ -5,11 +5,8 @@ export class HomeController extends ViewController {
// Super passes state, view name, and default state to ViewController,
// which stores state in this.appState and the view controller's state to this.state
super(state, 'home', {
messages: [
'hello',
'test',
'yay',
],
recentReviews: [],
recentUpdates: [],
});
// If using controller methods in an input's onchange or onclick instance,
@ -17,7 +14,10 @@ export class HomeController extends ViewController {
// or use `onclick=${() => controller.submit()}` to maintain the 'this' of the class instead.
}
get messages() {
return [...this.state.messages];
get recentReviews() {
return [...this.state.recentReviews];
}
get recentUpdates() {
return [...this.state.recentUpdates];
}
}

View file

@ -1,42 +1,18 @@
import html from 'choo/html';
import './styles.scss'; // Creates a separate CSS file, but allows better code splitting.
// We'll see if code splitting is worth it in the end or if we should combine everything into `src/index.scss`
import { HomeController } from './controller'; // The controller for this view, where processing should happen.
import { loggedOutView } from './loggedOut';
// This is the view function that is exported and used in the view manager.
export const homeView = (state, emit) => {
const controller = new HomeController(state);
const { i18n } = controller;
// Returning an array in a view allows non-shared parent HTML elements.
// This one doesn't have the problem right now, but it's good to remember.
return [
html`<section>
<h2 class="subtitle">${i18n.__('home.subtitle')}</h2>
<article class="flex two">
<div class="half">
<div class="card">
<header>
<p>${i18n.__('home.temp_left')}</p>
</header>
</div>
</div>
<div class="half">
<div class="card">
<header>
<p>${i18n.__('home.temp_right')}</p>
</header>
</div>
</div>
</article>
<article class="test">
${controller.messages.map(message => {
return html`<p>${message}</p>`;
})}
</article>
</section>`,
(!controller.isLoggedIn
? loggedOutView(controller, emit)
: html`<p>lol wut how are u logged in</p>`
),
];
}

View file

@ -0,0 +1,83 @@
import html from 'choo/html';
export const loggedOutView = (homeController, emit) => {
const { i18n } = homeController;
return [
html`<section>
<h2>${i18n.__('home.logged_out_subtitle')}</h2>
<article class="flex one three-500">
<div>
<div class="card">
<header class="center-align">
<span style="font-size:32pt;color:green;">
<i class="icon-check"></i>
</span>
</header>
<footer>
${i18n.__('home.logged_out_track_books')}
</footer>
</div>
</div>
<div>
<div class="card">
<header class="center-align">
<span style="font-size:32pt;color:red;">
<i class="icon-heart-filled"></i>
</span>
</header>
<footer>
${i18n.__('home.logged_out_share_friends')}
</footer>
</div>
</div>
<div>
<div class="card">
<header class="center-align">
<span style="font-size:32pt;color:yellow;">
<i class="icon-star"></i>
</span>
</header>
<footer>
${i18n.__('home.logged_out_read_rate')}
</footer>
</div>
</div>
</article>
</section>`,
html`<section>
<h2>${i18n.__('home.logged_out_community_header')}</h2>
<div class="flex one two-700">
<div>
<div class="card">
<header>
<h3>${i18n.__('home.logged_out_recent_reviews')}</h3>
<button class="small pseudo pull-right tooltip-left" data-tooltip=${i18n.__('interaction.reload')}>
<i class="icon-loading"></i><!--/* This needs to get updated to a reload icon */-->
</button>
</header>
<footer>
${homeController.recentReviews.map(review => reviewCard(homeController, review))}
</footer>
</div>
</div>
<div>
<div class="card">
<header>
<h3>${i18n.__('home.logged_out_recent_updates')}</h3>
<button class="small pseudo pull-right tooltip-left" data-tooltip=${i18n.__('interaction.reload')}>
<i class="icon-loading"></i><!--/* This needs to get updated to a reload icon */-->
</button>
</header>
<footer>
${homeController.recentUpdates.map(review => reviewCard(homeController, review))}
</footer>
</div>
</div>
</div>
</section>`,
html`<section class="center-align">
<a href="/login" class="large success button">${i18n.__('home.logged_out_join_now')}</a>
</section>`,
];
}

View file

@ -1,8 +0,0 @@
.test {
background-color: #dddddd;
padding: 10px;
p {
border: 1px solid #444444;
}
}

View file

@ -8,19 +8,56 @@ export const loginView = (state, emit) => {
return html`<section>
<article class="card">
<div class="container wide">
<label>
<span>${i18n.__('login.email')}</span>
<input type="email" name="email">
</label>
<label>
<span>${i18n.__('login.password')}</span>
<input type="password" name="password">
</label>
<input type="submit" value="${i18n.__('login.login_button')}">
<div class="flex one two-700">
<div>
<article class="card">
<header>
<h3>${i18n.__('login.log_in')}</h3>
</header>
<footer>
<label>
<span>${i18n.__('login.email')}</span>
<input type="email" name="email">
</label>
<label>
<span>${i18n.__('login.password')}</span>
<input type="password" name="password">
</label>
<input type="submit" value="${i18n.__('login.login_button')}">
</footer>
</article>
</div>
<div>
<article class="card">
<header>
<h3>${i18n.__('login.create_account')}</h3>
</header>
<footer>
<label>
<span>${i18n.__('login.email')}</span>
<input type="email" name="new_email">
</label>
<label>
<span>${i18n.__('login.password')}</span>
<input type="password" name="new_password">
</label>
<label>
<span>${i18n.__('login.confirm_password')}</span>
<input type="password" name="confirm_password">
</label>
<label>
<span>${i18n.__('login.username')}</span>
<input type="text" name="new_username">
</label>
<label>
<span>${i18n.__('login.display_name')}</span>
<input type="text" name="new_displayname">
</label>
<input type="submit" class="success" value="${i18n.__('login.create_account_button')}">
</footer>
</article>
</div>
</div>
</article>
</section>`;
</section>`;
}

View file

@ -0,0 +1,29 @@
import html from 'choo/html';
import { starRating } from './starRating';
export const reviewCard = (controller, review) => {
const { i18n } = controller;
return html`<article class="card">
<header style="font-weight:normal;">
<strong>${review.reviewer.name}</strong> <em>${review.reviewer.handle}</em><br>
${review.date} ${starRating(Math.ceil(review.rating))}
</header>
<footer>
<div class="content">
<p>
${review.review}
</p>
</div>
<span class="tooltip-top" data-tooltip=${i18n.__('interaction.heart')}>
<button class="pseudo">
<i class="icon-heart-outline"></i>
</button>
</span>
<span>
${review.hearts}
</span>
</footer>
</article>`;
}

View file

@ -1,5 +1,6 @@
import html from 'choo/html';
import { reviewCard } from '../partials/reviewCard';
import { starRating } from '../partials/starRating';
import { modal } from '../partials/modal';
@ -70,27 +71,7 @@ export const resultDetails = (searchController, result, emit = () => {}) => {
</div>
</div>
${result.reviews.map(review => {
return html`<article class="card">
<header style="font-weight:normal;">
<strong>${review.reviewer.name}</strong> <em>${review.reviewer.handle}</em><br>
${review.date} ${starRating(Math.ceil(review.rating))}
</header>
<footer>
<div class="content">
<p>
${review.review}
</p>
</div>
<span class="tooltip-top" data-tooltip=${i18n.__('interaction.heart')}>
<button class="pseudo">
<i class="icon-heart-outline"></i>
</button>
</span>
<span>
${review.hearts}
</span>
</footer>
</article>`;
return reviewCard(searchController, review);
})}
</div>
<div class="sixth-700">

View file

@ -11,7 +11,8 @@
"start": "npm run build && cross-env NODE_ENV=production npm run serve",
"watch-js": "parcel watch app/index.html --out-dir public --no-hmr --no-cache",
"serve": "node server/index.js",
"build": "npm run process-images && parcel build app/index.html --out-dir public --no-source-maps --no-cache",
"build": "npm run process-images && npm run bundle",
"bundle": "parcel build app/index.html --out-dir public --no-source-maps --no-cache",
"process-images": "node ./process-images.js",
"clear": "rimraf public/{*,.*}"
},