diff --git a/.gitignore b/.gitignore index 129e907..d1fa58e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /data /src/web/lang/en_CAT +/src/public/css/* diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1e30e2c --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ + +MIXINS = $(shell find src/scss -name "_*.scss") +SCSS = $(shell find src/scss -name "*.scss" -not -name "_*") +CSS = $(patsubst src/scss/%.scss,src/public/css/%.css,$(SCSS)) + +.PHONY: all clean css + +all: clean css + +clean: + @# clean scss + @printf "\033[31m RM \033[0m%s\n" src/public/css + @rm -fr src/public/css/* + +# =============================================== COMPILE SCSS == + +css: $(CSS) + +$(CSS): src/public/css/%.css : src/scss/%.scss $(MIXINS) + @printf "\033[33m SCSS \033[0m%s\n" $< + @mkdir -p $(@D) + @sassc --style compressed $< $@ diff --git a/build/stamp.sh b/build/stamp.sh new file mode 100644 index 0000000..3b19b04 --- /dev/null +++ b/build/stamp.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +out="./src/web/stamp.php" +public="./src/public" +files=$(find "$public" -type f -printf %P\\n) + +printf " "$out" +for file in $files; do + stamp=$(date +%s -r "$public/$file") + echo "\$__stamps['public/$file'] = $stamp;" >> "$out"; +done +echo "define('FILE_TIMES', \$__stamps);" >> "$out" +echo "unset(\$__stamps);" >> "$out" + diff --git a/src/public/css/common.css b/src/public/css/common.css deleted file mode 100644 index b941b1b..0000000 --- a/src/public/css/common.css +++ /dev/null @@ -1,644 +0,0 @@ -:root { - --white: #E4E6EB; - --blue: #1778f2; - --red: #f02849; - --green: #30ab5a; - - --blue-alt: #1D85FC; - --green-alt: #39B463; - - --font: Helvetica; -} - -:root { - --base :#18191A; - --surface0: #242526; - --surface1: #3A3B3C; - --surface2: #4E4F50; - - --text: #E4E6EB; - --subtext: #B0B3B8; - --btntext: #E4E6EB; -} - -/** -:root { - --base: #f0f2f5; - --surface0: #ffffff; - --surface1: #f0f2f5; - --surface2: #dadde1; - - --text: #000000; - --subtext: #1d2129; - --btntext: #606770; -} -*/ - -@font-face { - font-family: 'Helvetica Neue'; - font-style: normal; - src: url("/public/font/helvetica-neue.otf") format("opentype"); - font-display: swap; -} - -@font-face { - font-family: 'Material Icons'; - font-style: normal; - font-weight: 400; - src: url("/public/font/material-icons.ttf") format('truetype'); -} - -@font-face { - font-family: facebook; - src: url("/public/font/facebook.otf") format("opentype"); - font-display: swap; -} - -@font-face { - font-family: sfpro; - src: url("/public/font/sfpro.otf") format("opentype"); - font-display: swap; -} - -body { - background-color: var(--surface0); - width: 100%; - height: 100%; - margin: 0; - padding: 0; - display: flex; - flex-direction: column; - color: var(--text); - font-family: var(--font); -} - -#main-content { - background-color: var(--base); - padding-top: 1rem; -} - -header { - top: 0; - position: sticky; - height: 3.5rem; - background-color: var(--surface0); - display: flex; - flex-direction: row; - align-items: center; - padding: 0 1rem; - border-bottom: 1px solid var(--surface1); -} - -header .logo { - font-family: facebook; - color: var(--blue); - font-size: 2.25rem; - height: 100%; - line-height: 2rem; - margin-top: .75rem; -} - -footer { - text-align: center; - padding: 1rem; - color: var(--subtext); - font-size: .75rem; -} - -hr { - color: var(--surface2); - background-color: var(--surface2); - width: 100%; - height: 1px; - border: none; -} - -a, button, input, div { - box-sizing: border-box; -} - -a, button, input { - background: none; - border: none; - color: inherit; -} - -a, button { - cursor: pointer; -} - -.btn { - color: var(--btntext); - display: flex; - align-items: center; - align-content: center; - flex-direction: row; - font-weight: bold; - font-size: 1rem; - text-decoration: none; - - padding: .4rem .6rem; - border-radius: .25rem; - background-color: transparent; - width: fit-content; -} - -.btn:hover { - background-color: var(--surface1); -} - -.btn-alt { - background-color: var(--surface1); -} - -.btn-alt:hover { - background-color: var(--surface2); -} - -.btn-alt.btn-blue { - background-color: var(--blue); - color: var(--white); -} - -.btn-alt.btn-blue:hover { - background-color: var(--blue-alt); -} - -.btn-wide { - width: auto; - flex-grow: 1; - justify-content: center; -} - -.btn-line:hover { - background-color: inherit; - text-decoration: underline; -} - -.btn-blue { - color: var(--blue-alt); -} - -.btn { - position: relative; -} - -.btn-border::before { - position: absolute; - content: ""; - display: block; - bottom: -1px; - left: 0; - right: 0; - height: 1px; - background: var(--blue-alt); -} - -input.btn:focus { - border: none; - outline: none; -} - -.btn-submit { - color: var(--white); - background-color: var(--blue); - flex-grow: 1; - padding: .5rem; -} - -.btn-submit:hover { - background-color: var(--blue-alt); -} - -.btn-success { - color: var(--white); - background-color: var(--green); - flex-grow: 1; - padding: .5rem; -} - -.btn-success:hover { - background-color: var(--green-alt); -} - -.nav, -.nav-left, -.nav-center, -.nav-right { - position: relative; - display: flex; - flex-direction: row; - align-items: center; - z-index: 5; -} - -.nav { - position: sticky; -} - -.nav-right { - flex: 1; - justify-content: flex-end; -} - -.nav-center { - position: absolute; - left: 50%; - top: 0; - transform: translateX(-50%); - flex: 1; - justify-content: center; - height: 100%; - z-index: 6; -} - -@media (min-width: 800px) { - .nav-center .btn > span { - display: none; - } - - .nav-center .btn { - padding: 0 3rem; - height: 100%; - } - - #action-hamburger { - display: none; - } -} - -@media (max-width: 800px) { - .nav-center { - display: none; - position: absolute; - flex-direction: column; - top: 100%; - height: fit-content; - background-color: var(--surface0); - width: 100%; - left: 0; - transform: translateX(0%); - justify-content: flex-start; - } - - .nav-center.visible { - display: inherit !important; - } - - .nav-center .btn { - width: calc(100% - 3rem); - padding: .75rem 0rem !important; - padding-left: 3rem !important; - justify-content: flex-start; - } - - .nav-center .btn > span { - margin-left: 1rem; - } - - .nav-center .btn.active { - border-bottom: none; - } - - .nav .btn-border::before { - background: inherit; - } - -} - -.nav-right .image-loading { - display: block; -} - -.pfp, .pfp .inner { - height: 2.5rem; - border-radius: 2.5rem; - aspect-ratio: 1; - border-radius: 100%; - display: block; -} - -.pfp-sm, .pfp-sm .inner { - height: 1.75rem; -} - -object.inner { - pointer-events: none; -} - -.image-loading { - background: linear-gradient(-45deg, var(--surface0) 0%, var(--base) 25%, var(--surface0) 50%); - background-size: 500%; - background-position-x: 150%; -} - -.image-loaded { - background-color: var(--base); -} - -.card { - background-color: var(--surface0); - border-radius: .5rem; - padding: 1rem; -} - -.card p { - margin-bottom: 0; -} - -.card form { - flex-grow: 1; -} - -.card .sub-card { - background-color: var(--surface1); - border-radius: .5rem; - padding: .75rem; -} - -.row { - display: flex; - flex-direction: row; -} - -.col { - display: flex; - flex-direction: column; -} - -.grow { - flex-grow: 1; -} - -.ml-sm { - margin-left: .5rem; -} - -.ml { - margin-left: 1rem; -} - -.mr-sm { - margin-right: .5rem; -} - -.mr { - margin-right: 1rem; -} - -.mt { - margin-top: 1rem; -} - -.mb { - margin-bottom: .75rem; -} - -.pb { - padding-bottom: 1rem; -} - -.dim { - color: var(--subtext); -} - -.modal-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(255, 255, 255, .1); - display: block; -} - -.modal { - background-color: var(--surface0); - position: fixed; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - min-width: 40rem; - min-height: 24rem; - border-radius: .5rem; - display: flex; - flex-direction: column; - animation: fadeIn .1s, slideInModal .1s linear; - z-index: 10; -} - -@media (max-width: 40rem) { - .modal { - min-width: 100%; - width: 100%; - } -} - -@keyframes slideInModal { - 0% { - animation-timing-function: ease-in; - transform: translate(-50%, -60%); - } -} - -@keyframes slideIn { - 0% { - animation-timing-function: ease-in; - transform: translate(0, -20%); - } -} - -@keyframes fadeIn { - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } -} - -.modal>form { - display: flex; - flex-direction: column; - flex-grow: 1; -} - -.modal-header { - font-weight: bold; - position: relative; - border-bottom: 1px solid var(--surface1); - display: flex; - justify-content: center; - align-items: center; - cursor: grab; - padding: 1rem 0; -} - -.modal-content { - flex-grow: 1; - padding: 1rem; -} - -.modal-footer { - margin-top: auto; - padding: 0 1rem; - padding-bottom: 1rem; - display: flex; - flex-direction: row; - justify-content: flex-end; -} - -.float-right { - position: absolute; - top: 50%; - left: 100%; - transform: translate(-125%, -50%); -} - -.mi { - font-family: 'Material Icons'; - font-style: normal; - font-size: 1.5rem; -} - -.mi-sm { - font-size: 1rem; -} - -.mi-lg { - font-size: 2rem; -} - -#toast-container { - position: fixed; - top: 4rem; - left: 100%; - transform: translateX(-110%); - margin-top: 1rem; - z-index: 10000; -} - -.toast { - color: var(--white); - padding: .75rem; - margin: .5rem; - border-radius: .5rem; - min-width: 15rem; - animation: fadeIn .1s, slideIn .25s linear; - display: flex; - justify-content: space-between; -} - -.toast.error { - background-color: var(--red); -} - -.toast.success { - background-color: var(--green); -} - -form input:not(.btn) { - display: block; - font-size: 1.1rem; - outline: 2px solid var(--surface2); - border-radius: .25rem; - padding: .75rem; -} - -form input:not(.btn):focus { - outline-color: var(--blue); -} - -form .rel label:not(.static) { - position: absolute; - top: 50%; - transform: translate(.5rem, -40%); - color: var(--subtext); - transition: all 0.2s ease-out; - pointer-events: none; - width: fit-content; - font-size: 1.1rem; -} - -input:focus + label:not(.static), -input:not(:placeholder-shown) + label:not(.static) { - color: var(--text); - top: 0; - padding: .5rem; - padding-top: 0; - font-size: .75rem; - transform: translate(.5rem, -25%); - background-color: var(--surface0); -} - -.rel { - position: relative; -} - -.rel input { - width: 100%; - flex-grow: 1; -} - -input[type=radio] { - padding: 3rem !important; - width: 1rem !important; - outline: none !important; -} - -.radio { - display: flex; - flex-direction: row; - width: auto; - flex-grow: 1; -} - -.radio label { - border: 1px solid var(--surface2); - height: fit-content; - width: 100%; - padding: .75rem; - border-radius: .25rem; - cursor: pointer; -} - -.radio input { - position: absolute; - top: 50%; - left: 100%; - transform: translate(-250%, -70%); - width: fit-content; - outline: none !important; -} - -.container { - padding: 1rem; -} - -.grow { - flex-grow: 1; -} - -#user-menu { - position: fixed; - right: .5rem; - top: 4rem; - min-width: fit-content; - animation: fadeIn .1s, slideIn .1s linear; -} - -#user-menu .btn { - width: 100%; -} - -#user-menu-header { - align-items: center; -} - -#user-menu-header .pfp { - margin-right: 1rem; -} - -.hidden { - display: none; -} diff --git a/src/public/css/error.css b/src/public/css/error.css deleted file mode 100644 index 5567cd5..0000000 --- a/src/public/css/error.css +++ /dev/null @@ -1,16 +0,0 @@ -#main-content { - display: flex; - flex-direction: column; - align-items: center; - padding: 10rem 0; -} - -#main-content h1 { - color: var(--blue); - font-family: Facebook; - font-size: 5rem; -} - -#main-content span { - font-size: 2rem; -} diff --git a/src/public/css/people.css b/src/public/css/people.css deleted file mode 100644 index d36e5e8..0000000 --- a/src/public/css/people.css +++ /dev/null @@ -1,59 +0,0 @@ - -.title { - margin-top: 2rem; - margin-left: 3rem; - font-size: 3rem; - margin-bottom: 0; -} - -.desc { - margin-left: 3rem; -} - -#people-container { - display: grid; - width: 100%; - padding: 1rem 2rem; - margin-bottom: 1rem; - grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr) ); - grid-auto-rows: max-content; - grid-gap: 2rem; -} - -.profile { - width: 16rem; - text-decoration: none; - margin-left: auto; - margin-right: auto; -} - -.profile:hover { - outline: 1px solid var(--blue); -} - -.profile strong { - font-size: 1.5rem; -} - -.profile .pfp, .profile .pfp .inner { - padding: none; - margin: none; - width: 100%; - height: 100%; - aspect-ratio: 1; - border-radius: .3rem; -} - -.profile .pfp { - margin-bottom: 1rem; -} - -td:nth-child(1) { - font-weight: bold; - color: var(--subtext); - padding-right: 1rem; -} - -td:nth-child(2) { - color: var(--text); -} diff --git a/src/public/css/post.css b/src/public/css/post.css deleted file mode 100644 index 254e82b..0000000 --- a/src/public/css/post.css +++ /dev/null @@ -1,29 +0,0 @@ - -.action-load-comments { - margin-left: 4rem; -} - -#action-load-posts { - width: 100%; - justify-content: center; -} - -#post-container { - max-width: 40rem; - width: 100%; -} - -.post, #new-post { - margin-bottom: 1rem; - max-width: 40rem; - width: 100%; -} - -.post { - padding-bottom: 0; -} - -.post .likes { - display: block; - padding-top: .25rem; -} diff --git a/src/public/css/profile.css b/src/public/css/profile.css deleted file mode 100644 index 0c8dd78..0000000 --- a/src/public/css/profile.css +++ /dev/null @@ -1,142 +0,0 @@ -#main-content { - display: flex; - flex-direction: column; - padding: 0; -} - -#profile-header-container { - width: 100%; - display: flex; - flex-direction: row; - justify-content: center; - background-color: var(--surface0); - border-bottom: 1px solid var(--surface1); -} - -#profile-header { - min-width: 0; - max-width: 80rem; - flex-grow: 1; -} - -#profile-header .banner { - width: 100%; - max-width: 100%; - min-height: 30rem; - aspect-ratio: 5; -} - -.banner .inner { - width: 100%; - height: 100%; -} - -#profile-header .banner img { - height: 100%; - width: 100%; - object-fit: cover; -} - -#profile-header .info .pfp-wrapper .pfp, -#profile-header .info .pfp-wrapper .pfp .inner { - height: 12.5rem; -} - -#profile-header .info { - position: relative; - margin-bottom: 6rem; -} - -#profile-header .info .pfp-wrapper { - padding: .5rem; - background-color: var(--surface0); - height: fit-content; - border-radius: 100%; - position: absolute; - top: -2.5rem; - left: 1rem; -} - -#profile-header .info .content { - margin-left: 17rem; - margin-top: 2rem; -} - -@media(max-width: 800px) { - #profile-header .info .pfp-wrapper .pfp, - #profile-header .info .pfp-wrapper .pfp .inner { - height: 8rem; - } - - #profile-header .info .content { - margin-left: 12rem; - } -} - -#profile-header .info .content .name { - font-size: 2rem; -} - -#profile-header > hr { - border-bottom: 1px solid var(--surface1); - height: 0; - margin-bottom: 0; -} - -.options { - width: 100%; - height: 3rem; -} - -.options .btn { - height: 100%; - width: 10rem; -} - -.options .btn span { - width: 100%; - text-align: center; -} - -.tab { - max-width: 80rem; - width: 100%; - height: 100%; - margin-left: auto; - margin-right: auto; -} - -#post-container { - max-width: 40rem; - width: 100%; - margin-left: auto; - margin-right: auto; - margin-bottom: -1rem; -} - -#post-container .post { - margin-bottom: 1rem; -} - -td:nth-child(1) { - padding-right: 2rem; -} - -#about-tab { - width: auto; -} - -#follow-container { - margin-left: auto; - margin-right: 2rem; -} - -#follow-container > a { - width: 10rem; - padding: .5rem; -} - -#follow-container > a > span { - width: 100%; - text-align: center; -} diff --git a/src/public/font/facebook.otf b/src/public/font/Facebook.otf similarity index 100% rename from src/public/font/facebook.otf rename to src/public/font/Facebook.otf diff --git a/src/public/font/Facebook.ttf b/src/public/font/Facebook.ttf new file mode 100644 index 0000000..ad1183a Binary files /dev/null and b/src/public/font/Facebook.ttf differ diff --git a/src/public/font/Facebook.woff b/src/public/font/Facebook.woff new file mode 100644 index 0000000..80f9b1d Binary files /dev/null and b/src/public/font/Facebook.woff differ diff --git a/src/public/font/Facebook.woff2 b/src/public/font/Facebook.woff2 new file mode 100644 index 0000000..fcfea6c Binary files /dev/null and b/src/public/font/Facebook.woff2 differ diff --git a/src/public/font/helvetica-neue.otf b/src/public/font/Helvetica Neue.otf similarity index 100% rename from src/public/font/helvetica-neue.otf rename to src/public/font/Helvetica Neue.otf diff --git a/src/public/font/Helvetica Neue.ttf b/src/public/font/Helvetica Neue.ttf new file mode 100644 index 0000000..90c5010 Binary files /dev/null and b/src/public/font/Helvetica Neue.ttf differ diff --git a/src/public/font/Helvetica Neue.woff b/src/public/font/Helvetica Neue.woff new file mode 100644 index 0000000..0d4e85f Binary files /dev/null and b/src/public/font/Helvetica Neue.woff differ diff --git a/src/public/font/Helvetica Neue.woff2 b/src/public/font/Helvetica Neue.woff2 new file mode 100644 index 0000000..c02d45d Binary files /dev/null and b/src/public/font/Helvetica Neue.woff2 differ diff --git a/src/public/font/Material Icons.otf b/src/public/font/Material Icons.otf new file mode 100644 index 0000000..844e52a Binary files /dev/null and b/src/public/font/Material Icons.otf differ diff --git a/src/public/font/material-icons.ttf b/src/public/font/Material Icons.ttf similarity index 100% rename from src/public/font/material-icons.ttf rename to src/public/font/Material Icons.ttf diff --git a/src/public/font/Material Icons.woff b/src/public/font/Material Icons.woff new file mode 100644 index 0000000..02d9d8c Binary files /dev/null and b/src/public/font/Material Icons.woff differ diff --git a/src/public/font/Material Icons.woff2 b/src/public/font/Material Icons.woff2 new file mode 100644 index 0000000..4b3b9d4 Binary files /dev/null and b/src/public/font/Material Icons.woff2 differ diff --git a/src/public/font/sfpro.otf b/src/public/font/SF Pro.otf similarity index 100% rename from src/public/font/sfpro.otf rename to src/public/font/SF Pro.otf diff --git a/src/public/font/SF Pro.ttf b/src/public/font/SF Pro.ttf new file mode 100644 index 0000000..aef375f Binary files /dev/null and b/src/public/font/SF Pro.ttf differ diff --git a/src/public/font/SF Pro.woff b/src/public/font/SF Pro.woff new file mode 100644 index 0000000..43226a3 Binary files /dev/null and b/src/public/font/SF Pro.woff differ diff --git a/src/public/font/SF Pro.woff2 b/src/public/font/SF Pro.woff2 new file mode 100644 index 0000000..5f7f7fb Binary files /dev/null and b/src/public/font/SF Pro.woff2 differ diff --git a/src/public/font/sfprobold.otf b/src/public/font/sfprobold.otf deleted file mode 100644 index 28fa5a4..0000000 Binary files a/src/public/font/sfprobold.otf and /dev/null differ diff --git a/src/public/icons/logo512.png b/src/public/icons/logo512.png new file mode 100644 index 0000000..2551beb Binary files /dev/null and b/src/public/icons/logo512.png differ diff --git a/src/public/js/lib.js b/src/public/js/lib.js index 4d08bab..e19f6c6 100644 --- a/src/public/js/lib.js +++ b/src/public/js/lib.js @@ -131,12 +131,12 @@ $.ajaxSetup({ }) var onImgLoad = function(me) { - me.parentElement.classList.remove('image-loading'); - me.parentElement.classList.add('image-loaded'); + me.parentElement.classList.remove('loading'); + me.parentElement.classList.add('loaded'); } var onImgError = function(me) { - me.parentElement.classList.remove('image-loading'); - me.parentElement.classList.add('image-loaded'); + me.parentElement.classList.remove('loading'); + me.parentElement.classList.add('loaded'); me.remove(); } diff --git a/src/public/js/post.js b/src/public/js/post.js index 3c03bae..a7b05c6 100644 --- a/src/public/js/post.js +++ b/src/public/js/post.js @@ -104,7 +104,7 @@ $$('.action-new-comment-form').on('submit', function(e) { $$('.action-like').on('click', function() { let me = $(this); - let liked = me.hasClass('btn-blue'); + let liked = me.hasClass('btn-primary'); let like_id = me.attr('likeId'); let post_id = me.attr('postId'); @@ -119,15 +119,15 @@ $$('.action-like').on('click', function() { } const onPatch = () => { - let liked = me.hasClass('btn-blue'); - me.toggleClass('btn-blue'); + let liked = me.hasClass('btn-primary'); + me.toggleClass('btn-primary'); updateLiked(!liked); } const onPost = (data) => { - let liked = me.hasClass('btn-blue'); + let liked = me.hasClass('btn-primary'); me.attr('likeId', data[0].id + ''); - me.toggleClass('btn-blue'); + me.toggleClass('btn-primary'); updateLiked(!liked); } diff --git a/src/scss/_mixins.scss b/src/scss/_mixins.scss new file mode 100644 index 0000000..bcb795d --- /dev/null +++ b/src/scss/_mixins.scss @@ -0,0 +1,22 @@ +@mixin font-face($name) { + @font-face { + font-family: $name; + src: url("../font/" + $name + ".woff2") format("woff2"), + url("../font/" + $name + ".woff") format("woff"), + url("../font/" + $name + ".ttf") format("truetype"), + url("../font/" + $name + ".otf") format("opentype"); + font-weight: normal; + font-style: normal; + font-display: swap; + } +} + +@mixin row { + display: flex; + flex-direction: row; +} + +@mixin column { + display: flex; + flex-direction: column; +} diff --git a/src/scss/_variables.scss b/src/scss/_variables.scss new file mode 100644 index 0000000..3a81165 --- /dev/null +++ b/src/scss/_variables.scss @@ -0,0 +1,71 @@ + +$varient: "dark"; + +$white: #e4e6eb; +$white-alt: #b0b3b8; +$black: #000000; +$black-alt: #1d2129; +$red: #f02849; +$red-alt: #f02849; +$green: #30ab5a; +$green-alt: #39b463; +$blue: #1778f2; +$blue-alt: #1d85fc; +$yellow: #dcde81; +$yellow-alt: #808037; +$grey-100: #18191a; +$grey-200: #242526; +$grey-300: #3a3b3c; +$grey-400: #4e4f50; +$grey-500: #606770; +$grey-700: #dadde1; +$grey-800: #f0f2f5; +$grey-900: #fff; + +$base: null !default; +$surface0: null !default; +$surface1: null !default; +$surface2: null !default; +$text: null !default; +$subtext: null !default; +$btntext: null !default; + +@if $varient == "dark" { + $base: $grey-100; + $surface0: $grey-200; + $surface1: $grey-300; + $surface2: $grey-400; + $text: $white; + $subtext: $white-alt; + $btntext: $white; +} + +@if $varient == "light" { + $base: $grey-900; + $surface0: $grey-900; + $surface1: $grey-800; + $surface2: $grey-700; + $text: $black; + $subtext: $black-alt; + $btntext: $grey-500; +} + +$font: "Helvetica Neue", Helvetica, Verdana, Courier, monospace; +$header-font: "Facebook"; + +$scale: 16px; +$outer-gap: $scale; +$inner-gap: $scale; +$inner-inner-gap: $scale * 0.75; +$outer-radius: $scale / 2; +$inner-radius: $scale / 3; +$font-size: $scale; +$font-size-small: $scale * 0.75; + +$header-height: $scale * 3.5; + +$base-z-index: 1; +$header-z-index: 2; +$modal-z-index: 5; + +$content-width: $scale * 40; diff --git a/src/public/css/auth.css b/src/scss/auth.scss similarity index 90% rename from src/public/css/auth.css rename to src/scss/auth.scss index 2c31694..5f4fb91 100644 --- a/src/public/css/auth.css +++ b/src/scss/auth.scss @@ -1,3 +1,6 @@ +@import "./variables"; +@import "./mixins"; + #main-content { padding-top: 20rem; padding-bottom: 5rem; @@ -13,7 +16,7 @@ } .branding h1 { - color: var(--blue); + color: $blue; font-family: facebook; font-size: 3.5rem; } @@ -45,3 +48,4 @@ margin-top: 4rem; } } + diff --git a/src/scss/common.scss b/src/scss/common.scss new file mode 100644 index 0000000..5a570f9 --- /dev/null +++ b/src/scss/common.scss @@ -0,0 +1,600 @@ +@import "./variables"; +@import "./mixins"; + +@include font-face("Helvetica Neue"); +@include font-face("Material Icons"); +@include font-face("Facebook"); +@include font-face("SF Pro"); + +* { + box-sizing: border-box; +} + +hr { + color: $surface2; + background: $surface2; + width: 100%; + height: 1px; + border: none; +} + +a, +input, +button { + background: none; + border: none; + color: inherit; +} + +a, +button { + cursor: pointer; +} + +html { + color: $text; + font-family: $font; + font-size: $font-size; + background: $surface0; + + .subtext { + color: $subtext; + } +} + +html, +body { + width: 100%; + margin: 0; + padding: 0; +} + +header#header { + height: $header-height; + background: $surface0; + position: sticky; + top: 0; + display: flex; + flex-direction: row; + align-items: center; + padding: 0 $inner-gap; + border-bottom: 1px solid $surface1; + z-index: $header-z-index; + + .left, + .center, + .right { + display: flex; + flex-direction: row; + align-items: center; + flex: 1; + } + + .left { + .logo { + font-family: $header-font; + color: $blue; + font-size: 2.25em; + height: 100%; + line-height: 2rem; + margin-top: $inner-gap; + } + } + + .center { + position: absolute; + height: 100%; + left: 50%; + top: 0; + transform: translateX(-50%); + justify-content: center; + } + + .right { + justify-content: flex-end; + + > .pfp { + padding: 0; + } + + #user-menu { + position: fixed; + right: $inner-gap; + top: $header-height + $inner-gap; + min-width: fit-content; + width: 20em; + animation: fadeIn .1s, slideIn .1s linear; + + .user-menu-header { + align-items: center; + + .pfp { + margin-right: $inner-gap; + } + } + + .btn { + justify-content: flex-start; + } + } + } + +} + +@media (min-width: 800px) { + header#header { + .center { + .btn { + padding: 0 3rem; + height: 100%; + + > span { + display: none; + } + } + } + + .right { + #action-hamburger { + display: none; + } + } + } +} + +@media (max-width: 800px) { + header#header { + .center { + display: none; + position: absolute; + flex-direction: column; + top: 100%; + height: fit-content; + background-color: $surface0; + width: 100%; + left: 0; + transform: translateX(0%); + justify-content: flex-start; + + &.visible { + display: inherit !important; + } + + .btn { + width: 100%; + padding: $inner-gap 0; + padding-left: 3rem; + justify-content: flex-start; + + > span { + margin-left: $inner-gap; + } + + &.btn-border { + ::before { + background: inherit; + } + } + } + } + } +} + +main#main { + background: $base; + padding-top: $inner-gap; + display: flex; + flex-direction: column; + align-items: center; +} + +footer#footer { + text-align: center; + padding: $inner-gap; + color: $subtext; + font-size: $font-size-small; +} + +.btn { + display: flex; + justify-content: center; + align-items: center; + position: relative; + text-align: center; + border-radius: $inner-radius; + font-weight: bold; + text-decoration: none; + padding: $inner-gap * 0.5; + + &:hover { + background: $surface1; + } + + &.btn-alt { + background: $surface1; + + &:hover { + background: $surface2; + } + } + + &.btn-primary { + color: $blue-alt; + + &.btn-alt { + background: $blue; + color: $white; + + &:hover { + background: $blue-alt; + } + } + } + + &.btn-success, + &.btn-submit { + color: $green-alt; + + &.btn-alt { + background: $green; + color: $white; + + &:hover { + background: $green-alt; + } + } + } + + &.btn-blend { + font-weight: inherit; + + &:hover { + background: inherit !important; + text-decoration: underline; + } + } + + &.btn-border { + ::before { + position: absolute; + content: ""; + display: block; + bottom: -1px; + left: 0; + right: 0; + height: 1px; + background: $blue-alt; + } + } +} + +.image { + display: block; + + .inner { + width: 100%; + height: 100%; + display: inherit; + border-radius: inherit; + } + + &.pfp { + height: 2.5em; + aspect-ratio: 1; + border-radius: 100%; + } +} + +/* fix banner on profile pages */ +object.inner { + pointer-events: none; +} + +/* loading animation*/ +.loading { + background: linear-gradient(-45deg, $surface0) 0%, var(--base) 25%, var(--surface0) 50%; + background-size: 500%; + background-position-x: 150%; +} + +/* loaded bg to fix transparent images */ +.loaded { + background-color: $base; +} + +.card { + background-color: $surface0; + border-radius: $outer-radius; + padding: $inner-gap; + max-width: $content-width; + margin-bottom: $outer-gap; + + p { + margin-bottom: 0; + } + + form { + flex-grow: 1; + } + + .sub-card { + background-color: $surface1; + border-radius: $inner-radius; + padding: $inner-inner-gap; + } +} + +.row { + @include row; +} + +.col { + @include column; +} + +.grow { + width: auto; + flex: 1; + flex-grow: 1; +} + +.ml-sm { + margin-left: .5rem; +} + +.ml { + margin-left: 1rem; +} + +.mr-sm { + margin-right: .5rem; +} + +.mr { + margin-right: 1rem; +} + +.mt { + margin-top: 1rem; +} + +.mb { + margin-bottom: .75rem; +} + +.pb { + padding-bottom: 1rem; +} + +.modal-container { + z-index: $modal-z-index; + position: fixed; + background: #fff2; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: block; + + .modal { + background-color: $surface0; + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + min-width: $content-width; + min-height: $content-width * 0.6; + border-radius: $outer-radius; + @include column; + animation: fadeIn .1s, slideInModal .1s linear; + + .modal-header { + display: block; + position: relative; + border-bottom: 1px solid $surface1; + cursor: grab; + padding: $inner-gap; + text-align: center; + + .modal-title { + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + font-weight: bold; + } + + .modal-close { + float: right; + } + } + + .modal-content { + flex-grow: 1; + padding: 1rem; + } + + .modal-footer { + margin-top: auto; + padding: 0 1rem; + padding-bottom: 1rem; + display: flex; + flex-direction: row; + justify-content: flex-end; + } + + + > form { + display: flex; + flex-direction: column; + flex-grow: 1; + } + } +} + +@media (max-width: $content-width) { + .modal-container { + .modal { + min-width: 100%; + width: 100%; + } + } +} + +@keyframes slideInModal { + 0% { + animation-timing-function: ease-in; + transform: translate(-50%, -60%); + } +} + +@keyframes slideIn { + 0% { + animation-timing-function: ease-in; + transform: translate(0, -20%); + } +} + +@keyframes fadeIn { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} + +.float-right { + position: absolute; + top: 50%; + left: 100%; + transform: translate(-125%, -50%); +} + +.mi { + font-family: 'Material Icons'; + font-style: normal; + font-size: 1.5rem; +} + +.mi-sm { + font-size: 1rem; +} + +.mi-lg { + font-size: 2rem; +} + +#toast-container { + position: fixed; + top: 4rem; + left: 100%; + transform: translateX(-110%); + margin-top: 1rem; + z-index: 10000; +} + +.toast { + color: $white; + padding: .75rem; + margin: .5rem; + border-radius: .5rem; + min-width: 15rem; + animation: fadeIn .1s, slideIn .25s linear; + display: flex; + justify-content: space-between; +} + +.toast.error { + background-color: $red; +} + +.toast.success { + background-color: $green; +} + +form input:not(.btn) { + display: block; + font-size: 1.1rem; + outline: 2px solid $surface2; + border-radius: .25rem; + padding: .75rem; +} + +form input:not(.btn):focus { + outline-color: $blue; +} + +form .rel label:not(.static) { + position: absolute; + top: 50%; + transform: translate(.5rem, -40%); + color: $subtext; + transition: all 0.2s ease-out; + pointer-events: none; + width: fit-content; + font-size: 1.1rem; +} + +input:focus + label:not(.static), +input:not(:placeholder-shown) + label:not(.static) { + color: $text; + top: 0; + padding: .5rem; + padding-top: 0; + font-size: .75rem; + transform: translate(.5rem, -25%); + background-color: $surface0; +} + +.rel { + position: relative; +} + +.rel input { + width: 100%; + flex-grow: 1; +} + +input[type=radio] { + padding: 3rem !important; + width: 1rem !important; + outline: none !important; +} + +.radio { + display: flex; + flex-direction: row; + width: auto; + flex-grow: 1; +} + +.radio label { + border: 1px solid $surface2; + height: fit-content; + width: 100%; + padding: .75rem; + border-radius: .25rem; + cursor: pointer; +} + +.radio input { + position: absolute; + top: 50%; + left: 100%; + transform: translate(-250%, -70%); + width: fit-content; + outline: none !important; +} + +.container { + padding: 1rem; +} + +.grow { + flex-grow: 1; +} + +.hidden { + display: none; +} diff --git a/src/scss/error.scss b/src/scss/error.scss new file mode 100644 index 0000000..0f4c0b1 --- /dev/null +++ b/src/scss/error.scss @@ -0,0 +1,16 @@ +@import "./variables"; +@import "./mixins"; + +main#main { + padding: 10rem 0; + + h1 { + color: $blue; + font-family: $header-font; + font-size: 5em; + } + + span { + font-size: 2em; + } +} diff --git a/src/public/css/home.css b/src/scss/home.scss similarity index 79% rename from src/public/css/home.css rename to src/scss/home.scss index 40e1063..e490f55 100644 --- a/src/public/css/home.css +++ b/src/scss/home.scss @@ -1,3 +1,6 @@ +@import "./variables"; +@import "./mixins"; + #main-content { display: flex; flex-direction: column; @@ -16,6 +19,6 @@ height: 10rem; flex-grow: 1; background-color: transparent; - color: var(--text); - font-family: var(--font); + color: $text; + font-family: $font; } diff --git a/src/scss/people.scss b/src/scss/people.scss new file mode 100644 index 0000000..4511aa8 --- /dev/null +++ b/src/scss/people.scss @@ -0,0 +1,46 @@ +@import "./variables"; +@import "./mixins"; + +$profile-width: 16em; + +main#main { + .title { + margin-top: $outer-gap; + font-size: 3rem; + margin-bottom: 0; + } +} + +#people-container { + display: grid; + width: 100%; + padding: $inner-gap; + margin-bottom: $outer-gap; + grid-template-columns: repeat(auto-fill, minmax($profile-width, 1fr) ); + grid-auto-rows: max-content; + grid-gap: 2em; + + .profile { + width: $profile-width; + text-decoration: none; + margin-left: auto; + margin-right: auto; + + &:hover { + outline: 1px solid $blue; + } + + .name { + font-weight: bold; + font-size: 1.5em; + } + + .pfp { + border-radius: $inner-gap / 4; + width: 100%; + height: 100%; + margin-bottom: $inner-gap; + } + } + +} diff --git a/src/scss/post.scss b/src/scss/post.scss new file mode 100644 index 0000000..8913be0 --- /dev/null +++ b/src/scss/post.scss @@ -0,0 +1,15 @@ +@import "./variables"; +@import "./mixins"; + +#post-container { + max-width: $content-width; + width: 100%; + + .post { + padding-bottom: 0; + } +} + +#new-post { + width: 100%; +} diff --git a/src/scss/profile.scss b/src/scss/profile.scss new file mode 100644 index 0000000..ec271e4 --- /dev/null +++ b/src/scss/profile.scss @@ -0,0 +1,121 @@ +@import "./variables"; +@import "./mixins"; + +main#main { + padding-top: 0; +} + +$pfp-size: 12.5em; + +#profile-header-container { + width: 100%; + display: flex; + flex-direction: row; + justify-content: center; + background-color: $surface0; + border-bottom: 1px solid $surface1; +} + +#profile-header { + min-width: 0; + max-width: 80rem; + flex-grow: 1; + + .banner { + width: 100%; + max-width: 100%; + min-height: 30em; + aspect-ratio: 5; + + img { + object-fit: cover; + } + } + + .info { + position: relative; + margin-bottom: 6em; + + .pfp-wrapper { + padding: $inner-gap / 2; + background-color: $surface0; + height: fit-content; + border-radius: 100%; + position: absolute; + top: -2.5rem; + left: $inner-gap; + + .pfp { + height: $pfp-size; + } + } + + .content { + margin-left: $pfp-size + 5em; + margin-top: 2em; + + .name { + font-size: 2em;; + } + + .follow { + margin-left: auto; + margin-right: 2rem; + + a { + width: 10rem; + padding: $inner-gap / 2; + } + } + + } + } + + > hr { + margin: 0; + border-bottom: 1px solid $surface1; + } + + .options { + height: 3rem; + + .btn { + width: 10rem; + } + } +} + +@media(max-width: 800px) { + #profile-header { + .info { + .pfp-wrapper { + .pfp { + height: $pfp-size * 0.7; + } + } + + .content { + margin-left: ($pfp-size + 5em) * 0.7; + } + } + } +} + +#tab-container { + width: 100%; + @include column; + align-items: center; +} + +#tab-posts, +#tab-about { + width: 100%; + max-width: $content-width; +} + +#tab-about { + td:nth-child(1) { + padding-right: 2rem; + } +} + diff --git a/src/public/css/settings.css b/src/scss/settings.scss similarity index 79% rename from src/public/css/settings.css rename to src/scss/settings.scss index 8c3e9f7..2194bcc 100644 --- a/src/public/css/settings.css +++ b/src/scss/settings.scss @@ -1,3 +1,5 @@ +@import "./variables"; +@import "./mixins"; #main-content { display: flex; diff --git a/src/shim/shim.php b/src/shim/shim.php index 318d825..eb84412 100755 --- a/src/shim/shim.php +++ b/src/shim/shim.php @@ -69,12 +69,12 @@ function clear_all() { extract($GLOBALS); $psql->beginTransaction(); $psql->exec( - 'DELETE FROM admin.user; - DELETE FROM admin.post; - DELETE FROM admin.comment; - DELETE FROM admin.like; - DELETE FROM admin.follow; - DELETE FROM admin.user_media;' + 'DELETE FROM xssbook.user; + DELETE FROM xssbook.post; + DELETE FROM xssbook.comment; + DELETE FROM xssbook.like; + DELETE FROM xssbook.follow; + DELETE FROM xssbook.user_media;' ); } @@ -87,7 +87,7 @@ function migrate_users() { 'SELECT user_id, firstname, lastname, email, password, gender, date, day, month, year FROM users;' ); $submit = $psql->prepare( - 'INSERT INTO admin.user + 'INSERT INTO xssbook.user (id, username, password, first_name, last_name, email, gender, birth_date, created) VALUES (?, ?, ?, ?, ?, ?, ?, ?, to_timestamp(?));' @@ -125,7 +125,7 @@ function migrate_posts() { 'SELECT post_id, user_id, content, date FROM posts;' ); $submit = $psql->prepare( - 'INSERT INTO admin.post + 'INSERT INTO xssbook.post (id, user_id, content, created) VALUES (?, ?, ?, to_timestamp(?));' @@ -154,7 +154,7 @@ function migrate_comments() { 'SELECT comment_id, user_id, post_id, content, date FROM comments;' ); $submit = $psql->prepare( - 'INSERT INTO admin.comment + 'INSERT INTO xssbook.comment (id, user_id, post_id, content, created) VALUES (?, ?, ?, ?, to_timestamp(?));' @@ -184,7 +184,7 @@ function migrate_likes() { 'SELECT user_id, post_id FROM likes;' ); $submit = $psql->prepare( - 'INSERT INTO admin.like + 'INSERT INTO xssbook.like (user_id, post_id) VALUES (?, ?);' @@ -210,7 +210,7 @@ function migrate_follow() { 'SELECT follower_id, followee_id FROM friends;' ); $submit = $psql->prepare( - 'INSERT INTO admin.follow + 'INSERT INTO xssbook.follow (follower_id, followee_id) VALUES (?, ?);' @@ -233,7 +233,7 @@ function migrate_user_media($type) { // load queries $submit = $psql->prepare( - 'INSERT INTO admin.user_media + 'INSERT INTO xssbook.user_media (user_id, content, mime, type) VALUES (?, decode(?, \'base64\'), ?, ?);' @@ -273,7 +273,7 @@ function migrate_seq() { $tables = array('user', 'post', 'like', 'comment', 'follow', 'user_media'); foreach ($tables as $table) { - $sql = "SELECT setval('sys.{$table}_id_seq', (SELECT MAX(id) FROM admin.{$table}), true);"; + $sql = "SELECT setval('sys.{$table}_id_seq', (SELECT MAX(id) FROM xssbook.{$table}), true);"; $psql->exec($sql); } } diff --git a/src/web/_controller/_meta.php b/src/web/_controller/_meta.php new file mode 100644 index 0000000..bec3c65 --- /dev/null +++ b/src/web/_controller/_meta.php @@ -0,0 +1,34 @@ + 'xssbook.com', + 'name' => 'xssbook.com', + 'icons' => [ + array( + 'src' => 'https://xssbook.com/public/icons/logo512.png', + 'type' => 'image/png', + 'sizes' => '512x512', + 'purpose' => 'any maskable' + ) + ], + 'id' => 'https://xssbook.com/home', + 'start_url' => 'https://xssbook.com/home', + 'background_color' => '#181818', + 'display' => 'standalone', + 'scope' => '/', + 'theme_color' => '#181818', + 'shortcuts' => [], + 'description' => 'Post posts postfully on XSSBook', + 'screenshots' => [] + ); + + header('Content-type: application/json'); + echo json_encode($json); + } + +} + +?> diff --git a/src/web/_controller/apps/auth.php b/src/web/_controller/apps/auth.php index 6b30cc9..1df74da 100644 --- a/src/web/_controller/apps/auth.php +++ b/src/web/_controller/apps/auth.php @@ -27,7 +27,7 @@ class Auth_controller extends Controller { parent::index(); $data = $this->auth_model->get_data(); - $this->view('header_empty', $data); + $this->view('head', $data); $this->view('apps/auth/login', $data); $this->view('footer', $data); } diff --git a/src/web/_views/apps/auth/login.php b/src/web/_views/apps/auth/login.php index c12af57..1741ac5 100644 --- a/src/web/_views/apps/auth/login.php +++ b/src/web/_views/apps/auth/login.php @@ -1,6 +1,6 @@ -
+

