moving from hexo theme to my own react design

This commit is contained in:
Kim, Jimin 2021-05-15 00:30:19 +09:00
parent 7ff3176072
commit 379c1c60d9
96 changed files with 1990 additions and 50291 deletions

18
.gitignore vendored
View file

@ -1,7 +1,23 @@
# where I keep my notes
_/ _/
# auto generated
yarn.lock yarn.lock
package-lock.json package-lock.json
hexo/source/_drafts pages.json
# dependencies
.pnp/
.pnp.js
# testing
coverage/
# production
build/
# misc
.DS_Store
# unaltered # unaltered
# Created by https://www.toptal.com/developers/gitignore/api/firebase,node,hexo,git,visualstudiocode # Created by https://www.toptal.com/developers/gitignore/api/firebase,node,hexo,git,visualstudiocode

3
.gitmodules vendored
View file

@ -1,3 +0,0 @@
[submodule "hexo/themes/icarus"]
path = hexo/themes/icarus
url = https://github.com/developomp/hexo-theme-icarus.git

5
.prettierrc Normal file
View file

@ -0,0 +1,5 @@
{
"tabWidth": 4,
"useTabs": true,
"semi": false
}

30
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,30 @@
# Contributing
## Before starting
tl;dr for dummies:
- Suggestions and Bug reports here: [GitHub issues page](https://github.com/developomp/developomp-site/issues)
- contribution is only for developers
- code contributions only. No article contribution.
This document is aimed for developers. Basic level of development knowledge is expected from contributors.
To be specific, contributors are expected to be familiar with the javascript language, react framework, and code analyzers and formatters.
If you are **not** a developer, but have suggestions and/or bug report, feel free to go to [GitHub issues page](https://github.com/developomp/developomp-site/issues).
though the code is written with multi author in mind, I won't take article contributions.
## Guidelines
- Usage of vscode is highly recommended but other IDE works too as long as the code style is consistent.
- All contributions must be made in form of a github pull request. Sending code through email or other platform is not welcomed.
- Format code using Prettier formatter with [this](./.prettierrc) configuration.
- test your code before making pull request.
- Make sure to write basic comments to help other people understand your code at first glance.
- file top comment
```javascript
/** filename.tsx
* what it does and why it exists
*/
```

97
LICENSE_OFL Normal file
View file

@ -0,0 +1,97 @@
Copyright (c) <dates>, <Copyright Holder> (<URL|email>),
with Reserved Font Name <Reserved Font Name>.
Copyright (c) <dates>, <additional Copyright Holder> (<URL|email>),
with Reserved Font Name <additional Reserved Font Name>.
Copyright (c) <dates>, <additional Copyright Holder> (<URL|email>).
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

102
README.md
View file

@ -1,30 +1,90 @@
# <a href="https://developomp.com" target="_blank">developomp-site</a> # developomp-site
Tools used: Repository for my (developomp's) <a href="https://developomp.com" target="_blank">website</a>.
| Name | Use | Tools/Frameworks/Packages used:
| --------------------------------------: | :-------------------------------------- |
| [Hexo](https://hexo.io) | generating static files | | Name | Use |
| [Firebase](https://firebase.google.com) | hosting site (Future: hosting database) | | ----------------------------------------------------------------------------: | :---------------------------------------------------- |
| [Github](https://github.com) | storing source & automatic deployment | | [AWS](https://aws.amazon.com) | Domain register |
| [AWS](https://aws.amazon.com) | Domain name purchase & management | | [Firebase](https://firebase.google.com) | Static site hosting |
| [Typescript](https://github.com/microsoft/TypeScript) | Static typing for javascript |
| [react](https://reactjs.org) | Front end framework |
| [react-fontawesome](https://github.com/FortAwesome/react-fontawesome) | [Fontawesome](https://fontawesome.com) icons in react |
| [react-helmet](https://github.com/nfl/react-helmet) | HTML head management |
| [dompurify](https://github.com/cure53/DOMPurify) | HTML sanitizer for markdown -> HTML page generation |
| [gray-matter](https://github.com/jonschlinkert/gray-matter) | parsing markdown |
| [local-storage-fallback](https://github.com/ripeworks/local-storage-fallback) | storing theme choice |
| [react-tooltip](https://github.com/wwayne/react-tooltip) | Tooltips |
| [styled-components](https://github.com/styled-components/styled-components) | easier CSS styling |
| [styled-theming](https://github.com/styled-components/styled-theming) | Theming |
| [eslint](https://github.com/eslint/eslint) | code analysis |
| [prettier](https://github.com/prettier/prettier) | code formatter |
| [ts-node](https://github.com/TypeStrong/ts-node) | running markdown->html generator |
| [jest](https://jestjs.io) | code testing |
| [react-spinners](https://github.com/davidhu2000/react-spinners) | loading indicator |
# Setup # Setup
Requires: [git](https://git-scm.com), [node](https://nodejs.org), [hexo](https://github.com/hexojs/hexo), [firebase](https://firebase.google.com) Requirement:
- Clone the repo with git modules - [node](https://nodejs.org)
- `git clone --recurse-submodules https://github.com/developomp/developomp-site.git` - [yarn](https://github.com/yarnpkg/yarn) or [npm](https://github.com/npm/cli)\*
- to update: `git submodule foreach git pull origin master` - optional:
- Install dependencies - [git](https://git-scm.com)
- `cd developomp-site/hexo` - [vscode](https://code.visualstudio.com)
- `yarn` or `npm i` - extensions (also optional but recommended):
- Generate files - [styled components](https://marketplace.visualstudio.com/items?itemName=jpoissonnier.vscode-styled-components)
- `hexo generate` - [prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
- (optional, requires firebase setup) deploy it to firebase - [react](https://marketplace.visualstudio.com/items?itemName=dsznajder.es7-react-js-snippets)
- `firebase deploy` - [eslint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint)
\*Usage of yarn is highly recommended over npm
Steps:
- Clone this repository
- `git clone https://github.com/developomp/developomp-site.git`
- Or download compressed as zip
- ![](./downloading.png)
- open [`source`](./source) directory
- `cd source`
- Install dependencies (must be in `source` directory)
- `yarn install`
- start local server in http://localhost:3000
- `yarn start`
# How it works
single page application
react to build front end
components
sunning `yarn generate` converts markdown to html and in json with parsed meta
by date, etc.
Does not scale well but I won't have 10k posts any time soon
few thousand so more than good enough
generator underscore
no symbolic links
filename encoder not perfect. Some filenames might cause problem.
# Contributing
Please read the [`CONTRIBUTING.md`](./CONTRIBUTING.md) file.
# Special thanks
- design inspirations from [Ruipeng Zhang](https://github.com/ppoffice)'s [icarus theme](https://github.com/ppoffice/hexo-theme-icarus) for [hexo](https://github.com/hexojs/hexo).
- dark theme color from [discord](http://discord.com)
# License # License
This project is licensed under the MIT License.\ This project is licensed under the MIT License.<br>
Check the [LICENSE file](./LICENSE) for more information. Check the [LICENSE](./LICENSE) file for more information.
Font license:
[Open Font License (OFL)](./LICENSE_OFL) ([Source](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL#5667e9e4)):
- [Source Code Pro](https://fonts.google.com/specimen/Source+Code+Pro?query=source+code+pro) (monospaced code font)
- [Noto Sans KR](https://fonts.google.com/specimen/Noto+Sans+KR) (Korean and English font)

BIN
downloading.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

View file

@ -1,360 +0,0 @@
# Version of the configuration file
version: 4.0.0
# Icarus theme variant, can be "default" or "cyberpunk"
variant: default
# Path or URL to the website's logo
logo: /img/icon_circle.svg
# Page metadata configurations
head:
# URL or path to the website's icon
favicon: /img/icon_circle.svg
# Web application manifests configuration
# https://developer.mozilla.org/en-US/docs/Web/Manifest
manifest:
# Name of the web application (default to the site title)
name:
# The displayed name of the web application
# when there is not enough space to display full name
short_name:
# The start URL of the web application
start_url:
# The default theme color for the application
theme_color:
# A placeholder background color for the application page to display
# before its stylesheet is loaded
background_color:
# The preferred display mode for the website
display: standalone
# Image files that can serve as application icons for different contexts
icons:
-
# The path to the image file
src: ''
# A string containing space-separated image dimensions
sizes: ''
# A hint as to the media type of the image
type:
# Open Graph metadata
# https://hexo.io/docs/helpers.html#open-graph
open_graph:
# Page title (og:title) (optional)
# You should leave this blank for most of the time
title:
# Page type (og:type) (optional)
# You should leave this blank for most of the time
type: blog
# Page URL (og:url) (optional)
# You should leave this blank for most of the time
url:
# Page cover (og:image) (optional)
# You should leave this blank for most of the time
image:
# Site name (og:site_name) (optional)
# You should leave this blank for most of the time
site_name:
# Page author (article:author) (optional)
# You should leave this blank for most of the time
author:
# Page description (og:description) (optional)
# You should leave this blank for most of the time
description:
# Twitter card type (twitter:card)
twitter_card:
# Twitter ID (twitter:creator)
twitter_id:
# Twitter Site (twitter:site)
twitter_site:
# Google+ profile link (deprecated)
google_plus:
# Facebook admin ID
fb_admins:
# Facebook App ID
fb_app_id:
# Structured data of the page
# https://developers.google.com/search/docs/guides/intro-structured-data
structured_data:
# Page title (optional)
# You should leave this blank for most of the time
title:
# Page description (optional)
# You should leave this blank for most of the time
description:
# Page URL (optional)
# You should leave this blank for most of the time
url:
# Page author (article:author) (optional)
# You should leave this blank for most of the time
author:
# Page images (optional)
# You should leave this blank for most of the time
image:
# Additional HTML meta tags in an array
meta:
# Meta tag specified in <attribute>=<value> style
# E.g., name=theme-color;content=#123456 => <meta name="theme-color" content="#123456">
- ''
# URL or path to the website's RSS atom.xml
rss:
# Page top navigation bar configurations
navbar:
# Navigation menu items
menu:
Home: /
Archives: /archives
Categories: /categories
Tags: /tags
Explore: /explore
# Links to be shown on the right of the navigation bar
links:
RSS feed:
icon: fas fa-rss
url: /feed
View source:
icon: fab fa-github
url: 'https://github.com/developomp/developomp-site'
# Page footer configurations
footer:
# Links to be shown on the right of the footer section
links:
Creative Commons:
icon: fab fa-creative-commons
url: 'https://creativecommons.org/'
Attribution:
icon: fab fa-creative-commons-by
url: 'https://creativecommons.org/licenses/by/4.0/'
# Article related configurations
article:
# Code highlight settings
highlight:
# Code highlight themes
# https://github.com/highlightjs/highlight.js/tree/master/src/styles
theme: atom-one-light
# Show copy code button
clipboard: true
# Default folding status of the code blocks. Can be "", "folded", "unfolded"
fold: unfolded
# Whether to show estimated article reading time
readtime: true
# Article licensing block
# licenses:
# Creative Commons:
# icon: fab fa-creative-commons
# url: 'https://creativecommons.org/'
# Attribution:
# icon: fab fa-creative-commons-by
# url: 'https://creativecommons.org/licenses/by/4.0/'
# Search plugin configurations
# https://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Search/
search:
type: insight
# Comment plugin configurations
# https://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Comment/
# comment:
# type: disqus
# Disqus shortname
# shortname: 'developomp'
# Donate plugin configurations
# https://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Donation/
# donates:
# "Buy me a coffee" donate button configurations
# -
# type: buymeacoffee
# # URL to the "Buy me a coffee" page
# url: ''
# Patreon donate button configurations
# -
# type: patreon
# # URL to the Patreon page
# url: ''
# Paypal donate button configurations
# -
# type: paypal
# # Paypal business ID or email address
# business: ''
# # Currency code
# currency_code: USD
# Share plugin configurations
# https://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Share/
# share:
# type: sharethis
# # URL to the ShareThis share plugin script
# install_url: ''
# Sidebar configurations.
# Please be noted that a sidebar is only visible when it has at least one widget
sidebar:
# Left sidebar configurations
left:
# Whether the sidebar sticks to the top when page scrolls
sticky: false
# Right sidebar configurations
right:
# Whether the sidebar sticks to the top when page scrolls
sticky: false
# Sidebar widget configurations
# http://ppoffice.github.io/hexo-theme-icarus/categories/Widgets/
widgets:
# Profile widget configurations
# -
# Where should the widget be placed, left sidebar or right sidebar
# position: left
# type: profile
# Author name
# author: developomp
# Author title
# author_title:
# Author's current location
# location: South Korea
# URL or path to the avatar image
# avatar: /img/icon.svg
# Whether show the rounded avatar image
# avatar_rounded: true
# Email address for the Gravatar
# gravatar:
# URL or path for the follow button
# follow_link:
# Links to be shown on the bottom of the profile widget
# social_links:
# Github:
# icon: fab fa-github
# url: 'https://github.com/developomp'
# RSS:
# icon: fas fa-rss
# url: /feed
# Table of contents widget configurations
-
# Where should the widget be placed, left sidebar or right sidebar
position: left
type: toc
# Whether to show the index of each heading
index: true
# Recommendation links widget configurations
# -
# # Where should the widget be placed, left sidebar or right sidebar
# position: left
# type: links
# # Names and URLs of the sites
# links:
# Hexo: 'https://hexo.io'
# Bulma: 'https://bulma.io'
# Categories widget configurations
-
# Where should the widget be placed, left sidebar or right sidebar
position: left
type: categories
# Recent posts widget configurations
-
# Where should the widget be placed, left sidebar or right sidebar
position: left
type: recent_posts
# Archives widget configurations
-
# Where should the widget be placed, left sidebar or right sidebar
position: left
type: archives
# Tags widget configurations
-
# Where should the widget be placed, left sidebar or right sidebar
position: left
type: tags
# Google FeedBurner email subscription widget configurations
# -
# # Where should the widget be placed, left sidebar or right sidebar
# position: left
# type: subscribe_email
# # Hint text under the email input
# description:
# # Feedburner ID
# feedburner_id: ''
# Google AdSense unit configurations
# -
# # Where should the widget be placed, left sidebar or right sidebar
# position: left
# type: adsense
# # AdSense client ID
# client_id: ''
# # AdSense AD unit ID
# slot_id: ''
# Plugin configurations
# https://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/
plugins:
# Enable page startup animations
animejs: true
# Show the "back to top" button
back_to_top: true
# Baidu Analytics plugin settings
# https://tongji.baidu.com
# baidu_analytics:
# Baidu Analytics tracking ID
# tracking_id:
# Bing Webmaster Tools plugin settings
# https://www.bing.com/toolbox/webmaster/
# bing_webmaster:
# Bing Webmaster Tools tracking ID in the <meta> tag
# tracking_id:
# BuSuanZi site/page view counter
# https://busuanzi.ibruce.info
busuanzi: false
# CNZZ statistics
# https://www.umeng.com/web
# cnzz:
# CNZZ tracker id
# id:
# CNZZ website id
# web_id:
# Alerting users about the use of cookies
# https://www.osano.com/cookieconsent/
cookie_consent:
# The compliance type. Can be "info", "opt-in", or "opt-out"
type: info
# Theme of the popup. Can be "block", "edgeless", or "classic"
theme: edgeless
# Whether the popup should stay static regardless of the page scrolls
static: false
# Where on the screen the consent popup should display
position: bottom-left
# URL to your site's cookie policy
policyLink: 'https://www.cookiesandyou.com/'
# Enable the lightGallery and Justified Gallery plugins
gallery: true
# Google Analytics plugin settings
# https://analytics.google.com
google_analytics:
# Google Analytics tracking ID
tracking_id:
# Hotjar user feedback plugin
# https://www.hotjar.com/
hotjar:
# Hotjar site id
site_id:
# Enable the KaTeX math typesetting support
# https://katex.org/
katex: false
# Enable the MathJax math typesetting support
# https://www.mathjax.org/
mathjax: false
# Enable the Outdated Browser plugin
# http://outdatedbrowser.com/
outdated_browser: false
# Show a progress bar at top of the page on page loading
progressbar: true
# Statcounter statistics
# https://statcounter.com/
statcounter:
# Statcounter project id
project:
# Statcounter project security code
security:
# Twitter conversion tracking plugin settings
# https://business.twitter.com/en/help/campaign-measurement-and-analytics/conversion-tracking-for-websites.html
twitter_conversion_tracking:
# Twitter Pixel ID
pixel_id:
# CDN provider settings
# https://ppoffice.github.io/hexo-theme-icarus/Configuration/Theme/speed-up-your-site-with-custom-cdn/
providers:
# Name or URL template of the JavaScript and/or stylesheet CDN provider
cdn: jsdelivr
# Name or URL template of the webfont CDN provider
fontcdn: google
# Name or URL of the fontawesome icon font CDN provider
iconcdn: fontawesome

View file

@ -1,89 +0,0 @@
title: developomp
subtitle: ''
description: developomp's website
keywords: developomp
author: developomp
language: en
timezone: ''
url: 'http://developomp.com'
root: /
permalink: ':title/'
permalink_defaults:
lang: en
pretty_urls:
trailing_index: false
trailing_html: false
source_dir: source
public_dir: public
tag_dir: tags
archive_dir: archives
category_dir: categories
code_dir: downloads/code
i18n_dir: ':lang'
skip_render:
- '*.json'
- '*.unityweb'
- '**/*.html'
- '*.xml'
- '*.js'
- '*.css'
- '*.txt'
feed:
type:
- atom
- rss2
path:
- atom.xml
- rss2.xml
limit: 10
hub: null
content: null
content_limit: 140
content_limit_delim: ' '
order_by: '-date'
icon: /img/icon_circle.svg
autodiscovery: true
template: null
new_post_name: ':title.md'
default_layout: post
titlecase: false
external_link:
enable: true
field: site
exclude: ''
filename_case: 0
render_drafts: false
post_asset_folder: false
relative_link: false
future: true
highlight:
enable: true
line_number: true
auto_detect: false
tab_replace: ''
wrap: true
hljs: false
prismjs:
enable: false
preprocess: true
line_number: true
tab_replace: ''
index_generator:
path: ''
per_page: 10
order_by: '-date'
default_category: uncategorized
category_map: null
tag_map: null
meta_generator: true
date_format: YYYY-MM-DD
time_format: 'HH:mm:ss'
updated_option: mtime
per_page: 10
pagination_dir: page
include: null
exclude: null
ignore: null
theme: icarus
deploy:
type: ''

View file

@ -1,27 +0,0 @@
{
"name": "developomp.com",
"version": "0.0.0",
"private": true,
"author": "developomp",
"hexo": {
"version": "5.3.0"
},
"dependencies": {
"bulma-stylus": "^0.8.0",
"hexo": "latest",
"hexo-component-inferno": "latest",
"hexo-generator-archive": "latest",
"hexo-generator-category": "latest",
"hexo-generator-feed": "latest",
"hexo-generator-index": "latest",
"hexo-generator-tag": "latest",
"hexo-renderer-ejs": "latest",
"hexo-renderer-inferno": "latest",
"hexo-renderer-marked": "latest",
"hexo-renderer-stylus": "latest",
"hexo-server": "latest",
"hexo-theme-icarus": "latest",
"inferno": "latest",
"inferno-create-element": "latest"
}
}

View file

@ -1,6 +0,0 @@
---
title: { { title } }
date: { { date } }
updated: { { date } }
tags:
---

View file

@ -1,12 +0,0 @@
---
title:
comment:
licenses:
widgets:
article:
---
<center>
<h1><font size=40>404</font></h1>
the page you're looking for does not exist. :(
</center>

View file

@ -1,5 +0,0 @@
---
title: explore
---
Nothing here.

View file

@ -1,2 +0,0 @@
- [rss2](/rss2.xml)
- [atom](/atom.xml)

View file

@ -1,2 +0,0 @@
- [rss2](/rss2.xml)
- [atom](/atom.xml)

View file

@ -1,7 +0,0 @@
---
title: games
date: 2020-08-16
tags:
---
Nothing here yet.

View file

@ -1,176 +0,0 @@
/*---[ MAIN ]---*/
*, *::after, *::before {
box-sizing: border-box;
}
:root {
--cell-size: 100px;
--mark-size: calc(var(--cell-size) * .9);
--background-color: black;
--main-color: white;
}
body {
margin: 0;
background-color: var(--background-color);
}
/*---[ Winner message ]---*/
.winner {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, .9);
justify-content: center;
align-items: center;
color: var(--main-color);
font-size: 5rem;
font-family: Arial, sans-serif;
flex-direction: column;
}
.winner button {
font-size: 3rem;
background-color: var(--background-color);
color: var(--main-color);
border: 1px solid var(--main-color);
padding: .25em .5em;
cursor: pointer;
}
.winner button:hover {
background-color: var(--main-color);
color: var(--background-color);
border-color: var(--background-color);
}
.winner.show {
display: flex;
}
/*---[ Board styling ]---*/
.board {
width: 100vw;
height: 100vh;
display: grid;
justify-content: center;
align-content: center;
justify-items: center;
align-items: center;
grid-template-columns: repeat(3, auto);
}
/*---[ Cell styling ]---*/
.cell {
width: var(--cell-size);
height: var(--cell-size);
justify-content: center;
align-items: center;
display: flex;
background-color: var(--background-color);
border: 2px solid var(--main-color);
position: relative;
cursor: pointer;
}
.cell.x,
.cell.o {
cursor: not-allowed;
}
/*---[ Remove edge border for edge cells ]---*/
.cell:nth-child(1),
.cell:nth-child(2),
.cell:nth-child(3) {
border-top: none;
}
.cell:nth-child(1),
.cell:nth-child(4),
.cell:nth-child(7) {
border-left: none;
}
.cell:nth-child(3),
.cell:nth-child(6),
.cell:nth-child(9) {
border-right: none;
}
.cell:nth-child(7),
.cell:nth-child(8),
.cell:nth-child(9) {
border-bottom: none;
}
/*---[ X ]---*/
.cell.x::before,
.cell.x::after {
content: '';
position: absolute;
width: calc(var(--mark-size) * .1);
height: var(--mark-size);
background-color: var(--main-color);
}
.board.x .cell:not(.x):not(.o):hover::before,
.board.x .cell:not(.x):not(.o):hover::after {
content: '';
position: absolute;
width: calc(var(--mark-size) * .1);
height: var(--mark-size);
background-color: dimgray;
}
.cell.x::before,
.board.x .cell:hover::before {
transform: rotate(45deg);
}
.cell.x::after,
.board.x .cell:hover::after {
transform: rotate(-45deg);
}
/*---[ O ]---*/
.cell.o::before,
.cell.o::after {
content: '';
position: absolute;
border-radius: 50%;
width: var(--mark-size);
height: var(--mark-size);
background-color: var(--main-color);
}
.board.o .cell:not(.x):not(.o):hover::before,
.board.o .cell:not(.x):not(.o):hover::after {
content: '';
position: absolute;
border-radius: 50%;
width: var(--mark-size);
height: var(--mark-size);
background-color: dimgray;
}
.cell.o::before {
height: calc(var(--mark-size) * .9);
width: calc(var(--mark-size) * .9);
background-color: var(--main-color);
}
.board.o .cell:not(.x):not(.o):hover::before {
height: calc(var(--mark-size) * .9);
width: calc(var(--mark-size) * .9);
background-color: dimgray;
}
.cell.o::after,
.board.o .cell:not(.x):not(.o):hover::after{
height: calc(var(--mark-size) * .69);
width: calc(var(--mark-size) *.69);
background-color: var(--background-color);
}

View file

@ -1,28 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TicTac Toe</title>
<link rel="stylesheet" href="/games/tictactoe/index.css">
<script src="/games/tictactoe/index.js" defer></script>
</head>
<body>
<div class="board x" id="board">
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
<div class="cell" data-cell></div>
</div>
<div class="winner" id="winner">
<div data-message></div>
<button id="restart">Restart</button>
</div>
</body>
</html>

View file

@ -1,89 +0,0 @@
const X_CLASS = "x"
const O_CLASS = "o"
const WINNING_PATTERN = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
]
const cellElements = document.querySelectorAll("[data-cell]")
const board = document.getElementById("board")
const winnerMessage = document.querySelector("[data-message]")
const winner = document.getElementById("winner")
const restartButton = document.getElementById("restart")
let oTurn = false;
restartButton.addEventListener("click", gameStart)
function gameStart() {
function clickHandler(event) {
console.log(full())
const currentClass = oTurn ? O_CLASS : X_CLASS
event.target.classList.add(currentClass) // add O or X to the grid
if (checkWin(currentClass)) {
gameOver(false)
} else if (full()) {
gameOver(true)
}
oTurn = !oTurn // change tern
updateHover()
}
winner.classList.remove("show")
cellElements.forEach(cell => {
cell.classList.remove("o")
cell.classList.remove("x")
})
cellElements.forEach(cell => {
cell.addEventListener("click", clickHandler, {once: true})
})
updateHover()
}
function gameOver(draw) {
if (draw) {
// show draw message
}
else {
winnerMessage.innerText = `${oTurn ? "O" : "X"} won!!`
}
winner.classList.add("show")
}
function updateHover() {
board.classList.remove(X_CLASS)
board.classList.remove(O_CLASS)
if (oTurn) {
board.classList.add(O_CLASS)
}
else {
board.classList.add(X_CLASS)
}
}
function checkWin(currentClass) {
return WINNING_PATTERN.some(combination => {
return combination.every(index => {
return cellElements[index].classList.contains(currentClass)
})
})
}
function full() {
//todo: add when the game is a draw
return false
}
gameStart()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View file

@ -1,4 +0,0 @@
<svg width="800" height="800" viewBox="0 0 800 800" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="800" height="800" fill="black"/>
<path d="M217.617 226.262H184.863C180.632 226.262 176.23 226.77 171.66 227.785C167.259 228.632 163.197 230.07 159.473 232.102C155.749 234.133 152.702 236.757 150.332 239.973C147.962 243.189 146.777 247.082 146.777 251.652V252.16V341.281C146.777 354.315 144.915 365.826 141.191 375.812C137.467 385.63 132.643 394.178 126.719 401.457C133.828 410.598 138.822 420.415 141.699 430.91C144.746 441.405 146.27 451.223 146.27 460.363V550.246C146.27 556.171 147.793 560.91 150.84 564.465C153.887 567.85 157.526 570.474 161.758 572.336C165.99 574.029 170.221 575.129 174.453 575.637C178.685 575.975 181.986 576.145 184.355 576.145H217.109V642.922H183.848C176.908 642.922 169.46 642.16 161.504 640.637C153.717 639.283 145.931 636.997 138.145 633.781C130.527 630.734 123.164 626.757 116.055 621.848C109.115 616.939 102.936 611.014 97.5195 604.074C92.2721 597.134 88.0404 589.178 84.8242 580.207C81.7773 571.236 80.2539 561.079 80.2539 549.738V460.871C80.2539 451.9 77.8841 445.214 73.1445 440.812C68.5742 436.411 62.1419 434.211 53.8477 434.211C49.1081 434.211 44.707 433.365 40.6445 431.672C36.582 429.81 33.0273 427.44 29.9805 424.562C27.1029 421.516 24.8177 417.961 23.125 413.898C21.4323 409.836 20.5859 405.52 20.5859 400.949C20.5859 396.379 21.4323 392.147 23.125 388.254C24.8177 384.191 27.1029 380.721 29.9805 377.844C33.0273 374.797 36.4974 372.427 40.3906 370.734C44.4531 368.872 48.7695 367.857 53.3398 367.688C62.4805 367.688 69.3359 365.487 73.9062 361.086C78.4766 356.516 80.7617 349.914 80.7617 341.281V251.652C80.7617 237.095 83.724 224.146 89.6484 212.805C95.5729 201.464 103.444 191.9 113.262 184.113C123.079 176.327 134.167 170.402 146.523 166.34C159.049 162.277 171.829 160.246 184.863 160.246H217.617V226.262ZM595.47 371.242C595.47 386.307 593.608 399.764 589.884 411.613C586.16 423.462 581.082 433.957 574.65 443.098C568.387 452.069 561.108 459.771 552.814 466.203C544.52 472.635 535.802 477.883 526.662 481.945C517.69 486.008 508.55 488.97 499.24 490.832C490.099 492.694 481.466 493.625 473.341 493.625H324.045V427.609H473.341C481.805 426.932 489.422 425.24 496.193 422.531C503.133 419.654 509.058 415.845 513.966 411.105C518.875 406.366 522.684 400.695 525.392 394.094C528.101 387.323 529.455 379.706 529.455 371.242V341.281C528.608 332.987 526.831 325.37 524.123 318.43C521.414 311.49 517.69 305.565 512.951 300.656C508.38 295.747 502.795 291.939 496.193 289.23C489.591 286.353 481.974 284.914 473.341 284.914H324.552C315.75 284.914 309.064 287.199 304.494 291.77C299.923 296.34 297.638 302.941 297.638 311.574V583H231.623V311.574C231.623 294.647 234.67 280.259 240.763 268.41C247.026 256.561 254.728 246.997 263.869 239.719C273.179 232.44 283.25 227.193 294.084 223.977C304.917 220.591 314.904 218.898 324.045 218.898H473.341C488.237 218.898 501.61 220.845 513.459 224.738C525.308 228.462 535.718 233.54 544.689 239.973C553.83 246.236 561.532 253.514 567.795 261.809C574.227 270.103 579.474 278.82 583.537 287.961C587.768 296.932 590.815 306.073 592.677 315.383C594.539 324.523 595.47 333.156 595.47 341.281V371.242ZM778.07 400.949C778.07 405.52 777.223 409.836 775.53 413.898C773.838 417.961 771.468 421.516 768.421 424.562C765.543 427.44 762.073 429.81 758.011 431.672C754.118 433.365 749.886 434.211 745.316 434.211C736.683 434.211 729.997 436.411 725.257 440.812C720.687 445.214 718.402 451.9 718.402 460.871L718.909 549.738C718.909 561.079 717.301 571.236 714.085 580.207C710.869 589.178 706.553 597.134 701.136 604.074C695.719 611.014 689.456 616.939 682.347 621.848C675.407 626.757 668.043 630.734 660.257 633.781C652.64 636.997 644.853 639.283 636.898 640.637C629.111 642.16 621.748 642.922 614.808 642.922H582.054L581.546 576.145H614.808C617.008 576.145 620.224 575.975 624.456 575.637C628.688 575.129 632.835 574.029 636.898 572.336C641.129 570.474 644.769 567.85 647.816 564.465C650.862 560.91 652.386 556.171 652.386 550.246V460.363C652.386 451.223 653.909 441.405 656.956 430.91C660.172 420.415 665.166 410.598 671.937 401.457C666.012 394.178 661.103 385.63 657.21 375.812C653.486 365.826 651.624 354.315 651.624 341.281V252.16V251.652C650.778 246.913 649.17 242.935 646.8 239.719C644.599 236.503 641.806 233.879 638.421 231.848C635.036 229.816 631.227 228.378 626.995 227.531C622.933 226.685 618.701 226.262 614.3 226.262H581.038V160.246H614.3C628.011 160.246 641.129 162.447 653.655 166.848C666.181 171.079 677.184 177.258 686.663 185.383C696.312 193.339 703.929 202.987 709.515 214.328C715.101 225.5 717.894 237.941 717.894 251.652C717.894 252.837 717.978 260.878 718.148 275.773C718.317 290.5 718.402 312.336 718.402 341.281C718.402 349.914 720.602 356.516 725.003 361.086C729.404 365.487 736.175 367.688 745.316 367.688C749.886 367.857 754.118 368.872 758.011 370.734C762.073 372.427 765.543 374.797 768.421 377.844C771.468 380.721 773.838 384.191 775.53 388.254C777.223 392.147 778.07 396.379 778.07 400.949Z" fill="#F4F4F4"/>
</svg>

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

View file

@ -1,4 +0,0 @@
<svg width="800" height="800" viewBox="0 0 800 800" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="400" cy="400" r="400" fill="black"/>
<path d="M217.617 226.262H184.863C180.632 226.262 176.23 226.77 171.66 227.785C167.259 228.632 163.197 230.07 159.473 232.102C155.749 234.133 152.702 236.757 150.332 239.973C147.962 243.189 146.777 247.082 146.777 251.652V252.16V341.281C146.777 354.315 144.915 365.826 141.191 375.812C137.467 385.63 132.643 394.178 126.719 401.457C133.828 410.598 138.822 420.415 141.699 430.91C144.746 441.405 146.27 451.223 146.27 460.363V550.246C146.27 556.171 147.793 560.91 150.84 564.465C153.887 567.85 157.526 570.474 161.758 572.336C165.99 574.029 170.221 575.129 174.453 575.637C178.685 575.975 181.986 576.145 184.355 576.145H217.109V642.922H183.848C176.908 642.922 169.46 642.16 161.504 640.637C153.717 639.283 145.931 636.997 138.145 633.781C130.527 630.734 123.164 626.757 116.055 621.848C109.115 616.939 102.936 611.014 97.5195 604.074C92.2721 597.134 88.0404 589.178 84.8242 580.207C81.7773 571.236 80.2539 561.079 80.2539 549.738V460.871C80.2539 451.9 77.8841 445.214 73.1445 440.812C68.5742 436.411 62.1419 434.211 53.8477 434.211C49.1081 434.211 44.707 433.365 40.6445 431.672C36.582 429.81 33.0273 427.44 29.9805 424.562C27.1029 421.516 24.8177 417.961 23.125 413.898C21.4323 409.836 20.5859 405.52 20.5859 400.949C20.5859 396.379 21.4323 392.147 23.125 388.254C24.8177 384.191 27.1029 380.721 29.9805 377.844C33.0273 374.797 36.4974 372.427 40.3906 370.734C44.4531 368.872 48.7695 367.857 53.3398 367.688C62.4805 367.688 69.3359 365.487 73.9062 361.086C78.4766 356.516 80.7617 349.914 80.7617 341.281V251.652C80.7617 237.095 83.724 224.146 89.6484 212.805C95.5729 201.464 103.444 191.9 113.262 184.113C123.079 176.327 134.167 170.402 146.523 166.34C159.049 162.277 171.829 160.246 184.863 160.246H217.617V226.262ZM595.47 371.242C595.47 386.307 593.608 399.764 589.884 411.613C586.16 423.462 581.082 433.957 574.65 443.098C568.387 452.069 561.108 459.771 552.814 466.203C544.52 472.635 535.802 477.883 526.662 481.945C517.69 486.008 508.55 488.97 499.24 490.832C490.099 492.694 481.466 493.625 473.341 493.625H324.045V427.609H473.341C481.805 426.932 489.422 425.24 496.193 422.531C503.133 419.654 509.058 415.845 513.966 411.105C518.875 406.366 522.684 400.695 525.392 394.094C528.101 387.323 529.455 379.706 529.455 371.242V341.281C528.608 332.987 526.831 325.37 524.123 318.43C521.414 311.49 517.69 305.565 512.951 300.656C508.38 295.747 502.795 291.939 496.193 289.23C489.591 286.353 481.974 284.914 473.341 284.914H324.552C315.75 284.914 309.064 287.199 304.494 291.77C299.923 296.34 297.638 302.941 297.638 311.574V583H231.623V311.574C231.623 294.647 234.67 280.259 240.763 268.41C247.026 256.561 254.728 246.997 263.869 239.719C273.179 232.44 283.25 227.193 294.084 223.977C304.917 220.591 314.904 218.898 324.045 218.898H473.341C488.237 218.898 501.61 220.845 513.459 224.738C525.308 228.462 535.718 233.54 544.689 239.973C553.83 246.236 561.532 253.514 567.795 261.809C574.227 270.103 579.474 278.82 583.537 287.961C587.768 296.932 590.815 306.073 592.677 315.383C594.539 324.523 595.47 333.156 595.47 341.281V371.242ZM778.07 400.949C778.07 405.52 777.223 409.836 775.53 413.898C773.838 417.961 771.468 421.516 768.421 424.562C765.543 427.44 762.073 429.81 758.011 431.672C754.118 433.365 749.886 434.211 745.316 434.211C736.683 434.211 729.997 436.411 725.257 440.812C720.687 445.214 718.402 451.9 718.402 460.871L718.909 549.738C718.909 561.079 717.301 571.236 714.085 580.207C710.869 589.178 706.553 597.134 701.136 604.074C695.719 611.014 689.456 616.939 682.347 621.848C675.407 626.757 668.043 630.734 660.257 633.781C652.64 636.997 644.853 639.283 636.898 640.637C629.111 642.16 621.748 642.922 614.808 642.922H582.054L581.546 576.145H614.808C617.008 576.145 620.224 575.975 624.456 575.637C628.688 575.129 632.835 574.029 636.898 572.336C641.129 570.474 644.769 567.85 647.816 564.465C650.862 560.91 652.386 556.171 652.386 550.246V460.363C652.386 451.223 653.909 441.405 656.956 430.91C660.172 420.415 665.166 410.598 671.937 401.457C666.012 394.178 661.103 385.63 657.21 375.812C653.486 365.826 651.624 354.315 651.624 341.281V252.16V251.652C650.778 246.913 649.17 242.935 646.8 239.719C644.599 236.503 641.806 233.879 638.421 231.848C635.036 229.816 631.227 228.378 626.995 227.531C622.933 226.685 618.701 226.262 614.3 226.262H581.038V160.246H614.3C628.011 160.246 641.129 162.447 653.655 166.848C666.181 171.079 677.184 177.258 686.663 185.383C696.312 193.339 703.929 202.987 709.515 214.328C715.101 225.5 717.894 237.941 717.894 251.652C717.894 252.837 717.978 260.878 718.148 275.773C718.317 290.5 718.402 312.336 718.402 341.281C718.402 349.914 720.602 356.516 725.003 361.086C729.404 365.487 736.175 367.688 745.316 367.688C749.886 367.857 754.118 368.872 758.011 370.734C762.073 372.427 765.543 374.797 768.421 377.844C771.468 380.721 773.838 384.191 775.53 388.254C777.223 392.147 778.07 396.379 778.07 400.949Z" fill="#F4F4F4"/>
</svg>

Before

Width:  |  Height:  |  Size: 4.9 KiB

View file

@ -1,3 +0,0 @@
<svg width="800" height="800" viewBox="0 0 800 800" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M217.617 226.262H184.863C180.632 226.262 176.23 226.77 171.66 227.785C167.259 228.632 163.197 230.07 159.473 232.102C155.749 234.133 152.702 236.757 150.332 239.973C147.962 243.189 146.777 247.082 146.777 251.652V252.16V341.281C146.777 354.315 144.915 365.826 141.191 375.812C137.467 385.63 132.643 394.178 126.719 401.457C133.828 410.598 138.822 420.415 141.699 430.91C144.746 441.405 146.27 451.223 146.27 460.363V550.246C146.27 556.171 147.793 560.91 150.84 564.465C153.887 567.85 157.526 570.474 161.758 572.336C165.99 574.029 170.221 575.129 174.453 575.637C178.685 575.975 181.986 576.145 184.355 576.145H217.109V642.922H183.848C176.908 642.922 169.46 642.16 161.504 640.637C153.717 639.283 145.931 636.997 138.145 633.781C130.527 630.734 123.164 626.757 116.055 621.848C109.115 616.939 102.936 611.014 97.5195 604.074C92.2721 597.134 88.0404 589.178 84.8242 580.207C81.7773 571.236 80.2539 561.079 80.2539 549.738V460.871C80.2539 451.9 77.8841 445.214 73.1445 440.812C68.5742 436.411 62.1419 434.211 53.8477 434.211C49.1081 434.211 44.707 433.365 40.6445 431.672C36.582 429.81 33.0273 427.44 29.9805 424.562C27.1029 421.516 24.8177 417.961 23.125 413.898C21.4323 409.836 20.5859 405.52 20.5859 400.949C20.5859 396.379 21.4323 392.147 23.125 388.254C24.8177 384.191 27.1029 380.721 29.9805 377.844C33.0273 374.797 36.4974 372.427 40.3906 370.734C44.4531 368.872 48.7695 367.857 53.3398 367.688C62.4805 367.688 69.3359 365.487 73.9062 361.086C78.4766 356.516 80.7617 349.914 80.7617 341.281V251.652C80.7617 237.095 83.724 224.146 89.6484 212.805C95.5729 201.464 103.444 191.9 113.262 184.113C123.079 176.327 134.167 170.402 146.523 166.34C159.049 162.277 171.829 160.246 184.863 160.246H217.617V226.262ZM595.47 371.242C595.47 386.307 593.608 399.764 589.884 411.613C586.16 423.462 581.082 433.957 574.65 443.098C568.387 452.069 561.108 459.771 552.814 466.203C544.52 472.635 535.802 477.883 526.662 481.945C517.69 486.008 508.55 488.97 499.24 490.832C490.099 492.694 481.466 493.625 473.341 493.625H324.045V427.609H473.341C481.805 426.932 489.422 425.24 496.193 422.531C503.133 419.654 509.058 415.845 513.966 411.105C518.875 406.366 522.684 400.695 525.392 394.094C528.101 387.323 529.455 379.706 529.455 371.242V341.281C528.608 332.987 526.831 325.37 524.123 318.43C521.414 311.49 517.69 305.565 512.951 300.656C508.38 295.747 502.795 291.939 496.193 289.23C489.591 286.353 481.974 284.914 473.341 284.914H324.552C315.75 284.914 309.064 287.199 304.494 291.77C299.923 296.34 297.638 302.941 297.638 311.574V583H231.623V311.574C231.623 294.647 234.67 280.259 240.763 268.41C247.026 256.561 254.728 246.997 263.869 239.719C273.179 232.44 283.25 227.193 294.084 223.977C304.917 220.591 314.904 218.898 324.045 218.898H473.341C488.237 218.898 501.61 220.845 513.459 224.738C525.308 228.462 535.718 233.54 544.689 239.973C553.83 246.236 561.532 253.514 567.795 261.809C574.227 270.103 579.474 278.82 583.537 287.961C587.768 296.932 590.815 306.073 592.677 315.383C594.539 324.523 595.47 333.156 595.47 341.281V371.242ZM778.07 400.949C778.07 405.52 777.223 409.836 775.53 413.898C773.838 417.961 771.468 421.516 768.421 424.562C765.543 427.44 762.073 429.81 758.011 431.672C754.118 433.365 749.886 434.211 745.316 434.211C736.683 434.211 729.997 436.411 725.257 440.812C720.687 445.214 718.402 451.9 718.402 460.871L718.909 549.738C718.909 561.079 717.301 571.236 714.085 580.207C710.869 589.178 706.553 597.134 701.136 604.074C695.719 611.014 689.456 616.939 682.347 621.848C675.407 626.757 668.043 630.734 660.257 633.781C652.64 636.997 644.853 639.283 636.898 640.637C629.111 642.16 621.748 642.922 614.808 642.922H582.054L581.546 576.145H614.808C617.008 576.145 620.224 575.975 624.456 575.637C628.688 575.129 632.835 574.029 636.898 572.336C641.129 570.474 644.769 567.85 647.816 564.465C650.862 560.91 652.386 556.171 652.386 550.246V460.363C652.386 451.223 653.909 441.405 656.956 430.91C660.172 420.415 665.166 410.598 671.937 401.457C666.012 394.178 661.103 385.63 657.21 375.812C653.486 365.826 651.624 354.315 651.624 341.281V252.16V251.652C650.778 246.913 649.17 242.935 646.8 239.719C644.599 236.503 641.806 233.879 638.421 231.848C635.036 229.816 631.227 228.378 626.995 227.531C622.933 226.685 618.701 226.262 614.3 226.262H581.038V160.246H614.3C628.011 160.246 641.129 162.447 653.655 166.848C666.181 171.079 677.184 177.258 686.663 185.383C696.312 193.339 703.929 202.987 709.515 214.328C715.101 225.5 717.894 237.941 717.894 251.652C717.894 252.837 717.978 260.878 718.148 275.773C718.317 290.5 718.402 312.336 718.402 341.281C718.402 349.914 720.602 356.516 725.003 361.086C729.404 365.487 736.175 367.688 745.316 367.688C749.886 367.857 754.118 368.872 758.011 370.734C762.073 372.427 765.543 374.797 768.421 377.844C771.468 380.721 773.838 384.191 775.53 388.254C777.223 392.147 778.07 396.379 778.07 400.949Z" fill="#F4F4F4"/>
</svg>

Before

Width:  |  Height:  |  Size: 4.8 KiB

View file

@ -1,166 +0,0 @@
/**
* @author mrdoob / http://mrdoob.com/
* @author Mugen87 / https://github.com/Mugen87
*/
// https://raw.githubusercontent.com/mrdoob/three.js/dev/examples/jsm/controls/PointerLockControls.js
import {
Euler,
EventDispatcher,
Vector3
} from "./three.js";
var PointerLockControls = function ( camera, domElement ) {
if ( domElement === undefined ) {
console.warn( 'THREE.PointerLockControls: The second parameter "domElement" is now mandatory.' );
domElement = document.body;
}
this.domElement = domElement;
this.isLocked = false;
//
// internals
//
var scope = this;
var changeEvent = { type: 'change' };
var lockEvent = { type: 'lock' };
var unlockEvent = { type: 'unlock' };
var euler = new Euler( 0, 0, 0, 'YXZ' );
var PI_2 = Math.PI / 2;
var vec = new Vector3();
function onMouseMove( event ) {
if ( scope.isLocked === false ) return;
var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0;
var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0;
euler.setFromQuaternion( camera.quaternion );
euler.y -= movementX * 0.002;
euler.x -= movementY * 0.002;
euler.x = Math.max( - PI_2, Math.min( PI_2, euler.x ) );
camera.quaternion.setFromEuler( euler );
scope.dispatchEvent( changeEvent );
}
function onPointerlockChange() {
if ( document.pointerLockElement === scope.domElement ) {
scope.dispatchEvent( lockEvent );
scope.isLocked = true;
} else {
scope.dispatchEvent( unlockEvent );
scope.isLocked = false;
}
}
function onPointerlockError() {
console.error( 'THREE.PointerLockControls: Unable to use Pointer Lock API' );
}
this.connect = function () {
document.addEventListener( 'mousemove', onMouseMove, false );
document.addEventListener( 'pointerlockchange', onPointerlockChange, false );
document.addEventListener( 'pointerlockerror', onPointerlockError, false );
};
this.disconnect = function () {
document.removeEventListener( 'mousemove', onMouseMove, false );
document.removeEventListener( 'pointerlockchange', onPointerlockChange, false );
document.removeEventListener( 'pointerlockerror', onPointerlockError, false );
};
this.dispose = function () {
this.disconnect();
};
this.getObject = function () { // retaining this method for backward compatibility
return camera;
};
this.getDirection = function () {
var direction = new Vector3( 0, 0, - 1 );
return function ( v ) {
return v.copy( direction ).applyQuaternion( camera.quaternion );
};
}();
this.moveForward = function ( distance ) {
// move forward parallel to the xz-plane
// assumes camera.up is y-up
vec.setFromMatrixColumn( camera.matrix, 0 );
vec.crossVectors( camera.up, vec );
camera.position.addScaledVector( vec, distance );
};
this.moveRight = function ( distance ) {
vec.setFromMatrixColumn( camera.matrix, 0 );
camera.position.addScaledVector( vec, distance );
};
this.lock = function () {
this.domElement.requestPointerLock();
};
this.unlock = function () {
document.exitPointerLock();
};
this.connect();
};
PointerLockControls.prototype = Object.create( EventDispatcher.prototype );
PointerLockControls.prototype.constructor = PointerLockControls;
export { PointerLockControls };

View file

@ -1,89 +0,0 @@
body {
margin: 0;
background-color: #282828;
color: #fff;
font-family: Monospace, sans-serif;
font-size: 13px;
line-height: 24px;
overscroll-behavior: none;
}
canvas {
width: 100%;
height: 100%;
display: block;
}
a {
color: #ff0;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
button {
cursor: pointer;
text-transform: uppercase;
}
#info {
position: absolute;
top: 0;
width: 100%;
padding: 10px;
box-sizing: border-box;
text-align: center;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
pointer-events: none;
z-index: 1;
}
a, button, input, select {
pointer-events: auto;
}
.dg.ac {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
z-index: 2 !important;
}
#overlay {
position: absolute;
z-index: 2;
top: 0;
left: 0;
width: 100%;
height:100%;
display: flex;
align-items: center;
justify-content: center;
opacity: 1;
background-color: #000000;
color: #ffffff;
}
#overlay > div {
text-align: center;
}
#overlay > div > button {
height: 20px;
background: transparent;
color: #ffffff;
outline: 1px solid #ffffff;
border: 0;
cursor: pointer;
}
#overlay > div > p {
color: #777777;
font-size: 12px;
}

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>3D</title>
<link rel="stylesheet" href="/games/3d/index.css">
<script src="/games/3d/index.js" defer></script>
<script src="/games/3d/three.js"></script>
</head>
<body>
<div id="3dView"></div>
</body>
</html>

View file

@ -1,122 +0,0 @@
// https://cdnjs.cloudflare.com/ajax/libs/three.js/104/three.js
// https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.2/TweenMax.min.js
let scene, camera, container, GL_Renderer
let materials = {}, lights = {}, objects = {}
let FOV = 75
/*---[ HELPERS ]---*/
function moveObject(object, x, y, z) {
object.position.x += x
object.position.y += y
object.position.z += z
}
function rotateObject(object, x, y, z) {
object.rotateX(x)
object.rotateY(y)
object.rotateZ(z)
}
function setScale(object, scale) {
object.scale.x = object.scale.y = object.scale.z = scale
}
/*---[ EVENTS ]---*/
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
GL_Renderer.setSize(window.innerWidth, window.innerHeight)
}
function Start() {
window.addEventListener("resize", onWindowResize, false)
container = document.getElementById("3dView")
// Scene
{
scene = new THREE.Scene()
scene.background = new THREE.Color(0x000000)
scene.fog = new THREE.Fog(0xffffff, 0, 750)
}
// Camera
{
camera = new THREE.PerspectiveCamera(FOV, window.innerWidth / window.innerHeight, 0.1, 10000)
moveObject(camera, 0, 0, 500)
scene.add(camera)
}
// Lights
{
lights.ambientLight = new THREE.AmbientLight(0x404040, 0.3)
moveObject(lights.ambientLight, 10, 10, 10)
scene.add(lights.ambientLight)
lights.one = new THREE.DirectionalLight(0x00ffff, 0.3)
lights.one.position = camera.position
scene.add(lights.one)
lights.mainLight = new THREE.DirectionalLight(0xaabbff, 0.7)
moveObject(lights.mainLight, 0, 10, 20)
scene.add(lights.mainLight)
}
// Material
{
materials.main = new THREE.MeshPhongMaterial({
color: 0xffffff,
shading: THREE.FlatShading
})
materials.wire = new THREE.MeshPhongMaterial({
color: 0xffffff,
side: THREE.DoubleSide,
wireframe: true
})
}
// Objects
{
objects.rotatingGeo = {}
objects.rotatingGeo.main = new THREE.Mesh(new THREE.IcosahedronGeometry(8, 1), materials.main)
setScale(objects.rotatingGeo.main, 15)
scene.add(objects.rotatingGeo.main)
let outerGeo = new THREE.IcosahedronBufferGeometry(15, 1)
objects.rotatingGeo.outer = new THREE.Mesh(outerGeo, materials.wire)
setScale(objects.rotatingGeo.outer, 10)
scene.add(objects.rotatingGeo.outer)
let vertices = outerGeo.attributes.position.array;
for (let k=0; k<vertices.length; k+=3) {
let vertexSphere = new THREE.Mesh(new THREE.SphereGeometry(0.3, 5, 5), materials.main);
vertexSphere.applyMatrix(new THREE.Matrix4().makeTranslation(vertices[k],vertices[k+1],vertices[k+2]));
objects.rotatingGeo.outer.add(vertexSphere);
}
}
// Renderer
{
GL_Renderer = new THREE.WebGLRenderer({antialias: true, alpha: true })
GL_Renderer.setPixelRatio((window.devicePixelRatio) ? window.devicePixelRatio : 1)
GL_Renderer.setSize(window.innerWidth, window.innerHeight)
GL_Renderer.autoClear = false
GL_Renderer.setClearColor(0x000000, 0.0)
container.appendChild(GL_Renderer.domElement)
}
}
function Update() {
requestAnimationFrame(Update)
rotateObject(objects.rotatingGeo.main, 0.002, 0.003, 0)
rotateObject(objects.rotatingGeo.outer, 0.001, 0.003, 0)
GL_Renderer.render(scene, camera)
}
window.onload = () => {
Start()
Update()
}

File diff suppressed because one or more lines are too long

View file

@ -1,3 +0,0 @@
User-agent: *
Allow: /
Sitemap: /sitemap.xml

@ -1 +0,0 @@
Subproject commit 645cffa7a885409f6959a0263410015c1c486c30

1
source/.eslintignore Normal file
View file

@ -0,0 +1 @@
node_modules/

47
source/.eslintrc Normal file
View file

@ -0,0 +1,47 @@
{
"extends": [
"plugin:react/recommended",
"plugin:json/recommended",
"prettier"
],
"settings": {
"node": {
"tryExtensions": [".js", ".jsx", ".json"]
},
"react": {
"version": "17.0"
}
},
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"sourceType": "module"
},
"plugins": ["react", "@typescript-eslint"],
"rules": {
"react/jsx-uses-vars": "error",
"react/no-unknown-property": [
"error",
{
"ignore": [
"class",
"onclick",
"onload",
"onsubmit",
"crossorigin"
]
}
],
"react/react-in-jsx-scope": ["off"],
"react/prop-types": ["off"],
"react/display-name": ["off"],
"react/jsx-key": ["off"],
"react/jsx-no-target-blank": [
"error",
{
"allowReferrer": true
}
]
}
}

73
source/generate.ts Normal file
View file

@ -0,0 +1,73 @@
import fs from "fs" // read and write files
import path from "path" // get relative path
import matter from "gray-matter" // parse markdown metadata
import createDOMPurify from "dompurify" // sanitize result html
import { JSDOM } from "jsdom" // create empty window for fom purifier to work. Morea info here: https://github.com/cure53/DOMPurify
import toc from "markdown-toc" // table of contents generation
const window = new JSDOM("").window
const DOMPurify = createDOMPurify(window)
const dirPath = "./markdown" // where it will look for markdown documents
const outPath = "./src/pages.json" // path to the json database
const removeExceptionArray = ["content", "meta"] // gray-matter creates unnecessary properties
let pageList: any = {} // data that will be converted to JSON string
// big brain recursive function
// only supports folders and files (no symbolic links)
// does not scale well for large amount of folders and files
function addFiles(filesPath: string) {
// ignore if file/directory name starts with a underscore
let fileOrFolderName = filesPath.substring(filesPath.lastIndexOf("/") + 1)
if (fileOrFolderName.startsWith("_")) return
// not perfect. Some filenames might cause problem.
let stats = fs.lstatSync(filesPath) // checks if the path leads to a directory or a file
let urlPath = `/${path.relative(dirPath, filesPath)}` // path tha will be used for url
.replace(/\.[^/.]+$/, "") // remove .md file extension
.replaceAll(" ", "-") // replace space with a dash "-"
// if it's a directory, apply this function to every files/folders in it
// if it's a file, read and add it to pageList
if (stats.isDirectory()) {
fs.readdirSync(filesPath).map((child) =>
addFiles(`${filesPath}/${child}`)
)
} else if (stats.isFile()) {
// skip if file is not a markdown file
if (!fileOrFolderName.endsWith(".md")) {
console.log(`Ignoring non markdown file at: ${filesPath}`)
return
}
pageList[urlPath] = matter(fs.readFileSync(filesPath, "utf8")) // parse markdown metadata
// sanitizing should happens here but this code removes blockquote for some reason
// I might have to take a look at https://github.com/cure53/DOMPurify/issues/186 later
// pageList[urlPath].content = DOMPurify.sanitize(
// pageList[urlPath].content
// )
pageList[urlPath].meta = pageList[urlPath].data // change property name from data to meta
pageList[urlPath].meta.toc = toc(pageList[urlPath].content).content
// removes unnecessary data
Object.keys(pageList[urlPath]).forEach(
(key) =>
removeExceptionArray.includes(key) ||
delete pageList[urlPath][key]
)
}
}
// start recursive function + check if it's a directory
if (fs.lstatSync(dirPath).isDirectory()) {
addFiles(dirPath)
} else {
console.log("Path is not a directory. Result file will be empty.")
}
// write to json file
fs.writeFileSync(outPath, JSON.stringify(pageList) + "\n")

View file

@ -0,0 +1,10 @@
---
title:
comment:
licenses:
widgets:
article:
author:
---
Put something here

16
source/markdown/about.md Normal file
View file

@ -0,0 +1,16 @@
---
title: About
author: developomp
date: April 20, 2021
---
About page
- about me
- email: developomp@gmail.com
- discord: developomp#0001 (yes I have nitro)
- [github profile](https://github.com/developomp)
- me as a person
- [goals](/goals)
- [Portfolio](/portfolio)

View file

@ -0,0 +1,25 @@
---
title: guide to arch linux
author: developomp
date: May 13, 2021
---
# Guide to Arch Linux
## Why arch linux?
## Getting started
### Philosophy
### Arch wiki
### Command line
## Installation
## display manager
## window manager
# Conclusion

View file

@ -0,0 +1,6 @@
학교로 갔다
집으로 왔다
일을 한다
죽었다
나는 죽었다
나는 죽었다

9
source/markdown/games.md Normal file
View file

@ -0,0 +1,9 @@
---
title: games
date: Aug 16, 2020
author: developomp
---
- [TicTacToe](/games/tictactoe)
- [pong](/games/pong)
- [click](/games/click)

17
source/markdown/goals.md Normal file
View file

@ -0,0 +1,17 @@
---
title: goals
date: May 11, 2021
author: developomp
---
- skill
- type 400 letters per minute (both english and korean)
- milestone
- make a high quality video with at least 1M views on YouTube
- 1000 star on a gh repository
- completely switch to RISC based CPU powered laptop
- project
- create fully functional discord clone from scratch
- make a multiplayer game that can pay for itself
- assemble my own linux distro
- assemble my own mechanical keyboard

View file

@ -1,7 +1,8 @@
--- ---
title: Quote NO.1 title: Quote NO.1
date: 2020-08-16 date: Aug 16, 2020
tags: quotes tags: quotes
author: developomp
--- ---
> "Get the fuck out of my lawn" > "Get the fuck out of my lawn"

View file

@ -1,7 +1,8 @@
--- ---
title: Quote NO.2 title: Quote NO.2
date: 2021-02-20 date: Feb 20, 2021
tags: quotes tags: quotes
author: developomp
--- ---
In a Q&A session in Aalto Talk with Linus Torvalds, hosted by Aalto Center for Entrepreneurship (ACE) in Otaniemi. In a Q&A session in Aalto Talk with Linus Torvalds, hosted by Aalto Center for Entrepreneurship (ACE) in Otaniemi.
@ -9,6 +10,6 @@ In a Q&A session in Aalto Talk with Linus Torvalds, hosted by Aalto Center for E
<div style="padding: 56.25% 0px 0px; position: relative;"><iframe src="https://www.youtube.com/embed/MShbP3OpASA?cc_load_policy=1&end=3005&iv_load_policy=3&rel=0&start=2993" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen scrolling="no" style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%;"></iframe></div> <div style="padding: 56.25% 0px 0px; position: relative;"><iframe src="https://www.youtube.com/embed/MShbP3OpASA?cc_load_policy=1&end=3005&iv_load_policy=3&rel=0&start=2993" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen scrolling="no" style="position: absolute; top: 0px; left: 0px; width: 100%; height: 100%;"></iframe></div>
<br> <br>
>"Nvidia, Fuck you!" > "Nvidia, Fuck you!"
<div style="text-align: right"> <i>- Linus Torvalds (2012)</i> </div> <div style="text-align: right"> <i>- Linus Torvalds (2012)</i> </div>

View file

@ -1,7 +1,8 @@
--- ---
title: Quote NO.3 title: Quote NO.3
date: 2021-03-18 date: March 18, 2021
tags: quotes tags: quotes
author: developomp
--- ---
In the introduction of one of his book: "The Future of the mind" (9th paragraph) In the introduction of one of his book: "The Future of the mind" (9th paragraph)

View file

@ -0,0 +1,15 @@
---
title: My Quote NO.1
date: March 22, 2021
tags: quotes
author: developomp
---
> Let's find problems in ourselves first
<div style="text-align: right"> <i>- developomp 2019</i> </div>
To fix a problem, one should first understand the problem.
If one tries to fix what is not the problem, it will make the problem worse, or make another problem.
And the first place to look for problems is not other than ourselves.
Because often times, solution to our problems turns out to be, or in ourselves.<br>

10
source/markdown/quotes/me/10.md Executable file
View file

@ -0,0 +1,10 @@
---
title: My Quote NO.10
date: March 22, 2021
tags: quotes
author: developomp
---
> Don't forget what you planned to be
<div style="text-align: right"> <i>- developomp 2019</i> </div>

10
source/markdown/quotes/me/11.md Executable file
View file

@ -0,0 +1,10 @@
---
title: My Quote NO.11
date: March 22, 2021
tags: quotes
author: developomp
---
> Yesterday is a lecture for today
<div style="text-align: right"> <i>- developomp 2019</i> </div>

10
source/markdown/quotes/me/12.md Executable file
View file

@ -0,0 +1,10 @@
---
title: My Quote NO.12
date: March 22, 2021
tags: quotes
author: developomp
---
> Practice isn't a action. Its a formation.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

10
source/markdown/quotes/me/13.md Executable file
View file

@ -0,0 +1,10 @@
---
title: My Quote NO.13
date: March 22, 2021
tags: quotes
author: developomp
---
> Don't forget the peaks and the valleys of your life.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

12
source/markdown/quotes/me/14.md Executable file
View file

@ -0,0 +1,12 @@
---
title: My Quote NO.14
date: March 22, 2021
tags: quotes
author: developomp
---
> Those who see only the present lose their future.<br />
> Those who see only the future lose both the present and the future. <br />
> Only those who can see both the present and the future are given the future.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

10
source/markdown/quotes/me/15.md Executable file
View file

@ -0,0 +1,10 @@
---
title: My Quote NO.15
date: March 22, 2021
tags: quotes
author: developomp
---
> The depth of a proverb is proportional to the depth of the reader's thoughts.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

10
source/markdown/quotes/me/16.md Executable file
View file

@ -0,0 +1,10 @@
---
title: My Quote NO.16
date: March 22, 2021
tags: quotes
author: developomp
---
> Words of wisdom deepens the more you think about it.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

10
source/markdown/quotes/me/17.md Executable file
View file

@ -0,0 +1,10 @@
---
title: My Quote NO.17
date: March 22, 2021
tags: quotes
author: developomp
---
> God didn't bless us with the best, so let's do it ourself.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

11
source/markdown/quotes/me/18.md Executable file
View file

@ -0,0 +1,11 @@
---
title: My Quote NO.18
date: March 22, 2021
tags: quotes
author: developomp
---
> I got a purpose now, so why sit down?<br>
> I got ceilings to break and things to do.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

10
source/markdown/quotes/me/19.md Executable file
View file

@ -0,0 +1,10 @@
---
title: My Quote NO.19
date: March 22, 2021
tags: quotes
author: developomp
---
> Finding the problem is the first step to solving anything
<div style="text-align: right"> <i>- developomp 2019</i> </div>

View file

@ -0,0 +1,10 @@
---
title: My Quote NO.2
date: March 22, 2021
tags: quotes
author: developomp
---
> Don't be great for your fame, but be famous for your greatness.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

11
source/markdown/quotes/me/20.md Executable file
View file

@ -0,0 +1,11 @@
---
title: My Quote NO.20
date: March 22, 2021
tags: quotes
author: developomp
---
> Look at the clock and wait for the next minute to come.<br>
> You'll see the preciousness of time.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

11
source/markdown/quotes/me/21.md Executable file
View file

@ -0,0 +1,11 @@
---
title: My Quote NO.21
date: March 22, 2021
tags: quotes
author: developomp
---
> Kill an ant. Throw it and try to find it.<br>
> That's how almost all life ended. Forgotten.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

10
source/markdown/quotes/me/22.md Executable file
View file

@ -0,0 +1,10 @@
---
title: My Quote NO.22
date: March 22, 2021
tags: quotes
author: developomp
---
> Lot of things learned, nothing useful.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

11
source/markdown/quotes/me/23.md Executable file
View file

@ -0,0 +1,11 @@
---
title: My Quote NO.23
date: March 22, 2021
tags: quotes
author: developomp
---
> To give 10, one should know a 100.
> So when someone gives a 10, don't think he's in the same level as you.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

10
source/markdown/quotes/me/24.md Executable file
View file

@ -0,0 +1,10 @@
---
title: My Quote NO.24
date: March 22, 2021
tags: quotes
author: developomp
---
> Think about everything
<div style="text-align: right"> <i>- developomp 2019</i> </div>

View file

@ -0,0 +1,10 @@
---
title: My Quote NO.25
date: March 22, 2021
tags: quotes
author: developomp
---
> Challenge yourself to give your best at all time.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

View file

@ -0,0 +1,10 @@
---
title: My Quote NO.26
date: March 22, 2021
tags: quotes
author: developomp
---
> Escape from the valleys of life doesn't happen in an instant.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

View file

@ -0,0 +1,13 @@
---
title: My Quote NO.27
date: March 22, 2021
tags: quotes
author: developomp
---
> Sometimes I am amazed by the fact that I am aware of anything.
<div style="text-align: right"> <i>- developomp 2019</i> </div>
Learning about AI
This folded sheet of protein is capable to understand the laws that govern the universe

View file

@ -0,0 +1,10 @@
---
title: My Quote NO.28
date: March 22, 2021
tags: quotes
author: developomp
---
> Mind is like a sword. It will be dull if you stop sharpening it.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

View file

@ -0,0 +1,10 @@
---
title: My Quote NO.29
date: March 22, 2021
tags: quotes
author: developomp
---
> Even if the day comes when we can live for hundreds of years, we'll still make a world where hard working is a necessity.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

View file

@ -0,0 +1,10 @@
---
title: My Quote NO.3
date: March 22, 2021
tags: quotes
author: developomp
---
> If you have a proverbs, record it. Treat it as if it's a jewel. In the future, this fine gem will be the eyes of many, and a lamp to light the ways of people.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

View file

@ -0,0 +1,10 @@
---
title: My Quote NO.30
date: March 22, 2021
tags: quotes
author: developomp
---
> If you think too much about the answer, you'll forget what the question was.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

View file

@ -0,0 +1,10 @@
---
title: My Quote NO.31
date: March 22, 2021
tags: quotes
author: developomp
---
> People earns highest respect from me are those who appreciate critiques.
<div style="text-align: right"> <i>- developomp 2020</i> </div>

View file

@ -0,0 +1,10 @@
---
title: My Quote NO.32
date: May 10, 2021
tags: quotes
author: developomp
---
> Any field is fascinating as long as there are no exams.
<div style="text-align: right"> <i>- developomp 2021</i> </div>

View file

@ -0,0 +1,15 @@
---
title: My Quote NO.4
date: March 22, 2021
tags: quotes
author: developomp
---
> I don't want to call it learning that I didn't learn with my heart when I learn.
<div style="text-align: right"> <i>- developomp 2019</i> </div>
When we learn in school, we systematically memorize and recite information and immediately forget everything after an exam.
Some of us may remember some of it, but most of us don't remember most of the information we were taught.
I don't want to call that learning. Learning for me is when I know that topic of that subject by heart.
Something that you don't just get information, but the spirit of it too.

View file

@ -0,0 +1,10 @@
---
title: My Quote NO.5
date: March 22, 2021
tags: quotes
author: developomp
---
> Don't define anything different from normality as a failure.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

View file

@ -0,0 +1,10 @@
---
title: My Quote NO.6
date: March 22, 2021
tags: quotes
author: developomp
---
> What did you do when everyone in the world ran?
<div style="text-align: right"> <i>- developomp 2019</i> </div>

11
source/markdown/quotes/me/7.md Executable file
View file

@ -0,0 +1,11 @@
---
title: My Quote NO.7
date: March 22, 2021
tags: quotes
author: developomp
---
> The 1000 miles you've walked so far are not important. What's important is
> that you still have the will to walk another mile.
<div style="text-align: right"><i>- developomp 2019</i></div>

15
source/markdown/quotes/me/8.md Executable file
View file

@ -0,0 +1,15 @@
---
title: My Quote NO.8
date: March 22, 2021
tags: quotes
author: developomp
---
> Out of all the thing you've done and haven't done, which one do you regret more?
<div style="text-align: right"> <i>- developomp 2019</i> </div>
Many people regret not doing something
...
To them I want to ask this one question:
"So, what are the things you need to do now?"

10
source/markdown/quotes/me/9.md Executable file
View file

@ -0,0 +1,10 @@
---
title: My Quote NO.9
date: March 22, 2021
tags: quotes
author: developomp
---
> People who don't know what they're talking about are the poorest people in the world.
<div style="text-align: right"> <i>- developomp 2019</i> </div>

82
source/package.json Normal file
View file

@ -0,0 +1,82 @@
{
"name": "developomp-site",
"version": "1.0.0",
"description": "website source for https://developomp.com",
"author": "developomp <developomp@gmail.com>",
"homepage": ".",
"repository": "https://github.com/developomp/developomp-site.git",
"bugs": {
"url": "https://github.com/developomp/developomp-site/issues"
},
"private": true,
"license": "MIT",
"scripts": {
"generate": "ts-node -O '{\"module\":\"commonjs\"}' ./generate.ts",
"start": "yarn generate && react-scripts start",
"build": "yarn generate && react-scripts build",
"test": "yarn generate && react-scripts test",
"pretty": "yarn generate && prettier --write ./source"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-brands-svg-icons": "^5.15.3",
"@fortawesome/free-regular-svg-icons": "^5.15.3",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/react-fontawesome": "^0.1.14",
"@testing-library/jest-dom": "^5.12.0",
"@testing-library/react": "^11.2.6",
"@testing-library/user-event": "^13.1.8",
"@types/jest": "^26.0.23",
"@types/react": "^17.0.5",
"@types/react-dom": "^17.0.4",
"dompurify": "^2.2.8",
"gray-matter": "^4.0.3",
"local-storage-fallback": "^4.1.2",
"markdown-toc": "^1.2.0",
"marked": "^2.0.3",
"react": "^17.0.2",
"react-burger-menu": "^3.0.6",
"react-dom": "^17.0.2",
"react-helmet": "^6.1.0",
"react-router-dom": "^5.2.0",
"react-scripts": "^4.0.3",
"react-spinners": "^0.10.6",
"react-tooltip": "^4.2.19",
"styled-components": "^5.3.0",
"styled-theming": "^2.2.0",
"web-vitals": "^1.1.2"
},
"devDependencies": {
"@types/node": "^15.0.2",
"@types/styled-components": "^5.1.9",
"@types/styled-theming": "^2.2.5",
"@typescript-eslint/eslint-plugin": "^4.23.0",
"@typescript-eslint/parser": "^4.23.0",
"eslint": "^7.26.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-json": "^3.0.0",
"eslint-plugin-react": "^7.23.2",
"prettier": "^2.3.0",
"ts-node": "^9.1.1",
"tslint-config-prettier": "^1.18.0",
"typescript": "^4.2.4"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

8
source/src/App.test.tsx Normal file
View file

@ -0,0 +1,8 @@
import { render } from "@testing-library/react"
import App from "./App"
test("renders content", () => {
const { getByTestId } = render(<App />)
const content = getByTestId("content")
expect(content).toBeInTheDocument()
})

212
source/src/App.tsx Normal file
View file

@ -0,0 +1,212 @@
import { BrowserRouter as Router, Switch, Route } from "react-router-dom"
import { ThemeProvider, createGlobalStyle, css } from "styled-components"
import storage from "local-storage-fallback"
import { useState, useEffect } from "react"
import theme from "styled-theming"
import Loader from "react-spinners/HashLoader"
import theming from "./theming"
import Navbar from "./components/Navbar"
import Footer from "./components/Footer"
import Home from "./pages/home"
import Page from "./pages/page"
import NotFound from "./pages/notfound"
import Portfolio from "./pages/portfolio"
// Theme that will be used throughout the website
const GlobalStyle = createGlobalStyle`
body {
overflow-x: hidden;
overflow-y: scroll;
}
html, body, #root {
min-height: 100vh;
margin: 0;
display: flex;
flex-flow: column;
background-color: ${theme("mode", {
light: theming.light.backgroundColor1,
dark: theming.dark.backgroundColor1,
})};
color: ${theme("mode", {
light: theming.light.color1,
dark: theming.dark.color1,
})};
font-size: ${theming.size.medium};
font-family: ${theming.font.regular};
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
body::-webkit-scrollbar {
width: ${theming.size.x_small};
}
body::-webkit-scrollbar-track {
border-radius: ${theming.size.x2_small};
background: rgba(0,0,0,0.06);
box-shadow: inset 0 0 5px rgb(0 0 0 / 10%);
}
body::-webkit-scrollbar-thumb {
border-radius: ${theming.size.x2_small};
background: rgba(0,0,0,0.1);
box-shadow: inset 0 0 10px rgb(0 0 0 / 20%);
}
#content {
display:inline-block;
flex: 1 1 auto;
margin-bottom: 3rem;
}
code {
font-family: ${theming.font.code};
}
.link-color a {
text-decoration: none;
color: ${theming.color.linkColor};
&:visited {
color: ${theming.color.linkColor};
}
}
p {
line-height: 1.5rem;
}
blockquote {
background-color: rgba(0, 0, 0, 5%);
border-left: 0.4rem solid rgba(0, 0, 0, 10%);
padding-top: 0.1rem;
padding-right: 1rem;
padding-bottom: 0.1rem;
padding-left: 1.5rem;
}
.card {
margin: auto;
background-color: ${theme("mode", {
light: "white",
dark: "#2F3136",
})};
padding: 2rem;
border-radius: 6px;
box-shadow: 0 4px 10px rgb(0 0 0 / 5%), 0 0 1px rgb(0 0 0 / 10%);
@media screen and (max-width: ${theming.size.screen_size1}) {
& {
width: 100%;
}
}
}
.main-content {
margin-top: 3rem;
width: 50%;
@media screen and (max-width: ${theming.size.screen_size1}) {
& {
width: 70%;
}
}
}
* {
transition: color 0.1s linear;
}
`
// the loader is not compatible with styled-components so I'm converting it to string.
// doing this gives intellisense and stuff in my IDE
const LoaderStyle = css`
position: absolute;
top: 0%;
left: 50%;
transform: translate(-50%, 50%);
`.toString()
function App() {
const [usingTheme, _setTheme] = useState(() => {
const savedTheme = storage.getItem("theme")
return savedTheme ? JSON.parse(savedTheme) : { mode: "dark" }
})
useEffect(() => {
storage.setItem("theme", JSON.stringify(usingTheme))
}, [usingTheme])
const [isLoading, setLoading] = useState(true)
// show loading screen until all fonts are loaded.
// Experimental feature. Not fully supported on all browsers (ehem IE ehem).
// https://developer.mozilla.org/en-US/docs/Web/API/FontFaceSet
useEffect(() => {
// checks if document.fonts.onloadingdone is supported on the browser
if (typeof document.fonts.onloadingdone != undefined) {
document.fonts.onloadingdone = (_: EventListener) => {
setLoading(false)
}
} else {
setLoading(false)
}
}, [])
return (
<ThemeProvider
theme={{
...usingTheme,
setTheme: ({ setTheme, ...theme }) => _setTheme(theme),
}}
>
<GlobalStyle />
<Router>
<Navbar />
<div id="content">
{isLoading ? (
<Loader
color={
usingTheme.mode == "light"
? theming.light.color1
: theming.dark.color1
}
css={LoaderStyle}
size={200}
/>
) : (
<Switch>
<Route
exact
path="/"
component={() => (
<Home howMany={4} title="Home" />
)}
/>
<Route
exact
path="/archives"
component={() => <Home title="Archives" />}
/>
<Route
exact
path="/portfolio"
component={Portfolio}
/>
<Route exact path="/404" component={NotFound} />
<Route exact path="/:path*" component={Page} />
</Switch>
)}
</div>
<Footer />
</Router>
</ThemeProvider>
)
}
export default App

View file

@ -0,0 +1,66 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faGithub } from "@fortawesome/free-brands-svg-icons"
import styled from "styled-components"
import theme from "styled-theming"
import { HashRouter as Router, Link } from "react-router-dom"
const StyledFooter = styled.footer`
display: flex;
justify-content: space-between;
margin-bottom: 1px; /* footer goes outside the page by 1 px for some reason */
padding: 50px 10px;
background-color: white;
background-color: ${theme("mode", {
light: "white",
dark: "black",
})};
color: ${theme("mode", {
light: "black",
dark: "white",
})};
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.logo {
color: gray;
}
`
const StyledLink = styled.a`
width: 30px;
font-size: 2rem;
color: ${theme("mode", {
light: "lightgrey",
dark: "grey",
})};
&:hover {
color: ${theme("mode", {
light: "black",
dark: "white",
})};
}
`
function Footer() {
return (
<StyledFooter>
<div className="logo">
Copyright &copy; <strong>develo</strong>pomp
</div>
<Router className="icons">
<StyledLink
href="https://github.com/developomp/developomp-site"
target="_blank"
>
<FontAwesomeIcon icon={faGithub} />
</StyledLink>
</Router>
</StyledFooter>
)
}
export default Footer

View file

@ -0,0 +1,100 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faGithub } from "@fortawesome/free-brands-svg-icons"
import styled, { ThemeConsumer } from "styled-components"
import theme from "styled-theming"
import ReactTooltip from "react-tooltip"
import NavbarData from "../data/NavbarData"
import theming from "../theming"
import { Link } from "react-router-dom"
import SearchBox from "./SearchBox"
import Sidebar from "./Sidebar"
import ThemeToggleButton from "./ThemeToggleButton"
import { faLanguage } from "@fortawesome/free-solid-svg-icons"
const StyledNav = styled.nav`
display: flex;
align-items: center;
height: 2rem;
margin: 0;
padding: 1rem;
background-color: ${theme("mode", {
light: theming.light.backgroundColor0,
dark: theming.dark.backgroundColor0,
})};
color: ${theme("mode", {
light: theming.light.color0,
dark: theming.dark.color0,
})};
box-shadow: 0 4px 10px rgb(0 0 0 / 5%);
.right {
margin-left: auto;
}
`
const StyledNavLinks = styled.div`
@media only screen and (max-width: ${theming.size.screen_size1}) {
display: none;
}
`
const StyledImg = styled.img`
height: 2rem;
margin: 1rem;
`
const StyledLink = styled(Link)`
${theming.styles.navbarButtonStyle}
`
const StyledALink = styled.a`
${theming.styles.navbarButtonStyle}
`
function Navbar() {
return (
<StyledNav>
<Link to="/">
<StyledImg
src={process.env.PUBLIC_URL + "/icon/icon_circle.svg"}
/>
</Link>
<StyledNavLinks>
{NavbarData.map((item, index) => {
return (
<StyledLink key={index} to={item.path}>
{item.title}
</StyledLink>
)
})}
</StyledNavLinks>
<ThemeToggleButton />
<StyledALink data-tip data-for="language">
<FontAwesomeIcon icon={faLanguage} />
</StyledALink>
<ReactTooltip id="language" type="dark" effect="solid">
<span>Change to Korean/English</span>
</ReactTooltip>
<StyledALink
data-tip
data-for="github"
href="https://github.com/developomp/developomp-site"
target="_blank"
>
<FontAwesomeIcon icon={faGithub} />
</StyledALink>
<ReactTooltip id="github" type="dark" effect="solid">
<span>View source code</span>
</ReactTooltip>
<SearchBox />
<Sidebar />
</StyledNav>
)
}
export default Navbar

View file

@ -0,0 +1,51 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faSearch } from "@fortawesome/free-solid-svg-icons"
import styled, { ThemeConsumer, css } from "styled-components"
import theme from "styled-theming"
const StyledSearchBoxContainer = styled.div`
display: flex;
justify-content: left;
align-items: center;
background-color: ${theme("mode", {
light: "white",
dark: "#202225",
})};
color: ${theme("mode", {
light: "black",
dark: "#CFD0D0",
})};
&:hover {
background-color: ${theme("mode", {
light: "whitesmoke",
dark: "#36393F",
})};
}
`
const StyledSearchBox = styled.input`
width: 80%;
border: none;
border-right: 1rem;
outline: none;
padding: 10px 10px;
text-decoration: none;
background-color: inherit;
color: inherit;
`
const StyledSearchButton = styled(FontAwesomeIcon)`
cursor: pointer;
`
function Navbar() {
return (
<StyledSearchBoxContainer>
<StyledSearchBox type="text" name="search" placeholder="Search" />
<StyledSearchButton icon={faSearch} />
</StyledSearchBoxContainer>
)
}
export default Navbar

View file

@ -0,0 +1,124 @@
import { useEffect, useState } from "react"
import styled, { css } from "styled-components"
import NavbarData from "../data/NavbarData"
import theme from "styled-theming"
import ReactTooltip from "react-tooltip"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faEllipsisV, faTimes } from "@fortawesome/free-solid-svg-icons"
import theming from "../theming"
import SubMenu from "./SubMenu"
interface StateProps {
isSidebarOpen: boolean
}
const CommonSidebarToggleButtonStyle = css`
${theming.styles.navbarButtonStyle}
font-size: "1.5rem";
width: 1.5rem;
text-align: center;
cursor: pointer;
margin: 0.1rem;
@media only screen and (min-width: ${theming.size.screen_size1}) {
display: none;
}
`
const StyledToggleSidebarButton = styled.div`
${CommonSidebarToggleButtonStyle}
`
const StyledToggleSidebarButton2 = styled.div`
${CommonSidebarToggleButtonStyle}
border-radius: 0;
margin: auto;
width: 90%;
height: 2rem;
font-size: 1.1rem;
`
const StyledOverlay = styled.div<StateProps>`
display: ${(props) => (props.isSidebarOpen ? "block" : "none")};
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 20;
transition-property: opacity;
background-color: rgba(0, 0, 0, 25%);
* {
overflow: scroll;
}
`
const SidebarNav = styled.nav<StateProps>`
width: 250px;
height: 100vh;
display: flex;
justify-content: center;
position: fixed;
top: 0;
right: ${(props) => (props.isSidebarOpen ? "0" : "-100%")};
transition: 350ms;
z-index: 30;
overflow-x: hidden;
overflow-y: scroll;
background-color: ${theme("mode", {
light: theming.light.backgroundColor0,
dark: theming.dark.backgroundColor0,
})};
color: ${theme("mode", {
light: theming.light.color0,
dark: theming.dark.color0,
})};
`
const SidebarWrap = styled.div`
width: 100%;
`
const Sidebar = () => {
const [isSidebarOpen, setSidebar] = useState(false)
function toggleSidebar() {
setSidebar(!isSidebarOpen)
document.body.style.overflow = isSidebarOpen ? "scroll" : "hidden"
}
return (
<>
<StyledOverlay
isSidebarOpen={isSidebarOpen}
onClick={toggleSidebar}
/>
<StyledToggleSidebarButton
data-tip
data-for="sidebar"
onClick={toggleSidebar}
>
<FontAwesomeIcon icon={faEllipsisV}></FontAwesomeIcon>
<ReactTooltip id="sidebar" type="dark" effect="solid">
<span>open sidebar</span>
</ReactTooltip>
</StyledToggleSidebarButton>
<SidebarNav isSidebarOpen={isSidebarOpen}>
<SidebarWrap>
<StyledToggleSidebarButton2 onClick={toggleSidebar}>
<FontAwesomeIcon icon={faTimes}></FontAwesomeIcon> Close
</StyledToggleSidebarButton2>
{NavbarData.map((item, index) => {
return <SubMenu item={item} key={index} />
})}
</SidebarWrap>
</SidebarNav>
</>
)
}
export default Sidebar

View file

@ -0,0 +1,74 @@
import { useState } from "react"
import { Link } from "react-router-dom"
import styled from "styled-components"
import theming from "../theming"
const SidebarLink = styled(Link)`
${theming.styles.navbarButtonStyle};
display: flex;
width: 100%;
margin: 0;
border-radius: 0;
justify-content: space-between;
height: 2rem;
align-items: center;
padding: 20px;
list-style: none;
`
const SidebarLabel = styled.span`
margin-left: 16px;
`
const DropdownLink = styled(Link)`
background: #414757;
height: 60px;
padding-left: 3rem;
display: flex;
align-items: center;
text-decoration: none;
color: #f5f5f5;
font-size: 18px;
&:hover {
background: #632ce4;
cursor: pointer;
}
`
function SubMenu({ item }) {
const [isSubNavOpen, setSubNav] = useState(false)
const showSubNav = () => setSubNav(!isSubNavOpen)
return (
<>
<SidebarLink to={item.path} onClick={item.subNav && showSubNav}>
<div>
{item.icon}
<SidebarLabel>{item.title}</SidebarLabel>
</div>
<div>
{item.subNav && isSubNavOpen
? item.iconOpened
: item.subNav
? item.iconClosed
: null}
</div>
</SidebarLink>
{/* not used as of the moment */}
{isSubNavOpen &&
item.subNav.map((item, index) => {
return (
<DropdownLink to={item.path} key={index}>
{item.icon}
<SidebarLabel>{item.title}</SidebarLabel>
</DropdownLink>
)
})}
</>
)
}
export default SubMenu

View file

@ -0,0 +1,50 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faAdjust } from "@fortawesome/free-solid-svg-icons"
import styled, { ThemeConsumer } from "styled-components"
import theme from "styled-theming"
import ReactTooltip from "react-tooltip"
import theming from "../theming"
const StyledThemeButton = styled.div`
${theming.styles.navbarButtonStyle}
transition: transform 0.2s linear;
${theme("mode", {
light: "",
dark: "transform: scaleX(-1);\
-moz-transform: scaleX(-1);\
-webkit-transform: scaleX(-1);\
-ms-transform: scaleX(-1);",
})};
`
function Navbar() {
return (
<ThemeConsumer>
{(_theme) => (
<>
<StyledThemeButton
data-tip
data-for="theme"
className="right"
onClick={(_: any) =>
_theme.setTheme(
_theme.mode === "dark"
? { ..._theme, mode: "light" }
: { ..._theme, mode: "dark" }
)
}
>
<FontAwesomeIcon icon={faAdjust} />
</StyledThemeButton>
<ReactTooltip id="theme" type="dark" effect="solid">
<span>Change theme</span>
</ReactTooltip>
</>
)}
</ThemeConsumer>
)
}
export default Navbar

View file

@ -0,0 +1,42 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import {
faHome,
faArchive,
faUserTie,
faHashtag,
faListUl,
faHiking,
} from "@fortawesome/free-solid-svg-icons"
export default [
{
title: "Home",
path: "/",
icon: <FontAwesomeIcon icon={faHome} />,
},
{
title: "Archives",
path: "/archives",
icon: <FontAwesomeIcon icon={faArchive} />,
},
{
title: "Categories",
path: "/categories",
icon: <FontAwesomeIcon icon={faListUl} />,
},
{
title: "Tags",
path: "/tags",
icon: <FontAwesomeIcon icon={faHashtag} />,
},
{
title: "Explore",
path: "/explore",
icon: <FontAwesomeIcon icon={faHiking} />,
},
{
title: "Portfolio",
path: "/portfolio",
icon: <FontAwesomeIcon icon={faUserTie} />,
},
]

14
source/src/index.tsx Normal file
View file

@ -0,0 +1,14 @@
import React from "react"
import ReactDOM from "react-dom"
import App from "./App"
import reportWebVitals from "./reportWebVitals"
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
)
reportWebVitals()

118
source/src/pages/home.tsx Normal file
View file

@ -0,0 +1,118 @@
import { Link } from "react-router-dom"
import styled from "styled-components"
import theme from "styled-theming"
import marked from "marked"
import Helmet from "react-helmet"
import pages from "../pages.json"
const StyledPostList = styled.div`
padding-top: 2rem;
margin: auto;
text-align: center;
color: ${theme("mode", {
light: "#111111",
dark: "#EEEEEE",
})};
`
const StyledH1 = styled.h1`
margin-bottom: 20px;
font-weight: 500;
margin: 0;
`
const StyledTitle = styled.h1`
font-size: 2rem;
font-style: bold;
`
const StyledLink = styled(Link)`
text-decoration: none;
color: ${theme("mode", {
light: "black",
dark: "white",
})};
&:hover {
text-decoration: underline;
}
`
const StyledPostCard = styled.div`
box-shadow: 0 4px 10px rgb(0 0 0 / 10%);
text-align: left;
margin-bottom: 20px;
padding: 10px 20px;
`
function Home(props) {
let PostCards: Array<any> = []
let howMany = props.howMany
let isLimited = Boolean(howMany)
let h1Text = "All posts"
if (isLimited) {
h1Text = `${howMany} recent posts`
}
for (const pagePath in pages) {
if (isLimited && howMany <= 0) continue
let post = pages[pagePath]
post.title = post.meta?.title ? post.meta.title : "Unknown title"
post.date = post.meta?.date ? post.meta.date : "Unknown date"
post.author = post.meta?.author ? post.meta.author : "Unknown author"
PostCards.push(
<StyledPostCard key={pagePath} className="card main-content">
<StyledTitle>
<StyledLink to={pagePath}>{post.title}</StyledLink>
</StyledTitle>
<small>
Published on {post.date} by {post.author}
</small>
<hr />
<div
className="link-color"
dangerouslySetInnerHTML={{
__html: marked(
post.content.split(" ").slice(0, 20).join(" ") +
"..."
),
}}
></div>
<small>
<StyledLink to={pagePath}>Read more</StyledLink>
</small>
</StyledPostCard>
)
howMany--
}
return (
<>
<Helmet>
<title>pomp | {props.title}</title>
<meta property="og:title" content={props.title} />
<meta property="og:type" content="website" />
<meta property="og:url" content="http://developomp.com" />
<meta
property="og:image"
content="http://developomp.com/icon/icon.svg"
/>
<meta property="og:description" content="" />
</Helmet>
<StyledPostList>
<StyledH1>{h1Text}</StyledH1>
<br />
{PostCards}
</StyledPostList>
</>
)
}
export default Home

View file

@ -0,0 +1,42 @@
import styled from "styled-components"
import theme from "styled-theming"
import Helmet from "react-helmet"
const StyledNotFound = styled.div`
margin: auto;
margin-top: 2rem;
text-align: center;
color: ${theme("mode", {
light: "#111111",
dark: "#EEEEEE",
})};
`
const Styled404 = styled.h1`
font-size: 3rem;
`
function NotFound() {
return (
<>
<Helmet>
<title>pomp | 404</title>
<meta property="og:title" content="Page Not Found" />
<meta property="og:type" content="website" />
<meta property="og:url" content="http://developomp.com" />
<meta
property="og:image"
content="http://developomp.com/icon/icon.svg"
/>
<meta property="og:description" content="Page does not exist" />
</Helmet>
<StyledNotFound className="card main-content">
<Styled404>404</Styled404>
the page you are looking for does not exist. :(
</StyledNotFound>
</>
)
}
export default NotFound

71
source/src/pages/page.tsx Normal file
View file

@ -0,0 +1,71 @@
import marked from "marked"
import NotFound from "./notfound"
import Helmet from "react-helmet"
import pages from "../pages.json"
import { useParams } from "react-router-dom"
function Page() {
const path = `/${useParams().path}`
let fetched = pages[path]
if (!fetched) return <NotFound />
// to prevent wrapping. I don't want to touch prettier stuff
const idk = "Unknown"
fetched.content = fetched?.content ? fetched.content : "No content"
fetched.toc = fetched.meta?.toc ? fetched.meta.toc : undefined
fetched.title = fetched.meta?.title ? fetched.meta.title : "No title"
fetched.date = fetched.meta?.date ? fetched.meta.date : `${idk} date`
fetched.author = fetched.meta?.author
? fetched.meta.author
: `${idk} author`
const TableOfContents = fetched.toc && (
<>
<div className="card">
<strong>Table of Content:</strong>
<div
className="link-color"
dangerouslySetInnerHTML={{
__html: marked(fetched.toc),
}}
></div>
</div>
<hr />
</>
) // add toc if it exists
return (
<>
<Helmet>
<title>pomp | {fetched.title}</title>
<meta property="og:title" content="Page Not Found" />
<meta property="og:type" content="website" />
<meta property="og:url" content="http://developomp.com" />
<meta
property="og:image"
content="http://developomp.com/icon/icon.svg"
/>
<meta property="og:description" content="Page does not exist" />
</Helmet>
<div className="card main-content">
<h2>{fetched.title}</h2>
<small>
Published on {fetched.date} by {fetched.author}
</small>
<hr />
{TableOfContents}
<div
className="link-color"
dangerouslySetInnerHTML={{
__html: marked(fetched.content),
}}
></div>
</div>
</>
)
}
export default Page

View file

@ -0,0 +1,37 @@
import styled from "styled-components"
import theme from "styled-theming"
import Helmet from "react-helmet"
const StyledPortfolio = styled.div``
const StyledH1 = styled.h1`
font-size: 3rem;
`
function Portfolio() {
return (
<>
<Helmet>
<title>pomp | Portfolio</title>
<meta property="og:title" content="developomp's Portfolio" />
<meta property="og:type" content="website" />
<meta property="og:url" content="http://developomp.com" />
<meta
property="og:image"
content="http://developomp.com/icon/icon.svg"
/>
<meta
property="og:description"
content="developomp's Portfolio"
/>
</Helmet>
<StyledPortfolio className="card main-content">
<StyledH1>Portfolio</StyledH1>
My projects
</StyledPortfolio>
</>
)
}
export default Portfolio

6
source/src/react-app-env.d.ts vendored Normal file
View file

@ -0,0 +1,6 @@
/// <reference types="react-scripts" />
declare module "*.md"
interface Document {
[fonts: string]: any
}

View file

@ -0,0 +1,17 @@
import { ReportHandler } from "web-vitals"
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import("web-vitals").then(
({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry)
getFID(onPerfEntry)
getFCP(onPerfEntry)
getLCP(onPerfEntry)
getTTFB(onPerfEntry)
}
)
}
}
export default reportWebVitals

6
source/src/setupTests.ts Normal file
View file

@ -0,0 +1,6 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import "@testing-library/jest-dom"

63
source/src/theming.ts Normal file
View file

@ -0,0 +1,63 @@
/** theming.ts
* stores values that are used across
* It makes changing values easier
*/
import theme from "styled-theming"
import { css } from "styled-components"
export default {
font: {
regular: "'Noto Sans KR', sans-serif",
code: "'Source Code Pro', monospace",
},
size: {
x2_small: "3px",
x_small: "8px",
small: 0,
medium: "14px",
large: 0,
x_large: 0,
screen_size1: "950px",
},
color: {
linkColor: "#3273dc",
},
dark: {
backgroundColor0: "#202225",
backgroundColor1: "#36393F",
color0: "#FFFFFF",
color1: "#EEEEEE",
},
light: {
backgroundColor0: "#FFFFFF",
backgroundColor1: "#F7F7F7",
color0: "#000000",
color1: "#111111",
},
styles: {
navbarButtonStyle: css`
cursor: pointer;
font-size: 1em;
border-radius: 0.5rem;
float: left;
padding: 14px 16px;
text-decoration: none;
margin: 0.1em;
color: ${theme("mode", {
light: "black",
dark: "#CFD0D0",
})};
background-color: ${theme("mode", {
light: "white",
dark: "#202225",
})};
&:hover {
background-color: ${theme("mode", {
light: "lightgrey",
dark: "#36393F",
})};
}
`,
},
}

21
source/tsconfig.json Normal file
View file

@ -0,0 +1,21 @@
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": false,
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["src/**/*", "generate.ts"]
}