Compare commits

..

No commits in common. "4c8d58b646ac62e67fc34c12f8cad51e7512bee3" and "530bbf058781e00e588f1457b6ee589a64b74da1" have entirely different histories.

31 changed files with 135 additions and 604 deletions

1
.gitignore vendored
View file

@ -1,2 +1 @@
/data /data
/src/web/lang/en_CAT

View file

@ -1,15 +0,0 @@
CREATE VIEW api.follow AS
SELECT
f.id,
f.follower_id,
f.followee_id,
f.value,
f.created,
f.modified
FROM
admin.follow f;
GRANT SELECT ON TABLE api.follow
TO rest_anon, rest_user;
GRANT SELECT ON TABLE admin.follow
TO rest_anon, rest_user;

View file

@ -1,32 +0,0 @@
CREATE FUNCTION _api.follow_delete()
RETURNS TRIGGER
LANGUAGE plpgsql VOLATILE
AS $BODY$
DECLARE
_user_id INTEGER;
BEGIN
_user_id = _api.get_user_id();
IF OLD.follower_id <> _user_id THEN
PERFORM _api.raise_deny();
END IF;
UPDATE admin.follow SET
value = FALSE,
modified = clock_timestamp()
WHERE id = OLD.id;
END
$BODY$;
GRANT EXECUTE ON FUNCTION _api.follow_delete()
TO rest_user;
GRANT DELETE ON TABLE api.follow
TO rest_user;
GRANT UPDATE ON TABLE admin.follow
TO rest_user;
CREATE TRIGGER api_follow_delete_trgr
INSTEAD OF DELETE
ON api.follow
FOR EACH ROW
EXECUTE PROCEDURE _api.follow_delete();

View file

@ -1,46 +0,0 @@
CREATE FUNCTION _api.follow_insert()
RETURNS TRIGGER
LANGUAGE plpgsql VOLATILE
AS $BODY$
DECLARE
_user_id INTEGER;
BEGIN
_user_id = _api.get_user_id();
IF NEW.followee_id IS NULL THEN
-- for now
PERFORM _api.raise_deny();
END IF;
NEW.value := COALESCE(NEW.value, TRUE);
INSERT INTO admin.follow (
follower_id,
followee_id,
value
) VALUES (
_user_id,
NEW.followee_id,
NEW.value
)
RETURNING id
INTO NEW.id;
RETURN NEW;
END
$BODY$;
GRANT EXECUTE ON FUNCTION _api.follow_insert()
TO rest_user;
GRANT INSERT ON TABLE api.follow
TO rest_user;
GRANT INSERT ON TABLE admin.follow
TO rest_user;
GRANT UPDATE ON TABLE sys.follow_id_seq
TO rest_user;
CREATE TRIGGER api_follow_insert_trgr
INSTEAD OF INSERT
ON api.follow
FOR EACH ROW
EXECUTE PROCEDURE _api.follow_insert();

View file

@ -1,44 +0,0 @@
CREATE FUNCTION _api.follow_update()
RETURNS TRIGGER
LANGUAGE plpgsql VOLATILE
AS $BODY$
DECLARE
_user_id INTEGER;
_changed BOOLEAN;
BEGIN
_user_id = _api.get_user_id();
_changed = FALSE;
IF OLD.follower_id <> _user_id THEN
PERFORM _api.raise_deny();
END IF;
NEW.value = COALESCE(NEW.value, OLD.value);
IF NEW.value IS DISTINCT FROM OLD.value THEN
_changed = TRUE;
END IF;
IF _changed THEN
UPDATE admin.follow SET
value = NEW.value,
modified = clock_timestamp()
WHERE id = OLD.id;
END IF;
RETURN NEW;
END
$BODY$;
GRANT EXECUTE ON FUNCTION _api.follow_update()
TO rest_user;
GRANT UPDATE ON TABLE api.follow
TO rest_user;
GRANT UPDATE ON TABLE admin.follow
TO rest_user;
CREATE TRIGGER api_follow_update_trgr
INSTEAD OF UPDATE
ON api.follow
FOR EACH ROW
EXECUTE PROCEDURE _api.follow_update();

View file

@ -45,12 +45,6 @@ GRANT USAGE ON SCHEMA _api TO rest_anon, rest_user;
\i /db/rest/like/api_like_update.sql; \i /db/rest/like/api_like_update.sql;
\i /db/rest/like/api_like_delete.sql; \i /db/rest/like/api_like_delete.sql;
-- follow
\i /db/rest/follow/api_follow.sql;
\i /db/rest/follow/api_follow_insert.sql;
\i /db/rest/follow/api_follow_update.sql;
\i /db/rest/follow/api_follow_delete.sql;
-- media -- media
\i /db/rest/media/_api_serve_user_media.sql; \i /db/rest/media/_api_serve_user_media.sql;
\i /db/rest/media/_api_serve_system_media.sql; \i /db/rest/media/_api_serve_system_media.sql;