xssbook

@@ -31,18 +31,18 @@
'submit') )?>
'submit') )?> @@ -84,4 +84,4 @@ }); }) -
+ diff --git a/src/web/_views/apps/error/main.php b/src/web/_views/apps/error/main.php index 6d7e2ea..bcc6f90 100644 --- a/src/web/_views/apps/error/main.php +++ b/src/web/_views/apps/error/main.php @@ -1,6 +1,6 @@ -
+

-
+ diff --git a/src/web/_views/apps/home/main.php b/src/web/_views/apps/home/main.php index 6112173..05697b9 100644 --- a/src/web/_views/apps/home/main.php +++ b/src/web/_views/apps/home/main.php @@ -1,13 +1,13 @@ -
+
post_controller->index(); ?> -
+
diff --git a/src/web/_views/apps/people/card.php b/src/web/_views/apps/people/card.php index eda49b5..93b1350 100644 --- a/src/web/_views/apps/people/card.php +++ b/src/web/_views/apps/people/card.php @@ -7,8 +7,8 @@
- format_model->name($user)?> - + format_model->name($user)?> +
diff --git a/src/web/_views/apps/people/footer.php b/src/web/_views/apps/people/footer.php index ff93026..f18e031 100644 --- a/src/web/_views/apps/people/footer.php +++ b/src/web/_views/apps/people/footer.php @@ -1,3 +1,3 @@ -
+ diff --git a/src/web/_views/apps/people/header.php b/src/web/_views/apps/people/header.php index 1f3a025..b1099ec 100644 --- a/src/web/_views/apps/people/header.php +++ b/src/web/_views/apps/people/header.php @@ -1,6 +1,6 @@ -
+


