This commit is contained in:
Kurt Hutten
2021-09-18 16:47:17 +10:00
parent d94645d381
commit f3201cfd97
7 changed files with 183 additions and 164 deletions

View File

@@ -76,8 +76,8 @@ function Gooey() {
const z = randomSign(Math.random() * 2)
const position: [number, number, number] = [x, z, y]
const size = Math.random() * 0.8 + 0.1
const distort = (size > .1) ? Math.random() * .6 * size + 0.2 : 0
const speed = (size > .1) ? (Math.random() * 0.8) / size / size + 0.1 : 0
const distort = size > 0.1 ? Math.random() * 0.6 * size + 0.2 : 0
const speed = size > 0.1 ? (Math.random() * 0.8) / size / size + 0.1 : 0
return { position, size, distort, speed }
})
const secondSet = Array.from({ length: 5 }).map((_, index) => {
@@ -87,8 +87,8 @@ function Gooey() {
const z = randomSign(Math.random() * 2)
const position: [number, number, number] = [x, z, y]
const size = Math.random() * 0.2 + 0.05
const distort = (size > .1) ? Math.random() * .8 * size + 0.2 : 0
const speed = (size > .1) ? (Math.random() * 0.5) / size / size + 0.1 : 0
const distort = size > 0.1 ? Math.random() * 0.8 * size + 0.2 : 0
const speed = size > 0.1 ? (Math.random() * 0.5) / size / size + 0.1 : 0
return { position, size, distort, speed }
})
return [...firstSet, ...secondSet]

View File

@@ -53,13 +53,14 @@ export const sidebarTopConfig: SidebarConfigType[] = [
]
const DiscordLink = () => (
<a className="underline text-ch-pink-300"
href="https://discord.gg/SD7zFRNjGH"
target="_blank"
rel="noreferrer"
>
Discord
</a>
<a
className="underline text-ch-pink-300"
href="https://discord.gg/SD7zFRNjGH"
target="_blank"
rel="noreferrer"
>
Discord
</a>
)
const settingsConfig = [
@@ -74,7 +75,8 @@ const settingsConfig = [
</p>
<hr className="my-2" />
<p className="p-2">
We're building configuration settings for the Viewer pane now. Join us on <DiscordLink/> if you want to lend a hand!
We're building configuration settings for the Viewer pane now. Join us
on <DiscordLink /> if you want to lend a hand!
</p>
</div>
),
@@ -90,7 +92,8 @@ const settingsConfig = [
</p>
<hr className="my-2" />
<p className="p-2">
We're building configuration settings for the Viewer pane now. Join us on <DiscordLink/> if you want to lend a hand!
We're building configuration settings for the Viewer pane now. Join us
on <DiscordLink /> if you want to lend a hand!
</p>
</div>
),
@@ -106,7 +109,8 @@ const settingsConfig = [
</p>
<hr className="my-2" />
<p className="p-2">
We're building configuration settings for the Viewer pane now. Join us on <DiscordLink/> if you want to lend a hand!
We're building configuration settings for the Viewer pane now. Join us
on <DiscordLink /> if you want to lend a hand!
</p>
</div>
),

View File

@@ -7,24 +7,25 @@ interface EditToggleType {
}
const EditToggle = ({
onEdit = () => { console.error('Field declared editable without edit action.') },
onEdit = () => {
console.error('Field declared editable without edit action.')
},
isEditing = false,
} : EditToggleType) => (
(isEditing ? (
<button
className="font-fira-sans text-ch-gray-300 items-center ml-4 grid grid-flow-col-dense p-px px-2 gap-2 bg-ch-blue-500 bg-opacity-50 hover:bg-opacity-70 rounded-sm"
id="rename-button"
onClick={onEdit}
>
<Svg name="check" className="w-6 h-6" strokeWidth={3} />
<span>Update</span>
</button>
) : (
<button onClick={onEdit}>
<Svg name="pencil-solid" className="h-4 w-4 ml-4 mb-2" />
</button>
))
)
}: EditToggleType) =>
isEditing ? (
<button
className="font-fira-sans text-ch-gray-300 items-center ml-4 grid grid-flow-col-dense p-px px-2 gap-2 bg-ch-blue-500 bg-opacity-50 hover:bg-opacity-70 rounded-sm"
id="rename-button"
onClick={onEdit}
>
<Svg name="check" className="w-6 h-6" strokeWidth={3} />
<span>Update</span>
</button>
) : (
<button onClick={onEdit}>
<Svg name="pencil-solid" className="h-4 w-4 ml-4 mb-2" />
</button>
)
interface KeyValueType {
keyName: string
@@ -51,7 +52,7 @@ const KeyValue = ({
}
>
<span className={edit ? 'text-ch-blue-300' : ''}>{keyName}</span>
{edit && edit.hasPermissionToEdit && <EditToggle {...edit} /> }
{edit && edit.hasPermissionToEdit && <EditToggle {...edit} />}
</div>
<div className={'text-ch-gray-300 ' + (bottom ? 'mb-1' : 'mt-1')}>
{children}

View File

@@ -32,10 +32,7 @@ const ProjectCard = ({ title, mainImage, user, Reaction, cadPackage }) => (
</div>
<div className="flex items-center mt-1">
<div className="w-8 h-8 overflow-hidden rounded-full border border-ch-gray-300 shadow">
<ImageFallback
imageId={user?.image}
width={80}
/>
<ImageFallback imageId={user?.image} width={80} />
</div>
<div className="ml-3 text-lg text-ch-gray-300 font-fira-sans">
<div className="">{title}</div>

View File

@@ -102,41 +102,43 @@ const ProjectProfile = ({
className="px-3 py-2 rounded"
/>
</div>
{ (project?.description || hasPermissionToEdit) && <KeyValue
keyName="Description"
edit={{
hasPermissionToEdit,
isEditing,
onEdit: () => {
if (!isEditing) {
setIsEditing(true)
} else {
onEditSaveClick()
setIsEditing(false)
}
},
}}
>
<div
id="description-wrap"
name="description"
className={
'markdown-overrides rounded-sm pb-2 mt-2' +
(isEditing ? ' min-h-md' : '')
}
onClick={(e) =>
e?.target?.id === 'description-wrap' &&
editorRef?.current?.focusAtEnd()
}
{(project?.description || hasPermissionToEdit) && (
<KeyValue
keyName="Description"
edit={{
hasPermissionToEdit,
isEditing,
onEdit: () => {
if (!isEditing) {
setIsEditing(true)
} else {
onEditSaveClick()
setIsEditing(false)
}
},
}}
>
<Editor
ref={editorRef}
defaultValue={project?.description || ''}
readOnly={!isEditing}
onChange={onDescriptionChange}
/>
</div>
</KeyValue> }
<div
id="description-wrap"
name="description"
className={
'markdown-overrides rounded-sm pb-2 mt-2' +
(isEditing ? ' min-h-md' : '')
}
onClick={(e) =>
e?.target?.id === 'description-wrap' &&
editorRef?.current?.focusAtEnd()
}
>
<Editor
ref={editorRef}
defaultValue={project?.description || ''}
readOnly={!isEditing}
onChange={onDescriptionChange}
/>
</div>
</KeyValue>
)}
<div className="grid grid-flow-col-dense gap-6">
<KeyValue keyName="Created on">
{new Date(project?.createdAt).toDateString()}
@@ -154,64 +156,68 @@ const ProjectProfile = ({
className=""
/>
</KeyValue>
{ currentUser && <KeyValue keyName="Comments">
{!isEditing && (
<>
{currentUser && (
<>
<div className="pt-1">
<textarea
className="w-full h-32 rounded shadow-inner outline-none resize-none p-3 bg-ch-gray-600 placeholder-ch-gray-500 font-fira-sans"
placeholder="Have a question about this model, or a helpful tip about how to improve it? Remember, be nice!"
value={comment}
onChange={({ target }) =>
setComment(target.value)
}
/>
</div>
<Button
className={getActiveClasses(
'ml-auto hover:bg-opacity-100 bg-ch-pink-800 bg-opacity-30 mt-4 mb-6 text-ch-gray-300',
{ 'bg-indigo-200': currentUser }
)}
shouldAnimateHover
disabled={!currentUser}
iconName={''}
onClick={onCommentClear}
>
Comment
</Button>
</>
)}
<ul>
{project?.Comment.map(
({ text, user, id, createdAt }) => (
<li key={id} className="mb-5">
<div className="flex justify-between">
<Link
className="flex items-center"
to={routes.user({ userName: user?.userName })}
>
<Gravatar
image={user?.image}
className="w-10 h-10 mr-4"
/>
{user?.userName}
</Link>
<div className="font-fira-code text-ch-blue-400 flex items-center">
{new Date(createdAt).toDateString()}
</div>
</div>
<div className="ml-5 border-l-2 pl-5 my-3 border-ch-gray-300 text-ch-gray-300">
{text}
</div>
</li>
)
{currentUser && (
<KeyValue keyName="Comments">
{!isEditing && (
<>
{currentUser && (
<>
<div className="pt-1">
<textarea
className="w-full h-32 rounded shadow-inner outline-none resize-none p-3 bg-ch-gray-600 placeholder-ch-gray-500 font-fira-sans"
placeholder="Have a question about this model, or a helpful tip about how to improve it? Remember, be nice!"
value={comment}
onChange={({ target }) =>
setComment(target.value)
}
/>
</div>
<Button
className={getActiveClasses(
'ml-auto hover:bg-opacity-100 bg-ch-pink-800 bg-opacity-30 mt-4 mb-6 text-ch-gray-300',
{ 'bg-indigo-200': currentUser }
)}
shouldAnimateHover
disabled={!currentUser}
iconName={''}
onClick={onCommentClear}
>
Comment
</Button>
</>
)}
</ul>
</>
)}
</KeyValue> }
<ul>
{project?.Comment.map(
({ text, user, id, createdAt }) => (
<li key={id} className="mb-5">
<div className="flex justify-between">
<Link
className="flex items-center"
to={routes.user({
userName: user?.userName,
})}
>
<Gravatar
image={user?.image}
className="w-10 h-10 mr-4"
/>
{user?.userName}
</Link>
<div className="font-fira-code text-ch-blue-400 flex items-center">
{new Date(createdAt).toDateString()}
</div>
</div>
<div className="ml-5 border-l-2 pl-5 my-3 border-ch-gray-300 text-ch-gray-300">
{text}
</div>
</li>
)
)}
</ul>
</>
)}
</KeyValue>
)}
{hasPermissionToEdit && (
<>
<h4 className="mt-10 text-red-600">Danger Zone</h4>

View File

@@ -13,15 +13,18 @@ import {
// This function initializes the state management object for each of the fields
function buildFieldsConfig(fieldsConfig, user, hasPermissionToEdit) {
return Object.fromEntries(Object.keys(fieldsConfig).map(
(key: string): [string, FieldType] => ([key, {
name: key,
currentValue: user[key],
newValue: user[key],
isEditing: false,
hasPermissionToEdit,
}])
))
return Object.fromEntries(
Object.keys(fieldsConfig).map((key: string): [string, FieldType] => [
key,
{
name: key,
currentValue: user[key],
newValue: user[key],
isEditing: false,
hasPermissionToEdit,
},
])
)
}
const UserProfile = ({
@@ -39,7 +42,11 @@ const UserProfile = ({
navigate(routes.user({ userName: user.userName }))
}, [currentUser])
const initializedFields = buildFieldsConfig(fieldComponents, user, hasPermissionToEdit)
const initializedFields = buildFieldsConfig(
fieldComponents,
user,
hasPermissionToEdit
)
const [fields, fieldDispatch] = useReducer(fieldReducer, initializedFields)
const {
name: NameField,

View File

@@ -51,29 +51,32 @@ const ProfileKeyValue = ({
hasPermissionToEdit,
children,
bottom = false,
} : ProfileKeyValueType) => {
}: ProfileKeyValueType) => {
return (
(user[field.name] && hasPermissionToEdit) && <KeyValue
keyName={field.name}
edit={{
hasPermissionToEdit,
isEditing: field.isEditing,
onEdit: () => {
if (field.isEditing && field.currentValue !== field.newValue) {
save(user.userName, { [field.name]: field.newValue })
}
dispatch({
type: 'SET_CURRENT_VALUE',
payload: { field: field.name, value: field.newValue },
})
dispatch({ type: 'TOGGLE_EDITING', payload: field.name })
},
}}
bottom={bottom}
className="mb-4"
>
{children}
</KeyValue>
user[field.name] &&
hasPermissionToEdit && (
<KeyValue
keyName={field.name}
edit={{
hasPermissionToEdit,
isEditing: field.isEditing,
onEdit: () => {
if (field.isEditing && field.currentValue !== field.newValue) {
save(user.userName, { [field.name]: field.newValue })
}
dispatch({
type: 'SET_CURRENT_VALUE',
payload: { field: field.name, value: field.newValue },
})
dispatch({ type: 'TOGGLE_EDITING', payload: field.name })
},
}}
bottom={bottom}
className="mb-4"
>
{children}
</KeyValue>
)
)
}
@@ -110,7 +113,7 @@ function BioField(props) {
)
}
function MemberSinceField(props : FieldComponentPropsType) {
function MemberSinceField(props: FieldComponentPropsType) {
return (
<KeyValue keyName="Member Since">
<p className="text-ch-gray-300">
@@ -120,7 +123,7 @@ function MemberSinceField(props : FieldComponentPropsType) {
)
}
function ImageField(props : FieldComponentPropsType) {
function ImageField(props: FieldComponentPropsType) {
const { field, user, save, hasPermissionToEdit } = props
return (
<ImageUploader
@@ -138,7 +141,7 @@ function ImageField(props : FieldComponentPropsType) {
)
}
function NameField(props : FieldComponentPropsType) {
function NameField(props: FieldComponentPropsType) {
const { user, dispatch, field } = props
return (
@@ -162,7 +165,7 @@ function NameField(props : FieldComponentPropsType) {
)
}
function UserNameField(props : FieldComponentPropsType) {
function UserNameField(props: FieldComponentPropsType) {
const { dispatch, field } = props
return (
@@ -196,7 +199,8 @@ export function fieldReducer(state, action) {
[action.payload]: {
...state[action.payload],
isEditing:
state[action.payload].hasPermissionToEdit && !state[action.payload].isEditing
state[action.payload].hasPermissionToEdit &&
!state[action.payload].isEditing
? true
: false,
},