View file

@ -155,15 +155,6 @@ a, button {
background-color: var(--surface2); 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 { .btn-wide {
width: auto; width: auto;
flex-grow: 1; flex-grow: 1;
@ -446,8 +437,8 @@ input.btn:focus {
@keyframes slideIn { @keyframes slideIn {
0% { 0% {
animation-timing-function: ease-in; animation-timing-function: ease-out;
transform: translate(0, -20%); transform: translate(0, -50%);
} }
} }
@ -613,35 +604,3 @@ input[type=radio] {
width: fit-content; width: fit-content;
outline: none !important; 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;
}

View file

@ -10,14 +10,19 @@
.post, #new-post { .post, #new-post {
margin-bottom: 1rem; margin-bottom: 1rem;
max-width: 40rem; width: 40rem;
width: 100%;
} }
.post { .post {
padding-bottom: 0; padding-bottom: 0;
} }
@media(max-width: 40rem) {
.post, #new-post {
width: 100%;
}
}
.post .likes { .post .likes {
display: block; display: block;
padding-top: .25rem; padding-top: .25rem;

View file

@ -10,6 +10,7 @@
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
background-color: var(--surface0); background-color: var(--surface0);
margin-bottom: 1rem;
border-bottom: 1px solid var(--surface1); border-bottom: 1px solid var(--surface1);
} }
@ -84,9 +85,10 @@
.tab { .tab {
max-width: 80rem; max-width: 80rem;
width: 100%; width: 100%;
height: 100%;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
padding: 0 1rem;
margin-bottom: 1rem;
} }
#post-container { #post-container {
@ -104,22 +106,3 @@
td:nth-child(1) { td:nth-child(1) {
padding-right: 2rem; 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;
}

View file

@ -11,7 +11,7 @@ class Modal_controller extends Controller {
* @param array $data * @param array $data
*/ */
private function modal($name, $data = array()): void { private function modal($name, $data = array()): void {
$title = ucwords(lang($name . '_modal_title')); $title = lang($name . '_modal_title');
$data['title'] = $title; $data['title'] = $title;
$data['content'] = $name; $data['content'] = $name;
$this->view('template/modal', $data); $this->view('template/modal', $data);

View file

@ -7,7 +7,7 @@ class Auth_model extends Model {
public function get_data(): ?array { public function get_data(): ?array {
$data = parent::get_data(); $data = parent::get_data();
$data['title'] = ucfirst(lang('login')); $data['title'] = lang('login');
return $data; return $data;
} }
} }

View file

@ -8,15 +8,15 @@ class Error_model extends Model {
private function get_msg(&$data) { private function get_msg(&$data) {
if (!array_key_exists('code', $_GET)) { if (!array_key_exists('code', $_GET)) {
http_response_code(500); http_response_code(500);
$data['msg'] = ucfirst(lang('error')); $data['msg'] = lang('error');
$data['title'] = '500'; $data['title'] = '500';
} else { } else {
$code = $_GET['code']; $code = $_GET['code'];
http_response_code($code); http_response_code($code);
$data['title'] = $code; $data['title'] = $code;
$msg = ucfirst(lang('error_' . $code, FALSE)); $msg = lang('error_' . $code, FALSE);
if (!$msg) { if (!$msg) {
$msg = ucfirst(lang('error')); $msg = lang('error');
} }
$data['msg'] = $msg; $data['msg'] = $msg;
} }

View file

@ -15,7 +15,7 @@ class Home_model extends Model {
public function get_data(): ?array { public function get_data(): ?array {
$data = parent::get_data(); $data = parent::get_data();
$data['title'] = ucfirst(lang('title')); $data['title'] = lang('title');
$data['posts'] = $this->get_posts(); $data['posts'] = $this->get_posts();
return $data; return $data;
} }

View file

@ -24,15 +24,13 @@ class People_model extends Model {
case 'follower': { case 'follower': {
$query = $query $query = $query
->join('admin.follow f', 'f.follower_id = u.id AND f.followee_id', 'INNER') ->join('admin.follow f', 'f.follower_id = u.id AND f.followee_id', 'INNER')
->eq($filter_uid) ->eq($filter_uid);
->where('f.value = TRUE');
} break; } break;
case 'followee': { case 'followee': {
$query = $query $query = $query
->join('admin.follow f', 'f.followee_id = u.id AND f.follower_id', 'INNER') ->join('admin.follow f', 'f.followee_id = u.id AND f.follower_id', 'INNER')
->eq($filter_uid) ->eq($filter_uid);
->where('f.value = TRUE');
} break; } break;
} }
} }
@ -84,7 +82,7 @@ class People_model extends Model {
public function get_data(): ?array { public function get_data(): ?array {
$data = parent::get_data(); $data = parent::get_data();
$data['title'] = ucfirst(lang('title')); $data['title'] = lang('title');
return $data; return $data;
} }
} }

View file

@ -29,37 +29,9 @@ class Profile_model extends Model {
return NULL; return NULL;
} }
$following = FALSE;
$followed = FALSE;
$follow_id = NULL;
if ($this->main->session) {
$sid = $this->main->user()['id'];
$res = $this->db->select('f.value, f.id')
->from('admin.follow f')
->where('f.follower_id')
->eq($sid)
->where('f.followee_id')
->eq($uid)
->row();
$following = $res ? $res['value'] : FALSE;
$follow_id = $res ? $res['id'] : NULL;
$res = $this->db->select('f.value')
->from('admin.follow f')
->where('f.follower_id')
->eq($uid)
->where('f.followee_id')
->eq($sid)
->row();
$followed = $res ? $res['value'] : FALSE;
}
$data = parent::get_data(); $data = parent::get_data();
$data['user'] = $user; $data['user'] = $user;
$data['following'] = $following; $data['title'] = lang('title', sub: [$user['first_name']]);
$data['followed'] = $followed;
$data['follow_id'] = $follow_id;
$data['title'] = ucfirst(lang('title', sub: [$user['first_name']]));
return $data; return $data;
} }
} }

