Skip to content

Commit

Permalink
🎉 add spotify listening to field (#8)
Browse files Browse the repository at this point in the history
fix spotify dual rendering

update readme
  • Loading branch information
kairavkkp authored and rishavanand committed Aug 12, 2020
1 parent 881f084 commit 4c875ba
Show file tree
Hide file tree
Showing 9 changed files with 1,869 additions and 1,232 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ This projects is aimed to simplify your GitHub profile generation process by pro
- [x] Init with demo template
- [x] Multi column support
- [x] Customizable blocks and layouts
- [x] Listening to from Spotify
- [ ] Multi template
- [ ] Last tweet from Twitter
- [ ] Listening to from Spotify
- [ ] Last 3 uploads from Instagram

## 🚀 Getting started
Expand Down Expand Up @@ -88,6 +88,7 @@ npm start
- [amazing github-readme-stats](https://github.com/anuraghazra/github-readme-stats) by Anurag Hazra for creating detailed statistics
- [github-profile-views-counter](https://github.com/antonkomarev/github-profile-views-counter) by Anton Komarev for simplifying visitor counter
- [blog post workflow](https://github.com/gautamkrishnar/blog-post-workflow) by Gautam Krishna R which is a Genius use of Github Actions.
- [spotify-github-profile](https://github.com/kittinan/spotify-github-profile) by Kittinan which generated Spotify's currently listening album cover image.

## :heart: Supporting the project

Expand Down
2,887 changes: 1,667 additions & 1,220 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 5 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@
"dependencies": {
"@fortawesome/fontawesome-free": "^5.14.0",
"@fortawesome/fontawesome-svg-core": "^1.2.30",
"@fortawesome/free-brands-svg-icons": "^5.14.0",
"@fortawesome/free-solid-svg-icons": "^5.14.0",
"@fortawesome/react-fontawesome": "^0.1.11",
"@types/marked": "^1.1.0",
"@types/react-helmet": "^6.0.0",
"dot-prop": "^5.2.0",
"antd": "^4.5.1",
"emoji-mart": "^3.0.0",
"gatsby": "^2.24.15",
"gatsby-image": "^2.4.14",
Expand All @@ -29,19 +28,19 @@
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-helmet": "^6.1.0",
"react-render-html": "^0.6.0",
"react-scroll": "^1.8.0",
"styled-components": "^5.1.1",
"ts-node": "^8.10.2",
"use-dark-mode": "^2.3.1",
"uuid": "^8.3.0"
},
"devDependencies": {
"ts-node": "^8.10.2",
"@types/emoji-mart": "^3.0.2",
"@types/react-scroll": "^1.5.5",
"@typescript-eslint/eslint-plugin": "^3.7.1",
"@typescript-eslint/parser": "^3.7.1",
"antd": "^4.5.1",
"@types/marked": "^1.1.0",
"@types/react-helmet": "^6.0.0",
"eslint": "^7.5.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-prettier": "^3.1.4",
Expand Down
165 changes: 165 additions & 0 deletions src/components/Field/SpotifyListeningTo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import React, { useContext } from 'react';
import { Input, Row, Col, Button, Dropdown, Menu, Form, Switch } from 'antd';
import { DownOutlined } from '@ant-design/icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import styles from '../../styles/fields.module.scss';
import { faAlignLeft, faExpandArrowsAlt } from '@fortawesome/free-solid-svg-icons';
import { faSpotify } from '@fortawesome/free-brands-svg-icons';
import { FieldProps } from '.';
import { globalContext } from '../../context/GlobalContextProvider';

export enum ALIGNMENT {
LEFT = 'left',
CENTRE = 'center',
RIGHT = 'right',
}

export interface SpotifyListeningToOptions {
alignment?: ALIGNMENT;
fitImage?: boolean;
}

export interface SpotifyListeningToData {
spotifyMarkdown?: string;
}

export interface SpotifyListeningToProps extends FieldProps {
id?: string;
data?: SpotifyListeningToData;
options?: SpotifyListeningToOptions;
}

export const generateAlignmentTags = (alignment: ALIGNMENT, type: 'start' | 'end') => {
if ((alignment === ALIGNMENT.CENTRE || alignment === ALIGNMENT.RIGHT) && type === 'start')
return `<div align="${alignment}">`;
else if ((alignment === ALIGNMENT.CENTRE || alignment === ALIGNMENT.RIGHT) && type === 'end') return `</div>`;
else return '';
};

export const generateSpotifyListeningToMarkdown = ({ data, options }: SpotifyListeningToProps) => {
const markdown = data.spotifyMarkdown
? data.spotifyMarkdown
: '[spotify-github-profile](https://rishavanand.github.io/static/images/spotify-readme-example.svg)';
const svgLink = markdown.substring(markdown.indexOf('(') + 1, markdown.indexOf(')'));

if (options.fitImage)
return `<img src="${svgLink}" align="${options.alignment ? options.alignment : 'left'}" style="width: 100%" />`;
else if (options.alignment && (options.alignment === ALIGNMENT.CENTRE || options.alignment === ALIGNMENT.RIGHT))
return `<div align="${options.alignment}"><img src="${svgLink}" /></div>`;
else return `![Listening to on Spotify](${svgLink})`;
};

export const SpotifyListeningToField = (
imageFieldProps: SpotifyListeningToProps &
Required<
Pick<SpotifyListeningToProps, 'id' | 'sectionId' | 'sectionIndex' | 'columnIndex' | 'fieldIndex' | 'type'>
>,
) => {
const { modifyField } = useContext(globalContext);

const localSpotifyListeningProps: typeof imageFieldProps = {
options: {},
data: {},
...imageFieldProps,
};

const onChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const name = event.target.name;
const value = event.target.value;
if (name === 'md-code')
modifyField({
...localSpotifyListeningProps,
data: {
...localSpotifyListeningProps.data,
spotifyMarkdown: value,
},
});
};

const toggleFitImage = () => {
modifyField({
...localSpotifyListeningProps,
options: {
...localSpotifyListeningProps.options,
fitImage: localSpotifyListeningProps.options.fitImage ? false : true,
},
});
};

const changeAlignment = (alignment: typeof localSpotifyListeningProps.options.alignment) => {
const localProps = { ...localSpotifyListeningProps };
if (!localProps.options) localProps.options = {};
localProps.options.alignment = alignment;
modifyField(localProps);
};

const alignmentMenu = (
<Menu>
<Menu.Item key="1" onClick={() => changeAlignment(ALIGNMENT.LEFT)}>
Left
</Menu.Item>
<Menu.Item key="2" onClick={() => changeAlignment(ALIGNMENT.CENTRE)}>
Centre
</Menu.Item>
<Menu.Item key="3" onClick={() => changeAlignment(ALIGNMENT.RIGHT)}>
Right
</Menu.Item>
</Menu>
);

return (
<>
<Row justify="space-between" style={{ marginBottom: 10 }}>
<Col>
<Dropdown overlay={alignmentMenu}>
<Button
style={{ paddingLeft: 5, paddingRight: 5, width: 50 }}
icon={
<>
<FontAwesomeIcon icon={faAlignLeft} /> <DownOutlined />
</>
}
/>
</Dropdown>
<Button
icon={
<>
<FontAwesomeIcon icon={faExpandArrowsAlt} />
</>
}
onClick={() => toggleFitImage()}
className={[
styles.optionButton,
localSpotifyListeningProps.options && localSpotifyListeningProps.options.fitImage
? styles.selected
: styles.unselected,
].join(' ')}
/>
</Col>
<Col>
<a href="https://spotify-github-profile.vercel.app/api/login" rel="noreferrer" target="_blank">
<Button
icon={<FontAwesomeIcon icon={faSpotify} />}
style={{ color: 'white', backgroundColor: '#1DB954' }}
>
&nbsp; Connect with Spotify
</Button>
</a>
</Col>
</Row>
<Row></Row>
<Form layout="vertical">
<Form.Item label="First use the button to connect with Spotify, then paste the generated code in the field below">
<Input
name="md-code"
value={localSpotifyListeningProps.data.spotifyMarkdown}
onChange={onChange}
placeholder="Paste the generated code here"
/>
</Form.Item>
</Form>
</>
);
};

export default SpotifyListeningToField;
3 changes: 3 additions & 0 deletions src/components/Field/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { faPen, faCheck, faTimes, faCaretUp, faCaretDown } from '@fortawesome/fr
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { ProfileVisitorCounterField } from '../Field/ProfileVisitorCounterField';
import BlogPostField from './BlogPostField';
import SpotifyListeningToField from './SpotifyListeningTo';

export interface FieldProps {
id?: string;
Expand Down Expand Up @@ -58,6 +59,8 @@ export const Field = (
return <ProfileVisitorCounterField {...props} />;
case FIELD_TYPES.BLOG_POST:
return <BlogPostField />;
case FIELD_TYPES.SPOTIFY:
return <SpotifyListeningToField {...props} />;
}
};

Expand Down
12 changes: 7 additions & 5 deletions src/components/Preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { globalContext } from '../context/GlobalContextProvider';
import { FIELD_TYPES } from '../config/global';
import { generateTextFieldMarkdown } from './Field/TextField';
import marked from 'marked';
import renderHTML from 'react-render-html';
import styles from '../styles/preview.module.scss';
import { generateImageFieldMarkdown } from './Field/ImageField';
import { FieldProps, generateFieldTitleMarkdown } from './Field';
Expand All @@ -22,6 +21,7 @@ import { generateProfileVisitorCounterMarkdown } from './Field/ProfileVisitorCou
import { generateBlogPostMarkdown } from './Field/BlogPostField';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faStar } from '@fortawesome/free-solid-svg-icons';
import { generateSpotifyListeningToMarkdown } from './Field/SpotifyListeningTo';

const { Title } = Typography;
const { TextArea } = Input;
Expand Down Expand Up @@ -58,6 +58,9 @@ export const Preview = () => {
case FIELD_TYPES.BLOG_POST:
returnField += generateBlogPostMarkdown();
break;
case FIELD_TYPES.SPOTIFY:
returnField += generateSpotifyListeningToMarkdown(field);
break;
}
return returnField;
})
Expand Down Expand Up @@ -93,9 +96,8 @@ export const Preview = () => {

const generateMarkdown = () => {
const markdown = generateSectionMarkdown(context.sections);
const markdownText = marked(markdown);
const html = renderHTML(markdownText);
return { html, markdown, markdownText };
const html = marked(markdown);
return { html, markdown };
};

const toggleShowMarkdown = () => {
Expand All @@ -122,7 +124,7 @@ export const Preview = () => {
</Col>
</Row>
<Divider />
<div className={styles.markdown}>{generateMarkdown().html}</div>
<div className={styles.markdown} dangerouslySetInnerHTML={{ __html: generateMarkdown().html }} />
<Modal
title="Generated Markdown"
width="70vw"
Expand Down
1 change: 1 addition & 0 deletions src/components/Section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ const Section = (section: SectionProps & Required<Pick<SectionProps, 'sectionInd
<Option value={FIELD_TYPES.SOCIAL}> Social</Option>
<Option value={FIELD_TYPES.PROFILE_VISITOR_COUNTER}> Visitor Counter</Option>
<Option value={FIELD_TYPES.BLOG_POST}> Dynamic blog post list</Option>
<Option value={FIELD_TYPES.SPOTIFY}> Spotify Listening</Option>
</Select>
</Form.Item>
</Form>
Expand Down
18 changes: 18 additions & 0 deletions src/config/demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,24 @@ export const DEMO_SECTION_DATA: Array<SectionProps & Required<Pick<SectionProps,
sectionIndex: 4,
nameToMarkdown: true,
},
{
name: 'Spotify Listening',
id: 'ea07ce6b-cc2b-47f5-b345-931e561b83v6',
sectionIndex: 6,
fields: [
[
{
id: 'field001',
options: { size: 'h3', alignment: 'center' },
data: {
spotifyMarkdown: '',
},
type: FIELD_TYPES.SPOTIFY,
sectionId: 'ea07ce6b-cc2b-47f5-b345-931e561b83v6',
},
],
],
},
{
name: 'Visitor Counter',
id: 'ea07ce6b-cc2b-47f5-b345-931e561b57c8',
Expand Down
1 change: 1 addition & 0 deletions src/config/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export enum FIELD_TYPES {
SOCIAL = 'social',
PROFILE_VISITOR_COUNTER = 'profile-visitor-counter',
BLOG_POST = 'blog-post',
SPOTIFY = 'spotify',
}

0 comments on commit 4c875ba

Please sign in to comment.