Skip to content

Commit

Permalink
Revamp fontawesome to use kit and improve capabilities. Update tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
JessicaMulein committed Sep 8, 2024
1 parent 1d9b673 commit 1d09bf4
Show file tree
Hide file tree
Showing 21 changed files with 329 additions and 218 deletions.
4 changes: 1 addition & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ COPY ./apps/duality-social-react ./apps/duality-social-react
COPY ./apps/duality-social-node ./apps/duality-social-node

# Build the application
RUN yarn fontawesome:setup
RUN yarn all
RUN yarn all:build
RUN yarn build:all:dev

# Expose the desired port (e.g., 3000, 4200, or 8080)
EXPOSE 3000
Expand Down
13 changes: 8 additions & 5 deletions apps/duality-social-node/src/middlewares.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,15 @@ export class Middlewares {
// Helmet helps you secure your Express apps by setting various HTTP headers
app.use(helmet({
contentSecurityPolicy: {
directives: {
...helmet.contentSecurityPolicy.getDefaultDirectives(),
"img-src": ["'self'", "data:", "blob:"]
}
directives: {
...helmet.contentSecurityPolicy.getDefaultDirectives(),
"img-src": ["'self'", "data:", "blob:"],
"script-src": ["'self'", "https://kit.fontawesome.com"],
"connect-src": ["'self'", "https://ka-p.fontawesome.com"],
"style-src": ["'self'", "https://ka-p.fontawesome.com", "'unsafe-inline'"]
}
}
}));
}));
// Enable CORS
app.use(cors(Middlewares.corsOptionsDelegate));
// Parse incoming requests with JSON payloads
Expand Down
13 changes: 11 additions & 2 deletions apps/duality-social-react/src/app/app.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React from 'react';
import { Route, Routes } from 'react-router-dom';
import { ThemeProvider } from '@mui/material/styles';
import { Box } from '@mui/material';
import DashboardPage from '../components/dashboard-page';
import { MenuProvider } from '../menu-context';
import TopMenu from '../components/top-menu';
Expand All @@ -10,10 +12,9 @@ import PrivateRoute from '../components/private-route';
import VerifyEmailPage from '../components/verify-email-page';
import ChangePasswordPage from '../components/change-password-page';
import ForgotPasswordPage from '../components/forgot-password-page';
import { ThemeProvider } from '@mui/material/styles';
import { Box } from '@mui/material';
import theme from '../theme';
import UserProfilePage from '../components/user-profile-page';
import FormatGuide from '../components/format-guide';

