Skip to content

Commit b2555bc

Browse files
committed
lots of updates, include suspense
1 parent fcc3a30 commit b2555bc

32 files changed

Lines changed: 1784 additions & 865 deletions

index.html

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,33 @@
11
<!DOCTYPE html>
22
<html>
3-
<head>
4-
<meta charset="utf-8">
3+
<head>
4+
<meta charset="utf-8" />
55
<title>Conduit</title>
6+
<meta content="width=device-width" name="viewport">
67
<!-- Import Ionicon icons & Google Fonts our Bootstrap theme relies on -->
7-
<link href="//code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css" rel="stylesheet" type="text/css">
8-
<link href="//fonts.googleapis.com/css?family=Titillium+Web:700|Source+Serif+Pro:400,700|Merriweather+Sans:400,700|Source+Sans+Pro:400,300,600,700,300italic,400italic,600italic,700italic"
9-
rel="stylesheet" type="text/css">
8+
<link
9+
href="//code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css"
10+
rel="stylesheet"
11+
type="text/css"
12+
/>
13+
<link
14+
href="//fonts.googleapis.com/css?family=Titillium+Web:700|Source+Serif+Pro:400,700|Merriweather+Sans:400,700|Source+Sans+Pro:400,300,600,700,300italic,400italic,600italic,700italic"
15+
rel="stylesheet"
16+
type="text/css"
17+
/>
1018
<!-- Import the custom Bootstrap 4 theme from our hosted CDN -->
11-
<link rel="stylesheet" href="//demo.productionready.io/main.css">
12-
<link rel="shortcut icon" type="image/x-icon" href="//demo.productionready.io/favicon.ico"/>
13-
</head>
14-
<body>
19+
<link rel="preconnect" href="https://static.productionready.io" crossorigin />
20+
<link rel="preconnect" href="https://conduit.productionready.io" crossorigin />
21+
<link rel="preconnect" href="http://code.ionicframework.com" crossorigin />
22+
<link rel="stylesheet" href="//demo.productionready.io/main.css" />
23+
<link
24+
rel="shortcut icon"
25+
type="image/x-icon"
26+
href="//demo.productionready.io/favicon.ico"
27+
/>
28+
<style>body{min-height: 101vh;}</style>
29+
</head>
30+
<body>
1531
<script type="module" src="./dist/index.js"></script>
16-
</body>
17-
</html>
32+
</body>
33+
</html>

package-lock.json

Lines changed: 693 additions & 138 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "A Solid Implementation of the Realworld Example App",
55
"main": "dist/index.js",
66
"scripts": {
7-
"start": "rollup -w -c",
7+
"start": "serve -l 5000 -s & rollup -w -c",
88
"build": "rollup -c --environment production",
99
"test": "test"
1010
},
@@ -24,19 +24,20 @@
2424
},
2525
"homepage": "https://github.com/ryansolid/solid-realworld#readme",
2626
"dependencies": {
27-
"marked": "0.6.3",
28-
"solid-js": "0.15.4"
27+
"marked": "^0.8.0",
28+
"solid-js": "0.16.6"
2929
},
3030
"devDependencies": {
31-
"@babel/core": "7.7.4",
32-
"@babel/plugin-syntax-dynamic-import": "7.2.0",
33-
"babel-preset-solid": "0.15.4",
34-
"rollup": "1.27.14",
31+
"@babel/core": "7.8.3",
32+
"@babel/plugin-proposal-optional-chaining": "7.8.3",
33+
"@babel/plugin-syntax-dynamic-import": "7.8.3",
34+
"babel-preset-solid": "~0.16.6",
35+
"rollup": "1.29.0",
3536
"rollup-plugin-babel": "4.3.3",
3637
"rollup-plugin-clear": "^2.0.7",
3738
"rollup-plugin-commonjs": "^10.1.0",
3839
"rollup-plugin-node-resolve": "5.2.0",
39-
"rollup-plugin-serve": "^1.0.1",
40-
"rollup-plugin-terser": "^5.1.3"
40+
"rollup-plugin-terser": "^5.2.0",
41+
"serve": "^11.3.0"
4142
}
4243
}