diff --git a/src/web/_views/apps/people/main.php b/src/web/_views/apps/people/main.php index deec4c2..ec84ab9 100644 --- a/src/web/_views/apps/people/main.php +++ b/src/web/_views/apps/people/main.php @@ -16,7 +16,7 @@ = $page_size && $page_size < $total): ?> $loaded, 'pageSize' => $page_size, diff --git a/src/web/_views/apps/profile/main.php b/src/web/_views/apps/profile/main.php index 6d25c98..e3ed26c 100644 --- a/src/web/_views/apps/profile/main.php +++ b/src/web/_views/apps/profile/main.php @@ -1,6 +1,6 @@ -
+
@@ -12,13 +12,13 @@
format_model->name($user)?> - +
main->session && (!isset($self) || $self['id'] != $user['id']) ): ?> -
+
@@ -132,7 +132,7 @@
{ - tab.btn.removeClass('btn-blue'); + tab.btn.removeClass('btn-primary'); tab.btn.removeClass('btn-border'); tab.tab.css('display', 'none'); }; const enableTab = (tab) => { - tab.btn.addClass('btn-blue'); + tab.btn.addClass('btn-primary'); tab.btn.addClass('btn-border'); tab.tab.css('display', ''); }; @@ -266,4 +266,4 @@ loadTab('followers'); loadTab('following'); -
+
diff --git a/src/web/_views/apps/settings/main.php b/src/web/_views/apps/settings/main.php index dcfff92..02cbf57 100644 --- a/src/web/_views/apps/settings/main.php +++ b/src/web/_views/apps/settings/main.php @@ -116,7 +116,7 @@ function resetMedia(media_type) { } -
+


@@ -155,7 +155,7 @@ function resetMedia(media_type) {
@@ -170,11 +170,11 @@ function resetMedia(media_type) { )?>
@@ -187,14 +187,14 @@ function resetMedia(media_type) { )?>
-
+ diff --git a/src/web/_views/footer.php b/src/web/_views/footer.php index bc9b3a2..e26d4a5 100644 --- a/src/web/_views/footer.php +++ b/src/web/_views/footer.php @@ -1,6 +1,6 @@ -