start custom banner and avatar loading

This commit is contained in:
Freya Murphy 2024-04-01 15:02:51 -04:00
parent 3a82baec9d
commit 9ed46c335d
Signed by: freya
GPG key ID: 744AB800E383AE52
9 changed files with 153 additions and 33 deletions

44
src/db/bak/avatar.sql Normal file

File diff suppressed because one or more lines are too long

View file

@ -187,16 +187,61 @@ ALTER TABLE ONLY admin.follow
ALTER TABLE ONLY admin.follow
ADD CONSTRAINT follow_follower_unique UNIQUE (follower_id, followee_id);
CREATE SEQUENCE IF NOT EXISTS sys.media_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
CREATE TABLE admin.media (
id INTEGER DEFAULT nextval('sys.media_id_seq'::regclass) NOT NULL,
name TEXT NOT NULL,
content BYTEA NOT NULL,
type TEXT NOT NULL
type TEXT NOT NULL,
created TIMESTAMP WITH TIME ZONE DEFAULT clock_timestamp() NOT NULL,
modified TIMESTAMP WITH TIME ZONE DEFAULT clock_timestamp() NOT NULL
);
ALTER TABLE admin.media OWNER TO xssbook;
ALTER TABLE ONLY admin.media
ADD CONSTRAINT media_pkey PRIMARY KEY (name);
ADD CONSTRAINT media_pkey PRIMARY KEY (id);
ALTER TABLE ONLY admin.media
ADD CONSTRAINT media_name_unique UNIQUE (name);
CREATE SEQUENCE IF NOT EXISTS sys.user_media_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
CREATE TYPE admin.user_media_type AS ENUM (
'avatar', 'banner'
);
CREATE TABLE admin.user_media (
id INTEGER DEFAULT nextval('sys.user_media_id_seq'::regclass) NOT NULL,
media_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
type admin.user_media_type NOT NULL
);
ALTER TABLE admin.user_media OWNER TO xssbook;
ALTER TABLE ONLY admin.user_media
ADD CONSTRAINT user_media_pkey PRIMARY KEY (id);
ALTER TABLE ONLY admin.user_media
ADD CONSTRAINT user_media_media_id_fkey FOREIGN KEY (media_id) REFERENCES admin.media (id) ON DELETE CASCADE;
ALTER TABLE ONLY admin.user_media
ADD CONSTRAINT user_media_user_id_fkey FOREIGN KEY (user_id) REFERENCES admin.user (id) ON DELETE CASCADE;
ALTER TABLE ONLY admin.user_media
ADD CONSTRAINT user_media_type_unique UNIQUE (user_id, type);
ALTER DATABASE xssbook SET search_path = admin,public;
ALTER DATABASE xssbook SET bytea_output = 'hex';

View file

@ -0,0 +1,36 @@
CREATE FUNCTION api.profile_avatar(
user_id INTEGER DEFAULT 0
)
RETURNS sys."*/*"
LANGUAGE plpgsql VOLATILE
AS $BODY$
DECLARE
_id INTEGER;
_mod INTEGER;
_name TEXT;
BEGIN
SELECT media_id INTO _id
FROM admin.user_media m
WHERE m.user_id = profile_avatar.user_id
AND type = 'avatar'::admin.user_media_type;
-- get default if not exists
IF NOT FOUND THEN
_mod = MOD(user_id, 24);
_name = 'default_avatar_' || _mod || '.png';
SELECT id INTO _id
FROM admin.media
WHERE name = _name;
END IF;
RETURN _api.serve_media(_id);
END
$BODY$;
GRANT EXECUTE ON FUNCTION api.profile_avatar(INTEGER)
TO rest_anon, rest_user;
GRANT SELECT ON TABLE admin.user_media
TO rest_anon, rest_user;
GRANT SELECT ON TABLE admin.media
TO rest_anon, rest_user;

View file

@ -0,0 +1,13 @@
CREATE FUNCTION api.profile_banner(
user_id INTEGER DEFAULT 0
)
RETURNS sys."*/*"
LANGUAGE plpgsql VOLATILE
AS $BODY$
BEGIN
PERFORM _api.raise_deny();
END
$BODY$;
GRANT EXECUTE ON FUNCTION api.profile_banner(INTEGER)
TO rest_anon, rest_user;

View file

@ -27,7 +27,6 @@ GRANT USAGE ON SCHEMA _api TO rest_anon, rest_user;
\i /db/rest/user/api_user_insert.sql;
\i /db/rest/user/api_user_update.sql;
\i /db/rest/user/api_user_delete.sql;
\i /db/rest/user/api_avatar.sql;
-- post
\i /db/rest/post/api_post.sql;
@ -47,6 +46,10 @@ 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;
-- media
\i /db/rest/media/api_profile_avatar.sql;
\i /db/rest/media/api_profile_banner.sql;
-- login
\i /db/rest/login/_api_sign_jwt.sql;
\i /db/rest/login/_api_verify_jwt.sql;

View file

@ -1,22 +0,0 @@
CREATE FUNCTION api.avatar(
user_id INTEGER DEFAULT 0
)
RETURNS sys."*/*"
LANGUAGE plpgsql VOLATILE
AS $BODY$
DECLARE
_mod INTEGER;
_name TEXT;
BEGIN
_mod = MOD(user_id, 24);
_name = 'default_avatar_' || _mod || '.png';
RETURN _api.serve_media(_name);
END
$BODY$;
GRANT EXECUTE ON FUNCTION api.avatar(INTEGER)
TO rest_anon, rest_user;
GRANT SELECT ON TABLE admin.user
TO rest_anon, rest_user;
GRANT SELECT ON TABLE admin.media
TO rest_anon, rest_user;

View file

@ -1,5 +1,5 @@
CREATE FUNCTION _api.serve_media(
_name TEXT
_media_id INTEGER
)
RETURNS sys."*/*"
LANGUAGE plpgsql VOLATILE
@ -15,13 +15,13 @@ BEGIN
'{"Cache-Control": "max-age=259200"}]'
, m.type, m.name)
FROM admin.media m
WHERE m.name = _name INTO _headers;
WHERE m.id = _media_id INTO _headers;
PERFORM SET_CONFIG('response.headers', _headers, true);
SELECT m.content
FROM admin.media m
WHERE m.name = _name
WHERE m.id = _media_id
INTO _data;
IF FOUND THEN
@ -35,7 +35,7 @@ BEGIN
END
$BODY$;
GRANT EXECUTE ON FUNCTION _api.serve_media(TEXT)
GRANT EXECUTE ON FUNCTION _api.serve_media(INTEGER)
TO rest_anon, rest_user;
GRANT SELECT ON TABLE admin.media
TO rest_anon, rest_user;

View file

@ -12,7 +12,8 @@ var $$ = (selector) => {
'on',
'click',
'submit',
'each'
'each',
'error'
];
let vtable = {};

View file

@ -4,5 +4,5 @@
$class = isset($class) ? $class : '';
?>
<a class="image-loading pfp <?=$class?>" href="/profile?id=<?=$user['id']?>">
<img src="/api/rpc/avatar?user_id=<?=$user['id']?>" />
<img src="/api/rpc/profile_avatar?user_id=<?=$user['id']?>"/>
</a>