rollup.config.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import commonjs from "rollup-plugin-commonjs";
33
import babel from "rollup-plugin-babel";
44
import clear from "rollup-plugin-clear";
55
import { terser } from "rollup-plugin-terser";
6-
import serve from "rollup-plugin-serve";
76

87
const plugins = [
98
clear({
@@ -13,12 +12,10 @@ const plugins = [
1312
babel({
1413
exclude: "node_modules/**",
1514
presets: ["solid"],
16-
plugins: ["@babel/syntax-dynamic-import"]
15+
plugins: ["@babel/syntax-dynamic-import", "@babel/plugin-proposal-optional-chaining"]
1716
}),
1817
resolve({ extensions: [".js", ".jsx"] }),
1918
commonjs(),
20-
!process.env.production &&
21-
serve({ contentBase: "", host: "0.0.0.0", port: 5000 }),
2219
process.env.production && terser()
2320
];
2421

src/App.js

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,36 @@
11
import { lazy } from "solid-js";
2-
import { useStore } from "./store";
2+
import { useStore, useRouter } from "./store";
3+
import NavBar from "./components/NavBar";
34

4-
const NavBar = lazy(() => import("./components/NavBar")),
5-
Home = lazy(() => import("./components/Home")),
5+
const Home = lazy(() => import("./components/Home")),
66
Editor = lazy(() => import("./components/Editor")),
77
Settings = lazy(() => import("./components/Settings")),
88
Auth = lazy(() => import("./components/Auth")),
99
Article = lazy(() => import("./components/Article")),
1010
Profile = lazy(() => import("./components/Profile"));
1111

1212
export default () => {
13-
const [CommonStore, UserStore, { match, getParams }] = useStore(
14-
"common",
15-
"user",
16-
"router"
17-
);
13+
const [store, { setAppLoaded, pullUser }] = useStore(),
14+
{ match, getParams } = useRouter();
1815

19-
if (!CommonStore.state.token) CommonStore.setAppLoaded();
20-
else UserStore.pullUser().finally(() => CommonStore.setAppLoaded());
16+
if (!store.token) setAppLoaded();
17+
else pullUser().finally(() => setAppLoaded());
2118

2219
return (
2320
<>
2421
<NavBar />
25-
<Show when={CommonStore.state.appLoaded}>
26-
<Switch>
27-
<Match when={match("editor", /^editor\/?(.*)/)}><Editor {...getParams()} /></Match>
28-
<Match when={match("settings", /^settings/)}><Settings /></Match>
29-
<Match when={match("login", /^login/)}><Auth /></Match>
30-
<Match when={match("register", /^register/)}><Auth /></Match>
31-
<Match when={match("article", /^article\/(.*)/)}><Article {...getParams()} /></Match>
32-
<Match when={match("profile", /^@([^/]*)\/?(favorites)?/)}><Profile {...getParams()} /></Match>
33-
<Match when={match("", /^#?$/)}><Home /></Match>
34-
</Switch>
22+
<Show when={store.appLoaded}>
23+
<Suspense fallback={"Loading..."}>
24+
<Switch>
25+
<Match when={match("editor", /^editor\/?(.*)/)}><Editor {...getParams()} /></Match>
26+
<Match when={match("settings", /^settings/)}><Settings /></Match>
27+
<Match when={match("login", /^login/)}><Auth /></Match>
28+
<Match when={match("register", /^register/)}><Auth /></Match>
29+
<Match when={match("article", /^article\/(.*)/)}><Article {...getParams()} /></Match>
30+
<Match when={match("profile", /^@([^/]*)\/?(favorites)?/)}><Profile {...getParams()} /></Match>
31+
<Match when={match("", /^#?$/)}><Home /></Match>
32+
</Switch>
33+
</Suspense>
3534
</Show>
3635
</>
3736
);

src/components/Article.js

Lines changed: 62 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,12 @@ const ArticleActions = props => {
1313
<NavLink
1414
href={`editor/${article.slug}`}
1515
route="editor"
16-
className="btn btn-outline-secondary btn-sm"
16+
class="btn btn-outline-secondary btn-sm"
1717
>
18-
<i className="ion-edit" /> Edit Article
18+
<i class="ion-edit" /> Edit Article
1919
</NavLink>
20-
<button
21-
className="btn btn-outline-danger btn-sm"
22-
onClick={handleDelete}
23-
>
24-
<i className="ion-trash-a" /> Delete Article
20+
<button class="btn btn-outline-danger btn-sm" onClick={handleDelete}>
21+
<i class="ion-trash-a" /> Delete Article
2522
</button>
2623
</span>
2724
</Show>
@@ -31,18 +28,20 @@ const ArticleActions = props => {
3128
const ArticleMeta = props => {
3229
const article = props.article;
3330
return (
34-
<div className="article-meta">
31+
<div class="article-meta">
3532
<NavLink href={`@${article.author.username}`} route="profile">
3633
<img src={article.author.image} alt="" />
3734
</NavLink>
3835

39-
<div className="info">
40-
<NavLink href={`@${article.author.username}`} route="profile" className="author">
36+
<div class="info">
37+
<NavLink
38+
href={`@${article.author.username}`}
39+
route="profile"
40+
class="author"
41+
>
4142
{article.author.username}
4243
</NavLink>
43-
<span className="date">
44-
{new Date(article.createdAt).toDateString()}
45-
</span>
44+
<span class="date">{new Date(article.createdAt).toDateString()}</span>
4645
</div>
4746

4847
<ArticleActions
@@ -59,31 +58,32 @@ const Comment = props => {
5958
const show =
6059
props.currentUser && props.currentUser.username === comment.author.username;
6160
return (
62-
<div className="card">
63-
<div className="card-block">
64-
<p className="card-text">{comment.body}</p>
61+
<div class="card">
62+
<div class="card-block">
63+
<p class="card-text">{comment.body}</p>
6564
</div>
66-
<div className="card-footer">
67-
<NavLink href={`@${comment.author.username}`} route="profile" className="comment-author">
68-
<img
69-
src={comment.author.image}
70-
className="comment-author-img"
71-
alt=""
72-
/>
65+
<div class="card-footer">
66+
<NavLink
67+
href={`@${comment.author.username}`}
68+
route="profile"
69+
class="comment-author"
70+
>
71+
<img src={comment.author.image} class="comment-author-img" alt="" />
7372
</NavLink>
7473
&nbsp;
75-
<NavLink href={`@${comment.author.username}`} route="profile" className="comment-author">
74+
<NavLink
75+
href={`@${comment.author.username}`}
76+
route="profile"
77+
class="comment-author"
78+
>
7679
{comment.author.username}
7780
</NavLink>
78-
<span className="date-posted">
81+
<span class="date-posted">
7982
{new Date(comment.createdAt).toDateString()}
8083
</span>
8184
{show && (
82-
<span className="mod-options">
83-
<i
84-
className="ion-trash-a"
85-
onClick={() => props.onDelete(comment.id)}
86-
/>
85+
<span class="mod-options">
86+
<i class="ion-trash-a" onClick={() => props.onDelete(comment.id)} />
8787
</span>
8888
)}
8989
</div>
@@ -92,34 +92,30 @@ const Comment = props => {
9292
};
9393

9494
const CommentInput = props => {
95-
const [CommentsStore] = useStore("comments"),
95+
const [, { createComment }] = useStore(),
9696
[state, setState] = createState({ body: "" }),
9797
handleBodyChange = ev => setState({ body: ev.target.value }),
98-
createComment = ev => {
98+
createCommentHandler = ev => {
9999
ev.preventDefault();
100-
CommentsStore.createComment({ body: state.body }).then(() =>
100+
createComment({ body: state.body }).then(() =>
101101
setState({ body: "" })
102102
);
103103
};
104104
return (
105-
<form className="card comment-form" onSubmit={createComment}>
106-
<div className="card-block">
105+
<form class="card comment-form" onSubmit={createCommentHandler}>
106+
<div class="card-block">
107107
<textarea
108-
className="form-control"
108+
class="form-control"
109109
placeholder="Write a comment..."
110110
value={state.body}
111-
disabled={CommentsStore.state.isCreatingComment}
111+
disabled={store.isCreatingComment}
112112
onChange={handleBodyChange}
113113
rows="3"
114114
/>
115115
</div>
116-
<div className="card-footer">
117-
<img
118-
src={props.currentUser.image}
119-
className="comment-author-img"
120-
alt=""
121-
/>
122-
<button className="btn btn-sm btn-primary" type="submit">
116+
<div class="card-footer">
117+
<img src={props.currentUser.image} class="comment-author-img" alt="" />
118+
<button class="btn btn-sm btn-primary" type="submit">
123119
Post Comment
124120
</button>
125121
</div>
@@ -128,7 +124,7 @@ const CommentInput = props => {
128124
};
129125

130126
const CommentContainer = props => (
131-
<div className="col-xs-12 col-md-8 offset-md-2">
127+
<div class="col-xs-12 col-md-8 offset-md-2">
132128
<Show
133129
when={props.currentUser}
134130
fallback={
@@ -159,34 +155,28 @@ const CommentContainer = props => (
159155

160156
export default props => {
161157
let canModify;
162-
const [ArticlesStore, CommentsStore, UserStore] = useStore(
163-
"articles",
164-
"comments",
165-
"user"
166-
),
158+
const [store, { loadArticle, deleteArticle, deleteComment, loadComments }] = useStore(),
167159
slug = props.params[0],
168-
article = () => ArticlesStore.state.articlesRegistry[slug],
160+
article = () => store.articles[slug],
169161
handleDeleteArticle = slug =>
170-
ArticlesStore.deleteArticle(slug).then(() => {
162+
deleteArticle(slug).then(() => {
171163
// this.props.history.replace("/")
172-
}),
173-
handleDeleteComment = id => CommentsStore.deleteComment(id);
164+
});
174165

175-
ArticlesStore.loadArticle(slug, { acceptCached: true });
176-
CommentsStore.setArticleSlug(slug);
177-
CommentsStore.loadComments();
166+
loadArticle(slug, { acceptCached: true });
167+
loadComments(slug);
178168

179169
return (
180170
<div class="article-page">
181171
<Show when={article()}>
182172
{
183173
((canModify =
184-
UserStore.state.currentUser &&
185-
UserStore.state.currentUser.username === article.author.username),
174+
store.currentUser &&
175+
store.currentUser.username === article().author.username),
186176
(
187177
<>
188-
<div className="banner">
189-
<div className="container">
178+
<div class="banner">
179+
<div class="container">
190180
<h1>{article().title}</h1>
191181
<ArticleMeta
192182
article={article()}
@@ -197,14 +187,16 @@ export default props => {
197187
</div>
198188

199189
<div class="container page">
200-
<div className="row article-content">
201-
<div className="col-xs-12">
202-
<div innerHTML={marked(article().body, { sanitize: true })} />
190+
<div class="row article-content">
191+
<div class="col-xs-12">
192+
<div
193+
innerHTML={marked(article().body, { sanitize: true })}
194+
/>
203195

204-
<ul className="tag-list">
196+
<ul class="tag-list">
205197
{article().tagList.map(tag => {
206198
return (
207-
<li className="tag-default tag-pill tag-outline">
199+
<li class="tag-default tag-pill tag-outline">
208200
{tag}
209201
</li>
210202
);
@@ -225,11 +217,11 @@ export default props => {
225217

226218
<div class="row">
227219
<CommentContainer
228-
comments={CommentsStore.state.comments}
229-
errors={CommentsStore.state.commentErrors}
220+
comments={store.comments}
221+
errors={store.commentErrors}
230222
slug={slug}
231-
currentUser={UserStore.state.currentUser}
232-
onDelete={handleDeleteComment}
223+
currentUser={store.currentUser}
224+
onDelete={deleteComment}
233225
/>
234226
</div>
235227
</div>

0 commit comments

Comments
 (0)