View file

@ -3,7 +3,7 @@
<div id="main-content"> <div id="main-content">
<div class="branding col"> <div class="branding col">
<h1>xssbook</h1> <h1>xssbook</h1>
<span><?=ucfirst(lang('login_branding'))?></span> <span><?=lang('login_branding')?></span>
</div> </div>
<div class="form card col"> <div class="form card col">
<form id="action-login" class="col" action=""> <form id="action-login" class="col" action="">
@ -13,10 +13,9 @@
name="username" name="username"
id="login-username" id="login-username"
placeholder=" " placeholder=" "
autofocus="true"
> >
<label for="username"> <label for="username">
<?=ucfirst(lang('ph_username'))?> <?=lang('ph_username')?>
</label> </label>
</div> </div>
<div class="rel mb"> <div class="rel mb">
@ -27,7 +26,7 @@
placeholder=" " placeholder=" "
> >
<label for="password"> <label for="password">
<?=ucfirst(lang('ph_password'))?> <?=lang('ph_password')?>
</label> </label>
</div> </div>
<?=ilang('action_login', <?=ilang('action_login',

View file

@ -2,5 +2,5 @@
<?php /* vi: syntax=php */ ?> <?php /* vi: syntax=php */ ?>
<div id="main-content"> <div id="main-content">
<h1><?=$title?></h1> <h1><?=$title?></h1>
<span><?=ucfirst($msg)?></span> <span><?=$msg?></span>
</div> </div>

View file

@ -1,6 +1,6 @@
<?php /* Copyright (c) 2024 Freya Murphy */ ?> <?php /* Copyright (c) 2024 Freya Murphy */ ?>
<?php /* vi: syntax=php */ ?> <?php /* vi: syntax=php */ ?>
<div id="main-content" class="container"> <div id="main-content">
<?php if ($self): ?> <?php if ($self): ?>
<div id="new-post" class="card"> <div id="new-post" class="card">
<div class="row grow"> <div class="row grow">
@ -9,9 +9,9 @@
id="action-new-post" id="action-new-post"
class="btn btn-alt btn-wide ml" class="btn btn-alt btn-wide ml"
autocomplete="off" autocomplete="off"
aria-label="<?=ucfirst(lang('action_new_post_tip'))?>" aria-label="<?=lang('action_new_post_tip')?>"
> >
<?=ucfirst(lang('action_new_post_text', sub: [$self['first_name']]))?> <?=lang('action_new_post_text', sub: [$self['first_name']])?>
</a> </a>
</div> </div>
<script> <script>

View file

@ -1,6 +1,6 @@
<?php /* Copyright (c) 2024 Freya Murphy */ ?> <?php /* Copyright (c) 2024 Freya Murphy */ ?>
<?php /* vi: syntax=php */ ?> <?php /* vi: syntax=php */ ?>
<div id="main-content" class="col"> <div id="main-content" class="col">
<h1 class="title"><?=ucfirst(lang('title'))?></h1> <h1 class="title"><?=lang('title')?></h1>
<h3 class="desc"><?=ucfirst(lang('desc'))?></h3> <h3 class="desc"><?=lang('desc')?></h3>
<hr> <hr>

View file

@ -8,122 +8,12 @@
<div class="pfp-wrapper"> <div class="pfp-wrapper">
<?=pfp($user)?> <?=pfp($user)?>
</div> </div>
<div class="col content grow"> <div class="col content">
<div class="row grow">
<div class="col">
<strong class="name"><?=$this->format_model->name($user)?></strong> <strong class="name"><?=$this->format_model->name($user)?></strong>
<span class="dim"><?=$user['follower_count'] . ' ' . ucfirst(lang('followers'))?></span> <span class="dim"><?=$user['follower_count'] . ' ' . lang('followers')?></span>
</div>
<?php if (
$this->main->session &&
(!isset($self) || $self['id'] != $user['id'])
): ?>
<div id="follow-container">
<?=ilang(
'action_follow',
id: 'action-follow-follow',
class: 'btn btn-alt',
style: (!$following && !$followed) ? '' : 'display: none',
sub: [$user['first_name']]
)?>
<?=ilang(
'action_follow_back',
id: 'action-follow-follow-back',
class: 'btn btn-alt',
style: (!$following && $followed) ? '' : 'display: none',
sub: [$user['first_name']]
)?>
<?=ilang(
'action_following',
id: 'action-follow-following',
class: 'btn btn-alt btn-blue',
style: ($following && !$followed) ? '' : 'display: none',
sub: [$user['first_name']]
)?>
<?=ilang(
'action_friends',
id: 'action-follow-friends',
class: 'btn btn-alt btn-blue',
style: ($following && $followed) ? '' : 'display: none',
sub: [$user['first_name']]
)?>
</div>
<script>
let following = <?=json_encode($following)?>;
let followed = <?=json_encode($followed)?>;
let followId = <?=json_encode($follow_id)?>;
let followee_id = <?=json_encode($user['id'])?>;
let btns = {};
const disableBtn = (btn) => {
btn.css('display', 'none');
};
const enableBtn = (btn) => {
btn.css('display', '');
};
const updateFollow = () => {
for (let btn of Object.values(btns)) {
disableBtn(btn);
}
if (!following && !followed) {
enableBtn(btns['follow']);
} else if (!following && followed) {
enableBtn(btns['follow-back']);
} else if (following && !followed) {
enableBtn(btns['following']);
} else if (following && followed) {
enableBtn(btns['friends']);
}
}
const onPatchFollow = (data) => {
following = data[0].value;
updateFollow();
}
const onPostFollow = (data) => {
followId = data[0].id;
following = true;
updateFollow();
}
const onClickFollow = () => {
if (followId) {
$.ajax({
url: '/api/follow?id=eq.' + followId,
method: 'PATCH',
data: JSON.stringify({ followee_id, value: !following }),
success: onPatchFollow
});
} else {
$.ajax({
url: '/api/follow',
method: 'POST',
data: JSON.stringify({ followee_id, value: !following }),
success: onPostFollow,
});
}
}
const loadBtn = (name) => {
let btn = $('#action-follow-' + name);
btn.on('click', onClickFollow);
btns[name] = btn;
};
loadBtn('follow');
loadBtn('follow-back');
loadBtn('following');
loadBtn('friends');
</script>
<?php endif; ?>
</div>
<?php if(strlen($user['profile_bio']) > 0): ?> <?php if(strlen($user['profile_bio']) > 0): ?>
<br> <br>
<strong><?=ucfirst(lang('bio'))?></strong> <strong><?=lang('bio')?></strong>
<span class="dim"><?=$user['profile_bio']?></span> <span class="dim"><?=$user['profile_bio']?></span>
<?php endif; ?> <?php endif; ?>
</div> </div>
@ -153,61 +43,60 @@
</div> </div>
</div> </div>
</div> </div>
<div id="tab-container" class="container">
<div id="tab-posts" class="tab"> <div id="tab-posts" class="tab">
<?php <?php
$_GET['user_id'] = $user['id']; $_GET['user_id'] = $user['id'];
$this->post_controller->index(); $this->post_controller->index();
?> ?>
</div> </div>
<div id="tab-about" class="tab card"> <div id="tab-about" class="tab">
<h1><?=ucfirst(lang('about_general'))?></h1> <h1><?=lang('about_general')?></h1>
<table> <table>
<tr> <tr>
<td><strong><?=ucfirst(lang('about_general_username'))?></strong></td> <td><strong><?=lang('about_general_username')?></strong></td>
<td><?=$user['username']?></td> <td><?=$user['username']?></td>
</tr> </tr>
<tr> <tr>
<td><strong><?=ucfirst(lang('about_general_full_name'))?></strong></td> <td><strong><?=lang('about_general_full_name')?></strong></td>
<td><?=$user['first_name'] . ' ' . $user['last_name']?></td> <td><?=$user['first_name'] . ' ' . $user['last_name']?></td>
</tr> </tr>
<tr> <tr>
<td><strong><?=ucfirst(lang('about_general_email'))?></strong></td> <td><strong><?=lang('about_general_email')?></strong></td>
<td><?=$user['email']?></td> <td><?=$user['email']?></td>
</tr> </tr>
<tr> <tr>
<td><strong><?=ucfirst(lang('about_general_gender'))?></strong></td> <td><strong><?=lang('about_general_gender')?></strong></td>
<td><?=$user['gender']?></td> <td><?=$user['gender']?></td>
</tr> </tr>
<tr> <tr>
<td><strong><?=ucfirst(lang('about_general_birth_date'))?></strong></td> <td><strong><?=lang('about_general_birth_date')?></strong></td>
<td><?=$user['birth_date']?></td> <td><?=$user['birth_date']?></td>
</tr> </tr>
</table> </table>
<h1><?=ucfirst(lang('about_stats'))?></h1> <h1><?=lang('about_stats')?></h1>
<table> <table>
<tr> <tr>
<td><strong><?=ucfirst(lang('about_stats_posts'))?></strong></td> <td><strong><?=lang('about_stats_posts')?></strong></td>
<td><?=$user['post_count']?></td> <td><?=$user['post_count']?></td>
</tr> </tr>
<tr> <tr>
<td><strong><?=ucfirst(lang('about_stats_like'))?></strong></td> <td><strong><?=lang('about_stats_like')?></strong></td>
<td><?=$user['like_count']?></td> <td><?=$user['like_count']?></td>
</tr> </tr>
<tr> <tr>
<td><strong><?=ucfirst(lang('about_stats_comments'))?></strong></td> <td><strong><?=lang('about_stats_comments')?></strong></td>
<td><?=$user['comment_count']?></td> <td><?=$user['comment_count']?></td>
</tr> </tr>
<tr> <tr>
<td><strong><?=ucfirst(lang('about_stats_following'))?></strong></td> <td><strong><?=lang('about_stats_following')?></strong></td>
<td><?=$user['followed_count']?></td> <td><?=$user['followed_count']?></td>
</tr> </tr>
<tr> <tr>
<td><strong><?=ucfirst(lang('about_stats_joined'))?></strong></td> <td><strong><?=lang('about_stats_joined')?></strong></td>
<td><?=$user['created']?></td> <td><?=$user['created']?></td>
</tr> </tr>
<tr> <tr>
<td><strong><?=ucfirst(lang('about_stats_seen'))?></strong></td> <td><strong><?=lang('about_stats_seen')?></strong></td>
<td><?=$user['seen']?></td> <td><?=$user['seen']?></td>
</tr> </tr>
</table> </table>

View file

@ -13,19 +13,19 @@
id="action-home" id="action-home"
class="btn<?=$this->main->info['app'] == 'home' ? ' btn-blue btn-border' : ''?>" class="btn<?=$this->main->info['app'] == 'home' ? ' btn-blue btn-border' : ''?>"
href="/home" href="/home"
title="<?=ucfirst(lang('action_home_tip'))?>" title="<?=lang('action_home_tip')?>"
> >
<i class="mi mi-lg">home</i> <i class="mi mi-lg">home</i>
<span><?=ucfirst(lang('action_home_text'))?></span> <span><?=lang('action_home_text')?></span>
</a> </a>
<a <a
id="action-people" id="action-people"
class="btn<?=$this->main->info['app'] == 'people' ? ' btn-blue btn-border' : ''?>" class="btn<?=$this->main->info['app'] == 'people' ? ' btn-blue btn-border' : ''?>"
href="/people" href="/people"
title="<?=ucfirst(lang('action_people_tip'))?>" title="<?=lang('action_people_tip')?>"
> >
<i class="mi mi-lg">people</i> <i class="mi mi-lg">people</i>
<span><?=ucfirst(lang('action_people_text'))?></span> <span><?=lang('action_people_text')?></span>
</a> </a>
<!--a <!--a
id="action-chat" id="action-chat"
@ -40,45 +40,13 @@
<div class="nav-right"> <div class="nav-right">
<button <button
id="action-hamburger" id="action-hamburger"
title="<?=ucfirst(lang('action_hamburger_tip'))?>" title="<?=lang('action_hamburger_tip')?>"
class="btn mr" class="btn mr"
> >
<i class="mi mi-lg">menu</i> <i class="mi mi-lg">menu</i>
</button> </button>
<?php if($self): ?> <?php if($self): ?>
<script> <?=pfp($self)?>
var userMenu = null;
var toggleUserMenu = () => {
userMenu.toggleClass('hidden');
}
</script>
<?=pfp($self, FALSE, 'toggleUserMenu()')?>
<div class="card col hidden" id="user-menu">
<span class="row" id="user-menu-header">
<?=pfp($self, FALSE)?>
<span class="col">
<strong><?=$this->format_model->name($self)?></strong>
<span class="dim"><?=$self['username']?></span>
</span>
</span>
<hr>
<?=ilang(
'action_profile',
class: 'btn',
href: '/profile?id=' . $self['id']
)?>
<?=ilang(
'action_settings',
class: 'btn',
href: '/settings'
)?>
<?=ilang(
'action_logout',
class: 'btn',
href: '/auth/logout'
)?>
</div>
<?php else: ?> <?php else: ?>
<?=ilang('action_login', class: 'btn', href: '/auth/login')?> <?=ilang('action_login', class: 'btn', href: '/auth/login')?>
<?php endif; ?> <?php endif; ?>
@ -90,14 +58,3 @@
}); });
</script> </script>
</header> </header>
<script>
userMenu = $('#user-menu');
var nav = $('.nav');
document.onclick = function(event) {
console.log(event.target, nav[0]);
let outside = !(nav[0].contains(event.target));
if (outside) {
userMenu.addClass('hidden');
}
};
</script>

