Skip to content

Commit

Permalink
Corrections after first testing
Browse files Browse the repository at this point in the history
  • Loading branch information
optimista committed Jun 4, 2021
1 parent c9d9e47 commit 34ebe7d
Show file tree
Hide file tree
Showing 20 changed files with 62 additions and 44 deletions.
2 changes: 1 addition & 1 deletion fbc/src/app/core/Feed.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const useStyles = makeStyles(theme => ({
}
}))

const Feed = ({ collection, Item, orderBy = "timestamp", profileId, ready = true }) => {
const Feed = ({ collection, Item = () => null, orderBy = "timestamp", profileId, ready = true }) => {
const [batches, setBatches] = useState([]),
[fetching, setFetching, setHasMore] = useInfiniteScroll({ fetching: true, hasMore: true }),
listeners = useRef([]),
Expand Down
2 changes: 1 addition & 1 deletion fbc/src/app/core/Loading.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const LoadingScreen = ({ children = null, ready = false }) =>
children
:
<FocusLayout>
<CircularProgress size={40} />
<CircularProgress size={40} sx={{ display: "block", margin: "auto" }} />
</FocusLayout>

export default LoadingScreen;
7 changes: 4 additions & 3 deletions fbc/src/app/layouts/FeedLayout.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Grid, Link, List, ListItem, ListItemIcon, ListItemText, useMediaQuery } from '@material-ui/core'
import { makeStyles, useTheme } from '@material-ui/styles'
import { useTheme } from '@material-ui/core/styles'
import { HistoryEdu, HomeOutlined, LockOutlined, PaletteOutlined, PersonOutlined, PersonAddOutlined } from '@material-ui/icons'
import { makeStyles } from '@material-ui/styles'

import { useAuth } from 'auth'
import { Tooltip } from 'core'
Expand Down Expand Up @@ -41,8 +42,8 @@ const FeedLayout = ({ children, ...props }) => {
<Grid item className={classes.drawer}>
<List>
<DrawerItem href="/" Icon={HomeOutlined}>Home</DrawerItem>
<DrawerItem href={"/" + auth?.profile?.username} Icon={PersonOutlined} disabled={!auth}>Profile</DrawerItem>
<DrawerItem href="/stories" Icon={HistoryEdu} disabled={!auth}>Stories</DrawerItem>
<DrawerItem href={"/" + auth?.profile?.username} Icon={PersonOutlined} disabled={!auth.isLoggedIn}>Profile</DrawerItem>
<DrawerItem href="/stories" Icon={HistoryEdu} disabled={!auth.isLoggedIn}>Stories</DrawerItem>
</List>
<List>
<DrawerItem href="/join" Icon={PersonAddOutlined}>Join</DrawerItem>
Expand Down
2 changes: 1 addition & 1 deletion fbc/src/app/layouts/FocusLayout.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Container, Grid } from '@material-ui/core'

const FocusLayout = ({ children, maxWidth }) =>
<Container maxWidth={maxWidth}>
<Grid container sx={{ alignItems: "center", minHeight: "100vh", textAlign: "center" }}>
<Grid container sx={{ alignItems: "center", minHeight: "100vh" }}>
<Grid item xs={12}>{children}</Grid>
</Grid>
</Container>
Expand Down
2 changes: 1 addition & 1 deletion fbc/src/app/models/profile/Profile.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useDialog, useModel } from '@futo-ui/hooks'
import { Badge, Button, Dialog, Grid, Skeleton, Typography } from '@material-ui/core'
import { makeStyles } from '@material-ui/styles'
import { PhotoCamera } from '@material-ui/icons'
import { makeStyles } from '@material-ui/styles'
import { useRouter } from 'next/router'
import { useEffect, useState } from 'react'

Expand Down
10 changes: 5 additions & 5 deletions fbc/src/app/models/story/StoryCard.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { useMenu } from '@futo-ui/hooks'
import { time } from '@futo-ui/utils'
import { Card, CardActions, CardContent, Link, ListItemIcon, ListItemText, MenuItem, Skeleton, Typography } from '@material-ui/core'
import { DeleteOutlined, EditOutlined, ExpandMore } from '@material-ui/icons'

import { IconButton, Menu } from 'core'
import { Stories } from 'models/story'
import { description, lastEdited, storyPath, storyEditPath, title } from 'models/story/utils'

