From 733343545f2be35f192011f2741dc8c41948cac8 Mon Sep 17 00:00:00 2001
From: Vitaly Takmazov
Date: Sat, 9 Jun 2018 15:50:47 +0300
Subject: many updates
---
vnext/package.json | 33 +-
vnext/src/app.js | 62 -
vnext/src/components/Discover.js | 35 +-
vnext/src/components/Icon.js | 41 +
vnext/src/components/LoginButton.js | 18 +-
vnext/src/components/Message.js | 20 +-
vnext/src/components/Post.js | 33 +-
vnext/src/components/Thread.js | 10 +-
vnext/src/index.js | 70 +
vnext/src/style/main.css | 81 +-
vnext/src/views/index.html | 5 +-
vnext/webpack.config.js | 41 +-
vnext/yarn.lock | 3187 +++++++++++------------------------
13 files changed, 1234 insertions(+), 2402 deletions(-)
delete mode 100644 vnext/src/app.js
create mode 100644 vnext/src/components/Icon.js
create mode 100644 vnext/src/index.js
diff --git a/vnext/package.json b/vnext/package.json
index 2799a42f..fabd4c19 100644
--- a/vnext/package.json
+++ b/vnext/package.json
@@ -1,32 +1,32 @@
{
"name": "juick",
- "version": "1.0.0",
+ "version": "3.0.0",
"description": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
- "compile": "webpack --mode=development",
- "dist": "webpack --mode=production",
- "start": "webpack-serve --mode=development"
+ "dist": "webpack -p",
+ "start": "webpack-serve"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
- "babel-core": "^6.26.0",
+ "babel-core": "^6.26.3",
"babel-loader": "^7.1.4",
- "babel-preset-env": "^1.6.1",
+ "babel-preset-env": "^1.7.0",
"babel-preset-react": "^6.24.1",
"connect-history-api-fallback": "^1.5.0",
"css-loader": "^0.28.11",
"file-loader": "^1.1.11",
"internal-ip": "^3.0.1",
"koa-connect": "^2.0.1",
+ "mini-css-extract-plugin": "^0.4.0",
+ "postcss-loader": "^2.1.5",
"prop-types": "^15.6.1",
- "react-hot-loader": "^4.0.1",
- "style-loader": "^0.20.3",
- "webpack": "^4.5.0",
- "webpack-cli": "^2.0.14",
- "webpack-serve": "^0.3.1"
+ "style-loader": "^0.21.0",
+ "webpack": "^4.12.0",
+ "webpack-cli": "^3.0.3",
+ "webpack-serve": "^1.0.4"
},
"babel": {
"presets": [
@@ -35,11 +35,12 @@
]
},
"dependencies": {
- "query-string": "^6.0.0",
- "react": "^16.3.1",
- "react-dom": "^16.3.1",
- "react-markdown": "^3.3.0",
- "react-router-dom": "^4.2.2",
+ "evil-icons": "^1.10.1",
+ "query-string": "^6.1.0",
+ "react": "^16.4.0",
+ "react-dom": "^16.4.0",
+ "react-markdown": "^3.3.2",
+ "react-router-dom": "^4.3.1",
"whatwg-fetch": "^2.0.4"
}
}
diff --git a/vnext/src/app.js b/vnext/src/app.js
deleted file mode 100644
index 1f323b51..00000000
--- a/vnext/src/app.js
+++ /dev/null
@@ -1,62 +0,0 @@
-import React from "react"
-import ReactDOM from "react-dom"
-import { BrowserRouter as Router, Route, Link } from "react-router-dom"
-
-import Discover from "./components/Discover"
-import Post from "./components/Post"
-import Thread from "./components/Thread"
-import LoginButton from "./components/LoginButton"
-
-class App extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- visitor: { uid: 0 }
- }
- }
- render() {
- return (
-
-
-
-
-
-
-
-
- )
- }
- auth(data) {
- console.log(data)
- }
-}
-
-
-ReactDOM.render(, document.getElementById("wrapper"));
diff --git a/vnext/src/components/Discover.js b/vnext/src/components/Discover.js
index 7fde3d88..63a0cad0 100644
--- a/vnext/src/components/Discover.js
+++ b/vnext/src/components/Discover.js
@@ -1,30 +1,25 @@
-import "whatwg-fetch"
-import React from "react"
-import PropTypes from "prop-types"
-import queryString from "query-string"
+import 'whatwg-fetch';
+import React from 'react';
+import PropTypes from 'prop-types';
+import queryString from 'query-string';
-import Message from "./Message"
+import Message from './Message';
export default class Discover extends React.Component {
constructor(props) {
- super(props)
+ super(props);
this.state = {
msgs: [],
loading: false,
search: this.props.location.search
- }
+ };
this.loadMessages = this.loadMessages.bind(this);
}
componentDidMount() {
this.loadMessages();
}
- componentWillReceiveProps(props) {
- if (props.params != this.props.params) {
- this.loadMessages();
- }
- }
loadMessages() {
- const url = "https://api.juick.com/messages" + this.state.search;
+ const url = 'https://api.juick.com/messages' + this.state.search;
fetch(url)
.then(response => {
return response.json()
@@ -32,20 +27,20 @@ export default class Discover extends React.Component {
.then(data =>
this.setState({ msgs: data })
).catch(ex => {
- console.log(ex)
+ console.log(ex);
});
}
- render() {
+ render() {
var nodes = this.state.msgs.map(msg => {
- return ()
- });
+ return ();
+ });
return (
{nodes}
- )
+ );
}
-};
+}
Discover.propTypes = {
msgs: PropTypes.array
-}
+};
diff --git a/vnext/src/components/Icon.js b/vnext/src/components/Icon.js
new file mode 100644
index 00000000..b4e8804c
--- /dev/null
+++ b/vnext/src/components/Icon.js
@@ -0,0 +1,41 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+export default class Icon extends React.Component {
+ constructor(props) {
+ super(props);
+ }
+
+ render() {
+ var size = this.props.size ? ' icon--' + this.props.size : '';
+ var className = this.props.className ? ' ' + this.props.className : '';
+ var klass = 'icon icon--' + this.props.name + size + className;
+
+ var name = '#' + this.props.name + '-icon';
+ var useTag = '';
+ var Icon = React.createElement('svg', { className: 'icon__cnt', dangerouslySetInnerHTML: { __html: useTag } });
+ return React.createElement(
+ 'div',
+ { className: klass },
+ this.wrapSpinner(Icon, klass)
+ );
+ }
+
+ wrapSpinner(Html, klass) {
+ if (klass.indexOf('spinner') > -1) {
+ return React.createElement(
+ 'div',
+ { className: 'icon__spinner' },
+ Html
+ );
+ } else {
+ return Html;
+ }
+ }
+}
+
+Icon.propTypes = {
+ size: PropTypes.string.isRequired,
+ name: PropTypes.string.isRequired,
+ className: PropTypes.string
+}
diff --git a/vnext/src/components/LoginButton.js b/vnext/src/components/LoginButton.js
index 8d298fa2..f35a932d 100644
--- a/vnext/src/components/LoginButton.js
+++ b/vnext/src/components/LoginButton.js
@@ -1,27 +1,29 @@
-import React from 'react'
-import PropTypes from 'prop-types'
+import React from 'react';
+import PropTypes from 'prop-types';
+import Icon from './Icon';
+
export default class LoginButton extends React.Component {
constructor(props) {
super(props);
- window.addEventListener("message", (event) => {
+ window.addEventListener('message', (event) => {
this.props.onAuth(event.data);
}, false);
}
login(event) {
event.preventDefault();
- let loginWindow = window.open("https://juick.com/login?redirect=false", "Login to Juick", "width=400,height=300,resizeable=no,menubar=no,toolbar=no,scrollbars=no");
+ let loginWindow = window.open('https://juick.com/login?redirect=false', 'Login to Juick', 'width=400,height=300,resizeable=no,menubar=no,toolbar=no,scrollbars=no');
loginWindow.window.focus();
}
render() {
return (
- {this.props.title}
- )
+ {this.props.title}
+ );
}
-};
+}
LoginButton.propTypes = {
title: PropTypes.string.isRequired,
onAuth: PropTypes.func.isRequired
-}
\ No newline at end of file
+};
diff --git a/vnext/src/components/Message.js b/vnext/src/components/Message.js
index ba853f5c..d3148141 100644
--- a/vnext/src/components/Message.js
+++ b/vnext/src/components/Message.js
@@ -1,9 +1,9 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-import ReactMarkdown from 'react-markdown'
+import React from 'react';
+import PropTypes from 'prop-types';
+import ReactMarkdown from 'react-markdown';
export default class Message extends React.Component {
- render() {
+ render() {
const msg = this.props.data;
return (
@@ -27,21 +27,22 @@ export default class Message extends React.Component {
- { msg.photo &&
+ { msg.photo &&
}
- )}
-};
+ );
+ }
+}
function Tags(props) {
return props.data && props.data.map(tag => { return ({ tag }) })
}
Message.propTypes = {
- msg: PropTypes.shape({
+ data: PropTypes.shape({
mid: PropTypes.number.isRequired,
user: PropTypes.shape({
uid: PropTypes.number.isRequired,
@@ -50,4 +51,5 @@ Message.propTypes = {
timestamp: PropTypes.string.isRequired,
body: PropTypes.string
})
-}
+};
+
diff --git a/vnext/src/components/Post.js b/vnext/src/components/Post.js
index 54be77df..3256bbf6 100644
--- a/vnext/src/components/Post.js
+++ b/vnext/src/components/Post.js
@@ -1,20 +1,21 @@
-import React from 'react'
+import React from 'react';
export default class Post extends React.Component {
- render() {
+ render() {
return (
-
-
- )}
-};
\ No newline at end of file
+
+
+ );
+ }
+}
diff --git a/vnext/src/components/Thread.js b/vnext/src/components/Thread.js
index 49d9ea4d..a17a2022 100644
--- a/vnext/src/components/Thread.js
+++ b/vnext/src/components/Thread.js
@@ -1,5 +1,5 @@
-import "whatwg-fetch"
-import React from "react"
+import 'whatwg-fetch';
+import React from 'react';
export default class Thread extends React.Component {
constructor(props) {
@@ -7,7 +7,7 @@ export default class Thread extends React.Component {
this.state = {
replies: [],
loading: false
- }
+ };
}
componentDidMount() {
}
@@ -18,6 +18,6 @@ export default class Thread extends React.Component {
{user}
{mid}
- )
+ );
}
-}
\ No newline at end of file
+}
diff --git a/vnext/src/index.js b/vnext/src/index.js
new file mode 100644
index 00000000..97431188
--- /dev/null
+++ b/vnext/src/index.js
@@ -0,0 +1,70 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
+import Icon from './components/Icon';
+import Discover from './components/Discover';
+import Post from './components/Post';
+import Thread from './components/Thread';
+import LoginButton from './components/LoginButton';
+
+class App extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ visitor: { uid: 0 }
+ };
+ }
+ render() {
+ return (
+
+
+
+
+
+
+
+
+ )
+ }
+ auth(data) {
+ console.log(data)
+ }
+}
+
+
+ReactDOM.render(, document.getElementById('wrapper'));
diff --git a/vnext/src/style/main.css b/vnext/src/style/main.css
index 24108030..69c29f07 100644
--- a/vnext/src/style/main.css
+++ b/vnext/src/style/main.css
@@ -85,6 +85,11 @@ html {
margin: 12px 0 0 0;
width: 728px;
}
+#minimal_content {
+ margin: 0 auto;
+ min-width: 310px;
+ width: auto;
+}
body > header {
box-shadow: 0 0 3px rgba(0, 0, 0, 0.28);
background: #fff;
@@ -92,11 +97,26 @@ body > header {
top: 0;
width: 100%;
z-index: 10;
+ -webkit-transition-duration: 0.5s;
+ transition-duration: 0.5s;
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ -webkit-transition-property: -webkit-transform;
+ transition-property: transform;
}
#header_wrapper {
margin: 0 auto;
width: 1000px;
display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex-wrap: wrap;
+ padding: 4px;
+}
+.header--hidden {
+ -webkit-transform: translateY(-100%);
+ -ms-transform: translateY(-100%);
+ transform: translateY(-100%);
}
#footer {
clear: both;
@@ -142,7 +162,6 @@ body > header {
#logo {
height: 36px;
- margin: 7px 25px 0 20px;
width: 110px;
}
#logo a {
@@ -157,7 +176,6 @@ body > header {
width: 110px;
}
#global {
- flex-grow: 1;
display: flex;
}
#global a {
@@ -169,31 +187,24 @@ body > header {
#global li {
display: inline-block;
}
+#ctitle a {
+ padding: 14px;
+}
#global li:hover,
+#ctitle a:hover,
.l a:hover {
background-color: #fff;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.16);
cursor: pointer;
transition: box-shadow 0.2s ease-in;
}
-#search {
- margin: 12px 20px 12px 0;
-}
#search input {
background: #FFF;
- border: 1px solid #DDDDD5;
+ border: 1px solid #ccc;
outline: none !important;
padding: 4px;
-}
-@media screen and (max-width: 850px) {
- #logo {
- display: none;
- }
- #search {
- display: inline-block;
- float: none;
- margin: 10px 10px;
- }
+ -webkit-appearance: none;
+ border-radius: 0;
}
/* #endregion */
@@ -262,10 +273,12 @@ body > header {
/* #endregion */
/* #region main content */
-
#content > p,
#content > h1,
-#content > h2 {
+#content > h2,
+#minimal_content > p,
+#minimal_content > h1,
+#minimal_content > h2 {
margin: 1em 0;
}
.page {
@@ -331,10 +344,11 @@ article .tags {
margin-top: 3px;
}
.msg-tags {
- margin-top: 5px;
- min-height: 30px;
+ margin-top: 12px;
+ min-height: 1px;
}
article .tags > a,
+.badge,
.msg-tags > a {
background: #eee;
border: 1px solid #eee;
@@ -382,7 +396,6 @@ article .tags > a,
border-right: 5px solid #0C0;
}
.msg-ts {
- float: right;
font-size: small;
vertical-align: top;
}
@@ -478,6 +491,16 @@ article .tags > a,
}
@media screen and (max-width: 850px) {
+ #header_wrapper {
+ width: auto;
+ }
+ #global {
+ justify-content: space-around;
+ flex-grow: 1;
+ }
+ #search {
+ padding: 4px;
+ }
article {
overflow: auto;
}
@@ -509,12 +532,18 @@ article .tags > a,
}
@media screen and (max-width: 480px) {
- .msg-ts {
- float: none;
+ #wrapper {
+ margin-top: 104px;
+ }
+ #search {
+ display: none;
+ }
+ #global a {
+ padding: 14px 2px;
}
- .msg-tags {
- margin-top: 10px;
- min-height: 1px;
+ .msg-cont > nav.l,
+ article > nav.l {
+ font-size: 9pt;
}
.msg-txt {
padding-top: 5px;
diff --git a/vnext/src/views/index.html b/vnext/src/views/index.html
index 661634d6..74583a13 100644
--- a/vnext/src/views/index.html
+++ b/vnext/src/views/index.html
@@ -13,6 +13,9 @@
+
+
+
@@ -40,6 +43,6 @@
-
+