View file

@ -9,14 +9,14 @@
<?=pfp($user)?> <?=pfp($user)?>
<div class="col ml"> <div class="col ml">
<strong><?=$user['first_name'] . ' ' . $user['last_name']?></strong> <strong><?=$user['first_name'] . ' ' . $user['last_name']?></strong>
<span class="dim"><?=ucfirst(lang('now'))?></span> <span class="dim"><?=lang('now')?></span>
</div> </div>
</div> </div>
<textarea <textarea
type="text" type="text"
name="content" name="content"
id="new-post-content" id="new-post-content"
placeholder="<?=ucfirst(lang('action_new_post_text', sub: [$user['first_name']]))?>" placeholder="<?=lang('action_new_post_text', sub: [$user['first_name']])?>"
></textarea> ></textarea>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">

View file

@ -4,7 +4,7 @@
<form id="register-form"> <form id="register-form">
<div class="modal-content register-modal col"> <div class="modal-content register-modal col">
<label class="static"> <label class="static">
<?=ucwords(lang('ph_basic_info'))?> <?=lang('ph_basic_info')?>
</label> </label>
<div class="row mt"> <div class="row mt">
<div class="rel btn-wide"> <div class="rel btn-wide">
@ -15,7 +15,7 @@
placeholder=" " placeholder=" "
> >
<label for="first_name"> <label for="first_name">
<?=ucwords(lang('ph_first_name'))?> <?=lang('ph_first_name')?>
</label> </label>
</div> </div>
<div class="rel ml btn-wide"> <div class="rel ml btn-wide">
@ -26,7 +26,7 @@
placeholder=" " placeholder=" "
> >
<label for="last_name"> <label for="last_name">
<?=ucwords(lang('ph_last_name'))?> <?=lang('ph_last_name')?>
</label> </label>
</div> </div>
</div> </div>
@ -38,7 +38,7 @@
placeholder=" " placeholder=" "
> >
<label for="username"> <label for="username">
<?=ucwords(lang('ph_username'))?> <?=lang('ph_username')?>
</label> </label>
</div> </div>
<div class="rel mt"> <div class="rel mt">
@ -49,7 +49,7 @@
placeholder=" " placeholder=" "
> >
<label for="password"> <label for="password">
<?=ucwords(lang('ph_password'))?> <?=lang('ph_password')?>
</label> </label>
</div> </div>
<div class="rel mt"> <div class="rel mt">
@ -60,11 +60,11 @@
placeholder=" " placeholder=" "
> >
<label for="email"> <label for="email">
<?=ucwords(lang('ph_email'))?> <?=lang('ph_email')?>
</label> </label>
</div> </div>
<label for="birth_date" class="mt static"> <label for="birth_date" class="mt static">
<?=ucwords(lang('ph_birth_date'))?> <?=lang('ph_birth_date')?>
</label> </label>
<input <input
class="mt" class="mt"
@ -73,7 +73,7 @@
id="register-birth-date" id="register-birth-date"
> >
<label for="gender" class="mt static"> <label for="gender" class="mt static">
<?=ucwords(lang('ph_gender'))?> <?=lang('ph_gender')?>
</label> </label>
<div class="row mt" data-type="radio" data-name="gender-wrapper"> <div class="row mt" data-type="radio" data-name="gender-wrapper">
<div class="rel radio mr"> <div class="rel radio mr">
@ -81,13 +81,13 @@
type="radio" type="radio"
id="register-gender-male" id="register-gender-male"
name="gender" name="gender"
value="Male" value="male"
> >
<label <label
for="register-gender-male" for="register-gender-male"
class="static" class="static"
> >
<?=ucwords(lang('ph_gender_male'))?> <?=lang('ph_gender_male')?>
</label> </label>
</div> </div>
<div class="rel radio mr"> <div class="rel radio mr">
@ -95,13 +95,13 @@
type="radio" type="radio"
id="register-gender-female" id="register-gender-female"
name="gender" name="gender"
value="Female" value="female"
> >
<label <label
for="register-gender-female" for="register-gender-female"
class="static" class="static"
> >
<?=ucwords(lang('ph_gender_female'))?> <?=lang('ph_gender_female')?>
</label> </label>
</div> </div>
<div class="rel radio"> <div class="rel radio">
@ -109,13 +109,13 @@
type="radio" type="radio"
id="register-gender-lettuce" id="register-gender-lettuce"
name="gender" name="gender"
value="Lettuce" value="lettuce"
> >
<label <label
for="register-gender-lettuce" for="register-gender-lettuce"
class="static" class="static"
> >
<?=ucwords(lang('ph_gender_lettuce'))?> <?=lang('ph_gender_lettuce')?>
</label> </label>
</div> </div>
</div> </div>

