diff --git a/app/store/bolt.go b/app/store/bolt.go
index 448ad9b6..81393e2f 100644
--- a/app/store/bolt.go
+++ b/app/store/bolt.go
@@ -39,6 +39,8 @@ const (
userLimit = 50
)
+const tsNano = "2006-01-02T15:04:05.000000000Z07:00"
+
// BoltSite defines single site param
type BoltSite struct {
FileName string // full path to boltdb
@@ -117,7 +119,7 @@ func (b *BoltDB) Create(comment Comment) (commentID string, err error) {
// add reference to comment to "last" bucket
lastBkt := tx.Bucket([]byte(lastBucketName))
ref := b.makeRef(comment)
- commentTs := []byte(comment.Timestamp.Format(time.RFC3339Nano))
+ commentTs := []byte(comment.Timestamp.Format(tsNano))
e = lastBkt.Put(commentTs, ref)
if e != nil {
return errors.Wrapf(e, "can't put reference %s to %s", ref, lastBucketName)
@@ -288,7 +290,7 @@ func (b *BoltDB) SetBlock(siteID string, userID string, status bool) error {
bucket := tx.Bucket([]byte(blocksBucketName))
switch status {
case true:
- if e := bucket.Put([]byte(userID), []byte(time.Now().Format(time.RFC3339Nano))); e != nil {
+ if e := bucket.Put([]byte(userID), []byte(time.Now().Format(tsNano))); e != nil {
return errors.Wrapf(e, "failed to put %s to %s", userID, blocksBucketName)
}
case false:
@@ -328,7 +330,7 @@ func (b *BoltDB) Blocked(siteID string) (users []BlockedUser, err error) {
err = bdb.View(func(tx *bolt.Tx) error {
bucket := tx.Bucket([]byte(blocksBucketName))
return bucket.ForEach(func(k []byte, v []byte) error {
- ts, e := time.ParseInLocation(time.RFC3339Nano, string(v), time.Local)
+ ts, e := time.ParseInLocation(tsNano, string(v), time.Local)
if e != nil {
return errors.Wrap(e, "can't parse block ts")
}
diff --git a/web/TODO.md b/web/TODO.md
index 27c0714c..d2a48ea9 100644
--- a/web/TODO.md
+++ b/web/TODO.md
@@ -1,15 +1,9 @@
major features:
- improve design
- - add true preloader
- - disable inputs for guests
- - hide reply links for guests
- check mobile ui
- add icons for social networks
- - remove grey avatars 'cause we have default img
- add time format 'X hours ago'
- - use static buttons 'reply', 'pin', etc instead of dynamic
- - maybe we should change layout: vote buttons | avatar | info; info: (top: name, points, time), (center: text), (bottom: controls)
- edit comment
- `PUT /api/v1/comment/{id}?site=site-id&url=post-url`
- add description of web part to readme
diff --git a/web/app/components/auth-panel/__pseudo-link/auth-panel__pseudo-link.scss b/web/app/components/auth-panel/__pseudo-link/auth-panel__pseudo-link.scss
index d81c8d3a..fa9a37f0 100644
--- a/web/app/components/auth-panel/__pseudo-link/auth-panel__pseudo-link.scss
+++ b/web/app/components/auth-panel/__pseudo-link/auth-panel__pseudo-link.scss
@@ -1,6 +1,11 @@
.auth-panel__pseudo-link {
display: inline-block;
+ font-weight: 700;
white-space: nowrap;
cursor: pointer;
- color: #06c5c5;
+ color: #0aa;
+
+ &:hover {
+ color: #06c5c5;
+ }
}
diff --git a/web/app/components/comment/__action/comment__action.scss b/web/app/components/comment/__action/comment__action.scss
index fb24d978..3cd88b8a 100644
--- a/web/app/components/comment/__action/comment__action.scss
+++ b/web/app/components/comment/__action/comment__action.scss
@@ -1,7 +1,7 @@
.comment__action {
margin-left: 8px;
font-weight: 700;
- color: #777;
+ color: #0aa;
cursor: pointer;
&:hover {
diff --git a/web/app/components/comment/__avatar/comment__avatar.scss b/web/app/components/comment/__avatar/comment__avatar.scss
index 44e08462..124aeaa5 100644
--- a/web/app/components/comment/__avatar/comment__avatar.scss
+++ b/web/app/components/comment/__avatar/comment__avatar.scss
@@ -8,5 +8,4 @@
height: $avatarSize;
margin-right: $avatarOffset;
border-radius: 4px;
- background: #eee;
}
diff --git a/web/app/components/comment/__controls/comment__controls.scss b/web/app/components/comment/__controls/comment__controls.scss
index 5e41f63c..f8f97d0d 100644
--- a/web/app/components/comment/__controls/comment__controls.scss
+++ b/web/app/components/comment/__controls/comment__controls.scss
@@ -3,8 +3,6 @@
user-select: none;
@media (hover: hover) {
- margin-left: 0;
- transition: transform .2s .1s ease-out, opacity .2s .1s ease-out;
font-weight: 700;
opacity: 0;
}
diff --git a/web/app/components/comment/__text/comment__text.scss b/web/app/components/comment/__text/comment__text.scss
index c0f50581..bc03e370 100644
--- a/web/app/components/comment/__text/comment__text.scss
+++ b/web/app/components/comment/__text/comment__text.scss
@@ -5,7 +5,28 @@
margin: 0;
+ p {
- margin-top: 5px;
+ margin-top: 8px;
+ }
+
+ // imported comments have br instead of p
+ br {
+ content: '';
+ display: block;
+ margin-top: 8px;
}
}
+
+ a {
+ color: #0aa;
+
+ &:hover {
+ color: #06c5c5;
+ text-decoration: none;
+ }
+ }
+
+ img {
+ max-width: 100%;
+ max-height: 300px;
+ }
}
diff --git a/web/app/components/comment/__username/comment__username.scss b/web/app/components/comment/__username/comment__username.scss
index 1546489b..75f1b9ed 100644
--- a/web/app/components/comment/__username/comment__username.scss
+++ b/web/app/components/comment/__username/comment__username.scss
@@ -1,3 +1,4 @@
.comment__username {
- color: #06c5c5;
+ color: #777;
+ font-weight: 700;
}
diff --git a/web/app/components/comment/_view/_admin/comment_view_admin.scss b/web/app/components/comment/_view/_admin/comment_view_admin.scss
index 5ab3a17c..9d24f9da 100644
--- a/web/app/components/comment/_view/_admin/comment_view_admin.scss
+++ b/web/app/components/comment/_view/_admin/comment_view_admin.scss
@@ -1,6 +1,5 @@
.comment_view_admin {
.comment__username {
- font-weight: 700;
color: #ff4700;
};
}
diff --git a/web/app/components/comment/comment.jsx b/web/app/components/comment/comment.jsx
index eb50fc25..9df571cf 100644
--- a/web/app/components/comment/comment.jsx
+++ b/web/app/components/comment/comment.jsx
@@ -141,6 +141,7 @@ export default class Comment extends Component {
render(props, { userBlocked, pinned, score, scoreIncreased, scoreDecreased, isInputVisible }) {
const { data, mix, mods = {} } = props;
const isAdmin = store.get('user').admin;
+ const isGuest = !Object.keys(store.get('user')).length;
const time = new Date(data.time);
// TODO: which format for datetime should we choose?
@@ -176,7 +177,6 @@ export default class Comment extends Component {
- {/* TODO: add link to user's profile in social if we have it */}
{o.user.name}
@@ -195,7 +195,7 @@ export default class Comment extends Component {
{o.time}
{
- !mods.disabled && (
+ !mods.disabled && !isGuest && (
reply
diff --git a/web/app/components/comment/comment.scss b/web/app/components/comment/comment.scss
index 9fd079b8..bf3711e0 100644
--- a/web/app/components/comment/comment.scss
+++ b/web/app/components/comment/comment.scss
@@ -3,14 +3,13 @@
.comment {
position: relative;
overflow: hidden;
- margin-bottom: $offset;
+ margin-bottom: $offset / 2;
font-size: 16px;
line-height: 1.2;
@media (hover: hover) {
&:hover {
.comment__controls {
- transform: translateX(8px);
opacity: 1;
}
}
diff --git a/web/app/components/input/__button/input__button.scss b/web/app/components/input/__button/input__button.scss
index 6cf3f2c8..ffd4c323 100644
--- a/web/app/components/input/__button/input__button.scss
+++ b/web/app/components/input/__button/input__button.scss
@@ -8,6 +8,7 @@
bottom: 0;
box-sizing: border-box;
width: $buttonWidth;
+ height: 100%;
padding: 0 10px;
font-size: 16px;
border: 0;
diff --git a/web/app/components/preloader/__bounce/preloader__bounce.scss b/web/app/components/preloader/__bounce/preloader__bounce.scss
new file mode 100644
index 00000000..009c0c7d
--- /dev/null
+++ b/web/app/components/preloader/__bounce/preloader__bounce.scss
@@ -0,0 +1,35 @@
+.preloader__bounce {
+ display: inline-block;
+ width: 10px;
+ height: 10px;
+ margin-right: 3px;
+ background-color: #333;
+ border-radius: 100%;
+ animation: preloaderBounce 1.4s infinite ease-in-out both;
+
+ &:first-child {
+ animation-delay: -.32s;
+ }
+
+ &:nth-child(2) {
+ animation-delay: -.16s;
+ }
+
+ &:last-child {
+ margin-right: 0;
+ }
+
+ @keyframes preloaderBounce {
+ 0% {
+ transform: scale(0);
+ }
+
+ 40% {
+ transform: scale(1);
+ }
+
+ 80%, 100% {
+ transform: scale(0);
+ }
+ }
+}
diff --git a/web/app/components/preloader/index.js b/web/app/components/preloader/index.js
new file mode 100644
index 00000000..74d4e5b1
--- /dev/null
+++ b/web/app/components/preloader/index.js
@@ -0,0 +1,5 @@
+export { default } from './preloader';
+
+require('./preloader.scss');
+
+require('./__bounce/preloader__bounce.scss');
diff --git a/web/app/components/preloader/preloader.jsx b/web/app/components/preloader/preloader.jsx
new file mode 100644
index 00000000..e2ab0ed5
--- /dev/null
+++ b/web/app/components/preloader/preloader.jsx
@@ -0,0 +1,13 @@
+import { h, Component } from 'preact';
+
+export default class Preloader extends Component {
+ render(props, state) {
+ return (
+
+ );
+ }
+}
diff --git a/web/app/components/preloader/preloader.scss b/web/app/components/preloader/preloader.scss
new file mode 100644
index 00000000..932b616b
--- /dev/null
+++ b/web/app/components/preloader/preloader.scss
@@ -0,0 +1,5 @@
+.preloader {
+ width: 60px;
+ text-align: center;
+ font-size: 0;
+}
diff --git a/web/app/components/root/__auth-panel/root__auth-panel.scss b/web/app/components/root/__auth-panel/root__auth-panel.scss
deleted file mode 100644
index 1bda3eb6..00000000
--- a/web/app/components/root/__auth-panel/root__auth-panel.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-.root__auth-panel {
- margin-bottom: 4px;
-}
diff --git a/web/app/components/root/__input/root__input.scss b/web/app/components/root/__input/root__input.scss
index 2440c942..cfa788fd 100644
--- a/web/app/components/root/__input/root__input.scss
+++ b/web/app/components/root/__input/root__input.scss
@@ -1,3 +1,3 @@
.root__input {
- margin-bottom: 24px;
+ margin-top: 4px;
}
diff --git a/web/app/components/root/__pinned-comments/root__pinned-comments.scss b/web/app/components/root/__pinned-comments/root__pinned-comments.scss
index 7ffef917..547c776a 100644
--- a/web/app/components/root/__pinned-comments/root__pinned-comments.scss
+++ b/web/app/components/root/__pinned-comments/root__pinned-comments.scss
@@ -1,7 +1,7 @@
@import 'common/variables';
.root__pinned-comments {
- margin-bottom: $offset * 2;
+ margin-top: 24px;
padding: ($offset / 3) ($offset / 2);
border: 2px solid #0aa;
border-radius: 4px;
diff --git a/web/app/components/root/__preloader/root__preloader.scss b/web/app/components/root/__preloader/root__preloader.scss
new file mode 100644
index 00000000..77af553b
--- /dev/null
+++ b/web/app/components/root/__preloader/root__preloader.scss
@@ -0,0 +1,6 @@
+.root__preloader {
+ position: absolute;
+ left: 0;
+ right: 0;
+ margin: 0 auto;
+}
diff --git a/web/app/components/root/__threads/root__threads.scss b/web/app/components/root/__threads/root__threads.scss
new file mode 100644
index 00000000..b3e37227
--- /dev/null
+++ b/web/app/components/root/__threads/root__threads.scss
@@ -0,0 +1,3 @@
+.root__threads {
+ margin-top: 24px;
+}
diff --git a/web/app/components/root/_loading/root_loading.scss b/web/app/components/root/_loading/root_loading.scss
deleted file mode 100644
index 4674958e..00000000
--- a/web/app/components/root/_loading/root_loading.scss
+++ /dev/null
@@ -1,39 +0,0 @@
-// TODO: add true preloader
-
-.root_loading {
- position: relative;
- height: 3em;
-
- &::after {
- content: 'Loading..';
- position: absolute;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- margin: auto;
- animation: rootLoading 1s infinite;
- }
-
- @keyframes rootLoading {
- 0% {
- content: 'Loading..';
- }
-
- 25% {
- content: 'Loading...';
- }
-
- 50% {
- content: 'Loading..';
- }
-
- 75% {
- content: 'Loading.';
- }
-
- 100% {
- content: 'Loading.';
- }
- }
-}
diff --git a/web/app/components/root/index.js b/web/app/components/root/index.js
index 387778d4..b2eef646 100644
--- a/web/app/components/root/index.js
+++ b/web/app/components/root/index.js
@@ -2,10 +2,9 @@ export { default } from './root';
require('./root.scss');
-require('./__auth-panel/root__auth-panel.scss');
require('./__input/root__input.scss');
+require('./__preloader/root__preloader.scss');
require('./__pinned-comment/root__pinned-comment.scss');
require('./__pinned-comments/root__pinned-comments.scss');
require('./__thread/root__thread.scss');
-
-require('./_loading/root_loading.scss');
+require('./__threads/root__threads.scss');
diff --git a/web/app/components/root/root.jsx b/web/app/components/root/root.jsx
index e7c280e4..52a0f1a7 100644
--- a/web/app/components/root/root.jsx
+++ b/web/app/components/root/root.jsx
@@ -8,6 +8,7 @@ import store from 'common/store';
import AuthPanel from 'components/auth-panel';
import Comment from 'components/comment';
import Input from 'components/input';
+import Preloader from 'components/preloader';
import Thread from 'components/thread';
export default class Root extends Component {
@@ -91,29 +92,35 @@ export default class Root extends Component {
if (!loaded) {
return (
);
}
// TODO: i think we should do it on backend
const pinnedComments = store.getPinnedComments();
+ const isGuest = !Object.keys(user).length;
return (
-
+
-
+ {
+ !isGuest && (
+
+ )
+ }
{
!!pinnedComments.length && (
@@ -132,14 +139,20 @@ export default class Root extends Component {
}
{
- comments.map(thread => (
-
- ))
+ !!comments.length && (
+
+ {
+ comments.map(thread => (
+
+ ))
+ }
+
+ )
}
diff --git a/web/app/components/root/root.scss b/web/app/components/root/root.scss
index f5122fac..848f0443 100644
--- a/web/app/components/root/root.scss
+++ b/web/app/components/root/root.scss
@@ -1,3 +1,4 @@
.root {
+ position: relative;
font-family: 'PT Sans', Helvetica, Arial, sans-serif;
}
diff --git a/web/app/components/thread/thread.scss b/web/app/components/thread/thread.scss
index 59307364..a8149d32 100644
--- a/web/app/components/thread/thread.scss
+++ b/web/app/components/thread/thread.scss
@@ -1,5 +1,5 @@
@import 'common/variables';
.thread {
- margin-bottom: $offset;
+ margin-bottom: $offset / 2;
}
diff --git a/web/webpack.config.js b/web/webpack.config.js
index bffb9ec3..33bcf282 100644
--- a/web/webpack.config.js
+++ b/web/webpack.config.js
@@ -21,7 +21,7 @@ const commonStyleLoaders = [
plugins: [
require('autoprefixer')({ browsers: ['> 1%'] }),
require('postcss-url')({ url: 'inline', maxSize: 5 }),
- require('postcss-wrap')({ selector: `#${NODE_ID}` }),
+ require('postcss-wrap')({ selector: `#${NODE_ID}` , skip: /^html|body$/}),
require('postcss-csso'),
]
}