const StoryCard = ({ story }) => {
const menu = useMenu();
Expand All @@ -17,9 +17,9 @@ const StoryCard = ({ story }) => {
{
story ?
<>
<Link href={"/s/" + story.id} sx={{ display: "block" }} underline="none" variant="h6">{ story.nodes[story.order[0]]?.content || "Untitled Story" }</Link>
{ story.order[1] && <Typography variant="subtitle1">{story.nodes[story.order[1]].content}</Typography> }
<Typography variant="overline">{ "Last edited: " + time(story.editedAt) + " · " + story.order.length + " nodes" }</Typography>
<Link href={storyPath(story)} sx={{ display: "block" }} underline="none" variant="h6">{title(story)}</Link>
{ description(story) && <Typography variant="subtitle1">{description(story)}</Typography> }
<Typography variant="overline">{lastEdited(story)}</Typography>
</>
:
<>
Expand All @@ -37,7 +37,7 @@ const StoryCard = ({ story }) => {
<ExpandMore />
</IconButton>
<Menu anchorEl={menu.el} arrow open={menu.isOpen} onClose={menu.close} placement="end">
<MenuItem component={Link} href={"/s/" + story.id + "/edit"}>
<MenuItem component={Link} href={storyEditPath(story)}>
<ListItemIcon>
<EditOutlined />
</ListItemIcon>
Expand Down
2 changes: 1 addition & 1 deletion fbc/src/app/models/story/StoryFeed.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { Feed } from 'core'
import { Stories, StoryCard } from 'models/story'

const StoryFeed = props =>
<Feed Item={({ item, ...props }) => <StoryCard story={item} {...props} />} collection={Stories} {...props} orderBy="editedAt" />
<Feed Item={({ item, ...props }) => <StoryCard story={item} {...props} />} collection={Stories} orderBy="editedAt" {...props} />

export default StoryFeed;
7 changes: 0 additions & 7 deletions fbc/src/app/models/story/debug.js

This file was deleted.

11 changes: 6 additions & 5 deletions fbc/src/app/models/story/edit/Caret.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useEffect, useRef } from 'react'
import { ContentEditable, IconButton } from 'core'
import { useAutosave, useDispatch, useState } from 'models/story/context'
import { getPlaceholder, ImageButton } from 'models/story/edit'
import { emptyNodesKeymap, newNodeEnterActions } from 'models/story/state'
import { newNodeEnterActions } from 'models/story/state'

const Caret = props => {
const autosave = useAutosave(),
Expand All @@ -18,8 +18,8 @@ const Caret = props => {
useEffect(() => { if (state.caret.pending) {
focus(caretRef.current, state.caret.offset); dispatch({ type: "CARET_FOCUSED" }); }}, [state.caret.pending]);

const handleBlur = () => dispatch(state => {
const keymap = emptyNodesKeymap(state);
const handleBlur = () => state.caret.fold && dispatch(state => {
const keymap = { [state.caret.key]: empty(state.story.nodes[state.caret.key].content) };
return [{ type: "CARET_BLUR" }, { type: "NODES_REMOVE", keymap }, { type: "VIEW_REMOVE", keymap }];
});

Expand All @@ -36,11 +36,12 @@ const Caret = props => {
}}
}

const handleFoldClick = () => dispatch({ type: "CARET_FOLD" });
const handleToggle = () =>
dispatch(state => [{ type: "CARET_TOGGLE" }, ...(state.caret.fold ? [] : [{ type: "CARET_FOCUS", key: state.caret.key }])]);

return (
<>
{ empty(content) && <IconButton color="secondary" onClick={handleFoldClick} onMouseDown={e => e.preventDefault()} sx={{ left: -5, position: "absolute", top: "50%", transform: "translate(-100%, -50%)" + (state.caret.fold ? "" : "rotate(-45deg)"), transition: "transform 0.5s" }}><Add /></IconButton> }
{ empty(content) && <IconButton color="secondary" onClick={handleToggle} onMouseDown={e => e.preventDefault()} sx={{ left: -5, position: "absolute", top: "50%", transform: "translate(-100%, -50%)" + (state.caret.fold ? "" : "rotate(-45deg)"), transition: "transform 0.5s" }}><Add /></IconButton> }
<ContentEditable html={content} onBlur={handleBlur} onChange={handleChange} onKeyDown={handleKeyDown} placeholder={getPlaceholder(state)} ref={caretRef} sx={state.caret.fold ? {} : { opacity: 0, pointerEvents: "none" }} {...props} />
<Box onMouseDown={e => e.preventDefault()} sx={{ position: "absolute", top: "50%", transform: "translate(0, -50%)", ...(state.caret.fold ? { opacity: 0, pointerEvents: "none" } : {}) }}>
<ImageButton />
Expand Down
15 changes: 9 additions & 6 deletions fbc/src/app/models/story/edit/ImageButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { v4 } from 'uuid'
import { IconButton } from 'core'
import { firebase } from 'utils'

import { useDispatch, useState } from 'models/story/context'
import { useAutosave, useDispatch, useState } from 'models/story/context'

const MIME_TYPES = ["image/jpeg", "image/png", "image/webp"];
const MIME_TYPES = ["image/gif", "image/jpeg", "image/png", "image/webp"];

const ImageButton = () => {
const dispatch = useDispatch(), state = useState();
const autosave = useAutosave(), dispatch = useDispatch(), state = useState();

const handleFileChange = e => {
const handleChange = e => {
const file = e.target.files[0];
if (file && 0 < MIME_TYPES.filter(s => file.type.match(s)).length) {
const reader = new FileReader();
Expand All @@ -25,7 +25,10 @@ const ImageButton = () => {
upload.on("state_changed",
() => {}, // TODO: snapshot => console.log(snapshot.bytesTransferred / snapshot.totalBytes),
() => {}, // TODO: handle err => {}
() => upload.snapshot.ref.getDownloadURL().then(downloadURL => dispatch({ type: "NODE_EDIT", key, value: downloadURL }))
() => upload.snapshot.ref.getDownloadURL().then(downloadURL => {
dispatch({ type: "NODE_EDIT", key, value: downloadURL });
autosave.dispatch({ type: "TRIGGER" });
})
);
}
}
Expand All @@ -35,7 +38,7 @@ const ImageButton = () => {

return (
<IconButton htmlFor="image-file" component="label">
<input accept={MIME_TYPES.join(",")} hidden id="image-file" onChange={handleFileChange} type="file" />
<input accept={MIME_TYPES.join(",")} hidden id="image-file" onChange={handleChange} type="file" />
<ImageOutlined />
</IconButton>
)
Expand Down
10 changes: 7 additions & 3 deletions fbc/src/app/models/story/edit/StoryEditor.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { empty, nondraggable } from '@futo-ui/utils'
import { useEffect } from 'react'
import { last, nondraggable } from '@futo-ui/utils'
import { useEffect, useRef } from 'react'

import { useAutosave, useDispatch, useState } from 'models/story/context'
import { Caret, TextFocusable } from 'models/story/edit'
Expand All @@ -12,7 +12,11 @@ const StoryEditor = props => {
const handleMouseUp = e => e.currentTarget === e.target &&
dispatch(state => state.grab.dragged ? [] : newNodeActions(state, clientToCoors(state, { x: e.clientX, y: e.clientY })))

useEffect(() => !empty(state.render.container) && dispatch(state => newNodeEnterActions(state)), [empty(state.render.container)]);
const lastNodeHeight = state.render.nodes[last(state.story.order)]?.height,
wasCalled = useRef(false);
useEffect(() => {
if (lastNodeHeight && !wasCalled.current) { wasCalled.current = true; dispatch(state => newNodeEnterActions(state)); }
}, [lastNodeHeight])

useGrabbing({ onMouseMoveDispatch: ({ handle, key, deltas }) => {
switch(handle) {
Expand Down
1 change: 0 additions & 1 deletion fbc/src/app/models/story/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export { default as debug } from './debug'
export { default as Stories } from './Stories'
export { default as StoryCard } from './StoryCard'
export { default as StoryFeed } from './StoryFeed'
4 changes: 2 additions & 2 deletions fbc/src/app/models/story/state/caretReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ const caretReducer = (caret = { fold: true, key: null, offset: 0, pending: false
case "CARET_BLUR":
return { ...caret, key: null };
case "CARET_FOCUS":
return { ...caret, key: action.key, offset: action.offset || 0, pending: true };
return { ...caret, fold: true, key: action.key, offset: action.offset || 0, pending: true };
case "CARET_FOCUSED":
return { ...caret, pending: false };
case "CARET_FOLD":
case "CARET_TOGGLE":
return { ...caret, fold: !caret.fold };
default:
return caret;
Expand Down
1 change: 0 additions & 1 deletion fbc/src/app/models/story/state/storyReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ const positionsReducer = (positions, action) => {
}

const storyReducer = (story = { nodes: {}, order: [], positions: {} }, action) => {
//if (action.type) console.log(action.type, story, action);
switch(action.type) {
case "STORY_LOAD":
return action.value;
Expand Down
15 changes: 15 additions & 0 deletions fbc/src/app/models/story/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { empty, time } from '@futo-ui/utils'

// Paths
const storyPath = ({ id }) => "/s/" + id;
const storyEditPath = ({ id }) => "/s/" + id + "/edit";

// Helpers
const textNodeKeys = ({ nodes, order }) => order.filter(k => empty(nodes[k].type) || nodes[k].type === "text");

// Props
const description = s => s.nodes[textNodeKeys(s)[1]]?.content;
const lastEdited = ({ editedAt, order }) => "Last edited: " + time(editedAt) + " · " + order.length + " nodes";
const title = s => s.nodes[textNodeKeys(s)[0]]?.content || "Untitled Story";

export { description, lastEdited, storyPath, storyEditPath, title };
2 changes: 1 addition & 1 deletion fbc/src/app/models/story/view/NodeContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const NodeContainer = ({ children, grabbable = false, id: key, sx, ...props }) =
...(state.grab.dragged ? nonselectable : {}),
...(state.grab.dragged && state.grab.handle === "node" && state.grab.key === key ? { pointerEvents: "none" } : {}),
...(state.grab.dragged && state.grab.handle === "node" && state.grab.key === key && state.trash.over ? { opacity: 0.5 } : {}),
...state.story.nodes[key].sx,
...state.story.sx?.[key],
...sx
}} {...props}>{children}</Box>
}
Expand Down
2 changes: 1 addition & 1 deletion fbc/src/firestore.rules
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ service cloud.firestore {
}
}
service firebase.storage {
match /b/cherries-ghguz.appspot.com/o {
match /b/projectid/o {
match /profiles/{profileId} {
allow read;
allow write: if request.auth.uid == profileId;
Expand Down
3 changes: 2 additions & 1 deletion fbc/src/pages/new.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import { Stories } from 'models/story'
import { AutosaveProvider, DispatchProvider, StoreProvider } from 'models/story/context'
import { StoryEditor } from 'models/story/edit'
import { caretReducer, grabReducer, renderReducer, storyReducer, viewReducer } from 'models/story/state'
import { storyEditPath } from 'models/story/utils'

const StoryNewPage = () => {
const [state, dispatch] = useReducer({ caretReducer, grabReducer, renderReducer, storyReducer, viewReducer }, { root: true }),
auth = useAuth(), router = useRouter(), { id } = router.query,
autosave = useAutosave({ query: () => Stories.doc(id).set(state.story) });

useEffect(() => auth.isReady &&
Stories.add({ ...state.story, profileId: auth.uid }).then(doc => router.replace("/s/" + doc.id + "/edit", null, { shallow: true })) &&
Stories.add({ ...state.story, profileId: auth.uid }).then(doc => router.replace(storyEditPath(doc), null, { shallow: true })) &&
dispatch(state => ({ type: "STORY_LOAD", value: { ...state.story, profileId: auth.uid } }))
, [auth.isReady]);

Expand Down
3 changes: 2 additions & 1 deletion fbc/src/pages/s/[id]/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Stories } from 'models/story'
import { AutosaveProvider, DispatchProvider, StoreProvider } from 'models/story/context'
import { StoryEditor } from 'models/story/edit'
import { caretReducer, grabReducer, renderReducer, storyReducer, trashReducer, viewReducer } from 'models/story/state'
import { storyPath } from 'models/story/utils'
import { useStoryLoad } from 'models/story/view'

const StoryEditPage = () => {
Expand All @@ -18,7 +19,7 @@ const StoryEditPage = () => {

return (
<FixedLayout>
<Authorize ready={Boolean(state.story.profileId)} redirect={"/s/" + id} uid={state.story.profileId}>
<Authorize ready={Boolean(state.story.profileId)} redirect={storyPath(state.story)} uid={state.story.profileId}>
<AutosaveProvider value={{ dispatch: autosave.dispatch }}>
<DispatchProvider value={dispatch}>
<StoreProvider value={state}>
Expand Down
5 changes: 3 additions & 2 deletions fbc/src/pages/stories.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { Box, Button, Link, Typography } from '@material-ui/core'

import { Authorize } from 'auth'
import { Authorize, useAuth } from 'auth'
import { FeedLayout } from 'layouts'
import { StoryFeed } from 'models/story'

const StoriesPage = () => {
const auth = useAuth();
return (
<Authorize>
<FeedLayout maxWidth="lg">
<Box sx={{ display: "flex", justifyContent: "space-between", p: t => t.spacing(2, 1, 4, 1) }}>
<Typography variant="h4">Your Stories</Typography>
<Button component={Link} href="/new">Write a story</Button>
</Box>
<StoryFeed />
<StoryFeed profileId={auth.uid} />
</FeedLayout>
</Authorize>
)
Expand Down

0 comments on commit 34ebe7d

Please sign in to comment.