View file

@ -21,7 +21,7 @@
$post_attrs['likeId'] = $post['like_id']; $post_attrs['likeId'] = $post['like_id'];
} }
?> ?>
<span class="likes dim"><span class="count"><?=$post['like_count']?></span><?=' ' . ucfirst(lang('likes'))?></span> <span class="likes dim"><span class="count"><?=$post['like_count']?></span><?=' ' . lang('likes')?></span>
<?php if ($self): ?> <?php if ($self): ?>
<hr> <hr>
<div class="row"> <div class="row">
@ -76,8 +76,8 @@
autocomplete="off" autocomplete="off"
type="text" type="text"
name="text" name="text"
placeholder="<?=ucfirst(lang('action_new_comment_text'))?>" placeholder="<?=lang('action_new_comment_text')?>"
aria-label="<?=ucfirst(lang('action_new_comment_tip'))?>" aria-label="<?=lang('action_new_comment_tip')?>"
> >
</form> </form>
</div> </div>

View file

@ -10,9 +10,6 @@ abstract class Controller {
// the database // the database
public $db; public $db;
// the format model
protected $format_model;
/** /**
* Creates a constructor * Creates a constructor
* @param Loader $load - the website loaded object * @param Loader $load - the website loaded object
@ -29,8 +26,6 @@ abstract class Controller {
if ($app) { if ($app) {
$this->load->app_lang($lang, $app); $this->load->app_lang($lang, $app);
} }
$this->format_model = $this->load->model('format');
} }
public function index() {} public function index() {}

View file

@ -1,6 +1,6 @@
<?php /* Copyright (c) 2024 Freya Murphy */ <?php /* Copyright (c) 2024 Freya Murphy */
function image($src, $class = NULL, $link = NULL, $click = NULL): string { function image($src, $class = NULL, $link = NULL): string {
if ($class) { if ($class) {
$class = 'image-loading ' . $class; $class = 'image-loading ' . $class;
} else { } else {
@ -11,16 +11,12 @@ function image($src, $class = NULL, $link = NULL, $click = NULL): string {
if ($link) { if ($link) {
$content .= '<a class="' . $class . '" href="' . $link . '">'; $content .= '<a class="' . $class . '" href="' . $link . '">';
} else if ($click) {
$content .= '<button class="' . $class . '" onclick="' . $click . '">';
} else { } else {
$content .= '<span class="' . $class . '">'; $content .= '<span class="' . $class . '">';
} }
$content .= '<img src="' . $src . '" onerror="onImgError(this)" onload="onImgLoad(this)"/>'; $content .= '<img src="' . $src . '" onerror="onImgError(this)" onload="onImgLoad(this)"/>';
if ($link) { if ($link) {
$content .= '</a>'; $content .= '</a>';
} else if ($click) {
$content .= '</button>';
} else { } else {
$content .= '</span>'; $content .= '</span>';
} }
@ -30,11 +26,8 @@ function image($src, $class = NULL, $link = NULL, $click = NULL): string {
function pfp( function pfp(
$user, $user,
$link = TRUE, $embedLink = TRUE,
$click = NULL
): string { ): string {
if ($link === TRUE) { $link = $embedLink ? '/profile?id=' . $user['id'] : NULL;
$link = '/profile?id=' . $user['id']; return image('/api/rpc/profile_avatar?user_id=' . $user['id'], 'pfp', link: $link);
}
return image('/api/rpc/profile_avatar?user_id=' . $user['id'], 'pfp', link: $link, click: $click);
} }

View file

@ -18,7 +18,6 @@ function lang($key, $default = NULL, $sub = NULL) {
function ilang($key, function ilang($key,
$class = NULL, $class = NULL,
$style = NULL,
$id = NULL, $id = NULL,
$href = NULL, $href = NULL,
$click = NULL, $click = NULL,
@ -26,7 +25,7 @@ function ilang($key,
$sub = NULL, $sub = NULL,
$button = FALSE, $button = FALSE,
) { ) {
$text = ucfirst(lang($key . "_text", FALSE, sub: $sub)); $text = lang($key . "_text", FALSE, sub: $sub);
$tip = lang($key . "_tip", FALSE, sub: $sub); $tip = lang($key . "_tip", FALSE, sub: $sub);
$icon = lang($key . "_icon", FALSE); $icon = lang($key . "_icon", FALSE);
$content = lang($key . "_content", FALSE); $content = lang($key . "_content", FALSE);
@ -43,9 +42,6 @@ function ilang($key,
if ($class) { if ($class) {
echo 'class="' . $class . '" '; echo 'class="' . $class . '" ';
} }
if ($style) {
echo 'style="' . $style . '" ';
}
if ($id) { if ($id) {
echo 'id="' . $id . '" '; echo 'id="' . $id . '" ';
} }

View file

@ -1,19 +0,0 @@
#
# en_CAT generator from en_US
# uwuify and awk required
#
LANG_SRC = $(shell find en_US -type f)
LANG_OBJ = $(patsubst en_US/%,en_CAT/%,$(LANG_SRC))
.PHONY: all
all: $(LANG_OBJ)
$(LANG_OBJ): en_CAT/% : en_US/%
@printf "\033[35m UWU \033[0m%s\n" $<
@mkdir -p $(@D)
@./_bin/transpile.sh $< $@
clean:
@rm -fr "en_CAT"

View file

@ -1,29 +0,0 @@
#!/bin/sh
lang_part() {
echo "$1" | awk "{split(\$0,a,\" = \"); print a[$2]}"
}
export -f lang_part
handle_line() {
line="$1"
left=$(lang_part "$line" 1)
right=$(lang_part "$line" 2)
echo "$left" | grep -Ev '_content|_line' > /dev/null
if [ "$?" -eq 0 ]; then
right=$(echo "$right" | uwuify)
fi;
right=${right%;};
echo "$left = $right;"
}
export -f handle_line
transpile() {
file="$1"
out="$2"
printf "" > "$out"
printf "<?php /* Copyright (c) 2024 Freya Murphy */\n\n" > "$out";
cat "$file" | grep '$lang' | xargs -d'\n' -I {} bash -c 'handle_line "$@"' _ {} >> "$out"
}
transpile "$1" "$2"

View file

@ -16,15 +16,6 @@ $lang['action_followers_tip'] = 'View %s\'s followres';
$lang['action_following_text'] = 'Following'; $lang['action_following_text'] = 'Following';
$lang['action_following_tip'] = 'View who %s is following'; $lang['action_following_tip'] = 'View who %s is following';
$lang['action_follow_text'] = 'Follow';
$lang['action_follow_tip'] = 'Follow %s';
$lang['action_follow_back_text'] = 'Follow Back';
$lang['action_follow_back_tip'] = 'Follow %s';
$lang['action_following_text'] = 'Followed';
$lang['action_following_tip'] = 'Unfollow %s';
$lang['action_friends_text'] = 'Friends';
$lang['action_friends_tip'] = 'Unfollow %s';
$lang['action_load_posts_text'] = 'Load more posts'; $lang['action_load_posts_text'] = 'Load more posts';
$lang['action_load_posts_tip'] = 'Load more posts'; $lang['action_load_posts_tip'] = 'Load more posts';

View file

@ -44,20 +44,6 @@ $lang['new_post_modal_title'] = 'Author New Post';
$lang['action_new_post_text'] = 'What\'s on your mind, %s'; $lang['action_new_post_text'] = 'What\'s on your mind, %s';
$lang['action_new_post_tip'] = 'Author a new post.'; $lang['action_new_post_tip'] = 'Author a new post.';
// User Menu
$lang['action_logout_text'] = 'Logout';
$lang['action_logout_tip'] = 'Logout';
$lang['action_logout_icon'] = 'mi mi-sm';
$lang['action_logout_content'] = 'logout';
$lang['action_settings_text'] = 'Settings';
$lang['action_settings_tip'] = 'Edit account settings';
$lang['action_settings_icon'] = 'mi mi-sm';
$lang['action_settings_content'] = 'settings';
$lang['action_profile_text'] = 'Profile';
$lang['action_profile_tip'] = 'View your profile';
$lang['action_profile_icon'] = 'mi mi-sm';
$lang['action_profile_content'] = 'account_circle';
// Words // Words
$lang['now'] = 'Now'; $lang['now'] = 'Now';
$lang['likes'] = 'Likes'; $lang['likes'] = 'Likes';