function App() {
return (
Expand Down Expand Up @@ -56,6 +57,14 @@ function App() {
</PrivateRoute>
}
/>
<Route
path="/help/post-format"
element={
<PrivateRoute>
<FormatGuide />
</PrivateRoute>
}
/>
</Routes>
</Box>
</MenuProvider>
Expand Down
165 changes: 165 additions & 0 deletions apps/duality-social-react/src/components/format-guide.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import React from 'react';
import {
Typography,
Paper,
List,
ListItem,
ListItemText,
Divider,
ListItemIcon,
} from '@mui/material';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faHeart } from '@awesome.me/kit-89ec609b07/icons/classic/solid';
import { faHeart as faHeartRegular } from '@awesome.me/kit-89ec609b07/icons/classic/regular';

const FormatGuide: React.FC = () => {
return (
<Paper elevation={3} sx={{ padding: 2, maxWidth: 600, margin: 'auto' }}>
<Typography variant="h4" gutterBottom>
Post Formatting Guide
</Typography>
<Typography variant="body1" component="div" sx={{ marginBottom: 2 }}>
<p>
You can use Markdown syntax and a special custom FontAwesome powered
icon markup in your posts.
</p>
<p>
A complete list of icons available (we're using a complete Pro set)
can be found here{' '}
<a
href="https://fontawesome.com/icons"
target="_blank"
rel="noopener noreferrer"
>
https://fontawesome.com/icons
</a>
</p>
<p>Here's a quick guide:</p>
</Typography>
<Divider />
<Typography variant="h6" mt={2}>
Markdown Syntax:
</Typography>
<List>
<ListItem>
<ListItemText
primary="Bold"
secondary="**bold text** or __bold text__"
/>
</ListItem>
<ListItem>
<ListItemText
primary="Italic"
secondary="*italic text* or _italic text_"
/>
</ListItem>
<ListItem>
<ListItemText
primary="Links"
secondary="[link text](https://example.com)"
/>
</ListItem>
<ListItem>
<ListItemText
primary="Lists"
secondary="- Item 1\n- Item 2\n- Item 3"
/>
</ListItem>
</List>
<Divider />
<Typography variant="h6" mt={2}>
Icon Markup:
</Typography>
<List>
<ListItem>
<ListItemIcon>
<FontAwesomeIcon icon={faHeartRegular} />
</ListItemIcon>
<ListItemText
primary="Basic Icon"
secondary="{{heart}} renders as a regular heart icon"
/>
</ListItem>
<ListItem>
<ListItemIcon>
<FontAwesomeIcon icon={faHeart} />
</ListItemIcon>
<ListItemText
primary="Styled Icon"
secondary="{{solid heart}} renders as a solid heart icon"
/>
</ListItem>
<ListItem>
<ListItemText
primary="Available Styles"
secondary="classic, duotone, light, regular, solid, sharpsolid, thin, brands"
/>
</ListItem>
<ListItem>
<ListItemText
primary="Sizes"
secondary="xs, sm, lg, xl, 2xl, 1x, 2x, 3x, 4x, 5x, 6x, 7x, 8x, 9x, 10x"
/>
</ListItem>
<ListItem>
<ListItemIcon>
<FontAwesomeIcon icon={faHeart} size="lg" />
</ListItemIcon>
<ListItemText
primary="Size Example"
secondary="{{solid heart lg}} renders a large solid heart icon"
/>
</ListItem>
<ListItem>
<ListItemText
primary="Animations"
secondary="spin, spin-pulse, spin-reverse, pulse, beat, fade, beat-fade, flip, flip-both, flip-horizontal, flip-vertical, rotate-90, rotate-180, rotate-270, rotate-by"
/>
</ListItem>
<ListItem>
<ListItemIcon>
<FontAwesomeIcon icon={faHeart} spin />
</ListItemIcon>
<ListItemText
primary="Animation Example"
secondary="{{solid heart spin}} renders a spinning solid heart icon"
/>
</ListItem>
<ListItem>
<ListItemIcon>
<FontAwesomeIcon icon={faHeart} size="lg" spin />
</ListItemIcon>
<ListItemText
primary="Combined Usage"
secondary="{{solid lg spin heart}} renders a large, spinning, solid heart icon"
/>
</ListItem>
<ListItem>
<ListItemIcon>
<FontAwesomeIcon icon={faHeart} style={{ color: 'red', fontSize: '20px' }} />
</ListItemIcon>
<ListItemText
primary="Custom Styled Icon"
secondary="{{solid heart; color: red; font-size: 20px;}} renders as a red, 20px solid heart icon"
/>
</ListItem>
</List>
<Typography variant="body2" mt={2}>
Note: HTML tags are stripped for security reasons. Use Markdown and icon
markup for formatting.
</Typography>
<Typography variant="body2" mt={2}>
For more detailed styling options, refer to the{' '}
<a
href="https://docs.fontawesome.com/web/style/style-cheatsheet"
target="_blank"
rel="noopener noreferrer"
>
FontAwesome Style Cheatsheet
</a>. Our markup is a custom shorthand for this.
</Typography>
</Paper>
);
};

export default FormatGuide;
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faUser, faRobot, faDesktop } from '@fortawesome/free-solid-svg-icons';
import { faUser, faRobot, faDesktop } from '@awesome.me/kit-89ec609b07/icons/classic/regular';
import { HumanityTypeEnum } from '@duality-social/duality-social-lib';

interface HumanityTypeIconProps {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useState, useCallback } from 'react';
import { Dialog, DialogActions, DialogContent, Button } from '@mui/material';
import Cropper from 'react-easy-crop';
import { Point, Area } from 'react-easy-crop/types';
import { Point, Area } from 'react-easy-crop';

interface ImageCropDialogProps {
open: boolean;
Expand Down
2 changes: 1 addition & 1 deletion apps/duality-social-react/src/components/image-preview.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { Box, IconButton } from '@mui/material';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faTrash, faPencilAlt } from '@fortawesome/free-solid-svg-icons';
import { faTrash, faPencilAlt } from '@awesome.me/kit-89ec609b07/icons/classic/regular';

interface ImagePreviewProps {
image: File;
Expand Down
32 changes: 32 additions & 0 deletions apps/duality-social-react/src/components/live-post-preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React, { useState, useEffect } from 'react';
import { Box, Typography } from '@mui/material';
import { parsePostContent } from '@duality-social/duality-social-lib';

interface LivePostPreviewProps {
content: string;
}

const LivePostPreview: React.FC<LivePostPreviewProps> = ({ content }) => {
const [parsedContent, setParsedContent] = useState('');

useEffect(() => {
setParsedContent(parsePostContent(content));
}, [content]);

return (
<Box mt={2}>
<Typography variant="h6" color="primary" gutterBottom>Preview:</Typography>
<Box
sx={{
border: '1px solid #ccc',
borderRadius: '4px',
padding: '8px',
minHeight: '100px',
}}
dangerouslySetInnerHTML={{ __html: parsedContent }}
/>
</Box>
);
};

export default LivePostPreview;
9 changes: 8 additions & 1 deletion apps/duality-social-react/src/components/new-post.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import React, { useState } from 'react';
import { Button, TextField, Box } from '@mui/material';
import { Link } from 'react-router-dom';
import { Button, TextField, Box, Typography } from '@mui/material';
import { useFormik } from 'formik';
import * as Yup from 'yup';
import ImagePreview from './image-preview';
import LivePostPreview from './live-post-preview';
import ImageCropDialog from './image-crop-dialog';
import authenticatedApi from '../services/authenticated-api';
import { AppConstants } from '@duality-social/duality-social-lib';
Expand Down Expand Up @@ -127,6 +129,10 @@ const NewPost: React.FC<NewPostProps> = ({
(parentPostId ? 'Write a reply' : "What's on your mind?")
}
/>
<Typography variant="body2" sx={{ mt: 1, mb: 2 }}>
Need help with formatting? Check out our{' '}
<Link to="/help/post-format" target="_blank" rel="noopener noreferrer">post formatting guide</Link>.
</Typography>
{images.map((img, index) => (
<ImagePreview
key={index}
Expand Down Expand Up @@ -168,6 +174,7 @@ const NewPost: React.FC<NewPostProps> = ({
onClose={() => setCropDialogOpen(false)}
onSave={handleCropSave}
/>
<LivePostPreview content={formik.values.content} />
</Box>
);
};
Expand Down
2 changes: 1 addition & 1 deletion apps/duality-social-react/src/components/top-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
Box,
} from '@mui/material';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faUser, faComment } from '@fortawesome/free-solid-svg-icons';
import { faUser, faComment } from '@awesome.me/kit-89ec609b07/icons/classic/regular';
import { AuthContext } from '../auth-provider';
import { CommentMenuOption, useMenu } from '../menu-context';
import dualitySocialSymbol from '../assets/DSImageOnlySmall.png';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// file: user-profile.tsx
import React, { useState, useEffect } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faCheckCircle } from '@fortawesome/free-solid-svg-icons';
import { faCheckCircle } from '@awesome.me/kit-89ec609b07/icons/classic/regular';
import {
Box,
Chip,
Expand Down
1 change: 1 addition & 0 deletions apps/duality-social-react/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<script src="https://kit.fontawesome.com/89ec609b07.js" crossorigin="anonymous"></script>
</head>
<body>
<div id="root"></div>
Expand Down
7 changes: 7 additions & 0 deletions apps/duality-social-react/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
import { StrictMode } from 'react';
import * as ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import { config, library } from '@fortawesome/fontawesome-svg-core';
import { all } from '@awesome.me/kit-89ec609b07/icons';
import '@fortawesome/fontawesome-svg-core/styles.css';

import App from './app/app';
import { AuthProvider } from './auth-provider';

// fontawesome
library.add(...all);
config.autoAddCss = false;

const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
Expand Down
3 changes: 2 additions & 1 deletion apps/duality-social-react/src/utils/reactions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { DefaultReactionsTypeEnum } from '@duality-social/duality-social-lib';
import { faFaceAngry, faFaceKissWinkHeart, faPartyHorn, faFaceSmilingHands, faFaceConfused, faFaceLaugh, faThumbsUp, faHeart, faFaceSadTear, faFaceHushed, faFaceDizzy, IconDefinition } from '@fortawesome/pro-solid-svg-icons';
import { faFaceAngry, faFaceKissWinkHeart, faPartyHorn, faFaceSmilingHands, faFaceConfused, faFaceLaugh, faThumbsUp, faHeart, faFaceSadTear, faFaceHushed, faFaceDizzy } from '@awesome.me/kit-89ec609b07/icons/classic/regular';
import { IconDefinition } from '@awesome.me/kit-89ec609b07/icons';

export const reactionEmojis: { [type in DefaultReactionsTypeEnum]: string } = {
[DefaultReactionsTypeEnum.Angry]: '😡',
Expand Down
3 changes: 2 additions & 1 deletion fontawesome-npmrc.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/bin/bash

echo "@fortawesome:registry=https://npm.fontawesome.com/
//npm.fontawesome.com/:_authToken=$FONTAWESOME_KEY" > .npmrc
@awesome.me:registry=https://npm.fontawesome.com/
//npm.fontawesome.com/:_authToken=$FONTAWESOME_KEY" > .npmrc
2 changes: 1 addition & 1 deletion libs/duality-social-lib/src/lib/duality-social-lib.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { parsePostContent } from './duality-social-lib';
describe('DualitySocialLib', () => {
it('should do markdown and our cool icons', () => {
const testMarkdown = '# Hello World\nThis is a test of our markdown parser.\n' +
'This should be a red heart with a zig-zag through it -> {{duotone heart-pulse color: red;}}';
'This should be a red heart with a zig-zag through it -> {{duotone heart-pulse; color: red;}}';
const expectedHtml = '<h1>Hello World</h1>\n<p>This is a test of our markdown parser.<br />\n' +
'This should be a red heart with a zig-zag through it -&gt; <i class="fa-duotone fa-heart-pulse" style="display: inline-block; color: red;"></i></p>\n';

Expand Down
Loading

0 comments on commit 1d09bf4

Please sign in to comment.