From b6ae609ee3186148836f96260aa203202f230d6a Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Fri, 5 Apr 2024 12:58:11 -0400 Subject: [PATCH] follow ppl --- src/db/rest/follow/api_follow.sql | 15 ++ src/db/rest/follow/api_follow_delete.sql | 32 +++ src/db/rest/follow/api_follow_insert.sql | 46 ++++ src/db/rest/follow/api_follow_update.sql | 44 ++++ src/db/rest/rest.sql | 6 + src/public/css/common.css | 17 ++ src/public/css/post.css | 9 +- src/public/css/profile.css | 23 +- src/web/_model/apps/people.php | 6 +- src/web/_model/apps/profile.php | 28 +++ src/web/_views/apps/home/main.php | 2 +- src/web/_views/apps/profile/main.php | 254 ++++++++++++++++------- src/web/helper/lang.php | 4 + src/web/lang/en_US/apps/profile.php | 9 + 14 files changed, 409 insertions(+), 86 deletions(-) create mode 100644 src/db/rest/follow/api_follow.sql create mode 100644 src/db/rest/follow/api_follow_delete.sql create mode 100644 src/db/rest/follow/api_follow_insert.sql create mode 100644 src/db/rest/follow/api_follow_update.sql diff --git a/src/db/rest/follow/api_follow.sql b/src/db/rest/follow/api_follow.sql new file mode 100644 index 0000000..c0a07e5 --- /dev/null +++ b/src/db/rest/follow/api_follow.sql @@ -0,0 +1,15 @@ +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; diff --git a/src/db/rest/follow/api_follow_delete.sql b/src/db/rest/follow/api_follow_delete.sql new file mode 100644 index 0000000..46454cf --- /dev/null +++ b/src/db/rest/follow/api_follow_delete.sql @@ -0,0 +1,32 @@ +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(); diff --git a/src/db/rest/follow/api_follow_insert.sql b/src/db/rest/follow/api_follow_insert.sql new file mode 100644 index 0000000..6351855 --- /dev/null +++ b/src/db/rest/follow/api_follow_insert.sql @@ -0,0 +1,46 @@ +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(); diff --git a/src/db/rest/follow/api_follow_update.sql b/src/db/rest/follow/api_follow_update.sql new file mode 100644 index 0000000..2164829 --- /dev/null +++ b/src/db/rest/follow/api_follow_update.sql @@ -0,0 +1,44 @@ +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(); diff --git a/src/db/rest/rest.sql b/src/db/rest/rest.sql index 783866a..3db77a2 100644 --- a/src/db/rest/rest.sql +++ b/src/db/rest/rest.sql @@ -45,6 +45,12 @@ GRANT USAGE ON SCHEMA _api TO rest_anon, rest_user; \i /db/rest/like/api_like_update.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 \i /db/rest/media/_api_serve_user_media.sql; \i /db/rest/media/_api_serve_system_media.sql; diff --git a/src/public/css/common.css b/src/public/css/common.css index 281df6b..3e6b6b6 100644 --- a/src/public/css/common.css +++ b/src/public/css/common.css @@ -155,6 +155,15 @@ a, button { 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; @@ -604,3 +613,11 @@ input[type=radio] { width: fit-content; outline: none !important; } + +.container { + padding: 1rem; +} + +.grow { + flex-grow: 1; +} diff --git a/src/public/css/post.css b/src/public/css/post.css index 2b6a4b1..47106a9 100644 --- a/src/public/css/post.css +++ b/src/public/css/post.css @@ -10,19 +10,14 @@ .post, #new-post { margin-bottom: 1rem; - width: 40rem; + max-width: 40rem; + width: 100%; } .post { padding-bottom: 0; } -@media(max-width: 40rem) { - .post, #new-post { - width: 100%; - } -} - .post .likes { display: block; padding-top: .25rem; diff --git a/src/public/css/profile.css b/src/public/css/profile.css index 71cbbfa..a6f2ef4 100644 --- a/src/public/css/profile.css +++ b/src/public/css/profile.css @@ -10,7 +10,6 @@ flex-direction: row; justify-content: center; background-color: var(--surface0); - margin-bottom: 1rem; border-bottom: 1px solid var(--surface1); } @@ -85,10 +84,9 @@ .tab { max-width: 80rem; width: 100%; + height: 100%; margin-left: auto; margin-right: auto; - padding: 0 1rem; - margin-bottom: 1rem; } #post-container { @@ -106,3 +104,22 @@ 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/web/_model/apps/people.php b/src/web/_model/apps/people.php index ade59d3..4287094 100644 --- a/src/web/_model/apps/people.php +++ b/src/web/_model/apps/people.php @@ -24,13 +24,15 @@ class People_model extends Model { case 'follower': { $query = $query ->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; case 'followee': { $query = $query ->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; } } diff --git a/src/web/_model/apps/profile.php b/src/web/_model/apps/profile.php index 592fbcb..97b0150 100644 --- a/src/web/_model/apps/profile.php +++ b/src/web/_model/apps/profile.php @@ -29,8 +29,36 @@ class Profile_model extends Model { 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['user'] = $user; + $data['following'] = $following; + $data['followed'] = $followed; + $data['follow_id'] = $follow_id; $data['title'] = lang('title', sub: [$user['first_name']]); return $data; } diff --git a/src/web/_views/apps/home/main.php b/src/web/_views/apps/home/main.php index 735e3d8..60c3eb9 100644 --- a/src/web/_views/apps/home/main.php +++ b/src/web/_views/apps/home/main.php @@ -1,6 +1,6 @@ -
+
diff --git a/src/web/_views/apps/profile/main.php b/src/web/_views/apps/profile/main.php index e3d65b5..6671d87 100644 --- a/src/web/_views/apps/profile/main.php +++ b/src/web/_views/apps/profile/main.php @@ -8,9 +8,116 @@
-
- format_model->name($user)?> - +
+
+
+ format_model->name($user)?> + +
+ +
+ + + + +
+ + +
0): ?>
@@ -43,78 +150,79 @@
-
+
+
+ post_controller->index(); + ?> +
+
+

+ + + + + + + + + + + + + + + + + + + + + +
+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
post_controller->index(); + $_GET['filter'] = 'follower'; + $_GET['uid'] = $user['id']; + $this->people_controller->content(); ?> -
-
-

- - - - - - - - - - - - - - - - - - - - - -
-

- - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
- people_controller->content(); - ?> -
-
- people_controller->content(); - ?> -
+
+
+ people_controller->content(); + ?> +