diff --git a/app/api/alpha/utils/site.py b/app/api/alpha/utils/site.py index 980cfe6b..3ade562a 100644 --- a/app/api/alpha/utils/site.py +++ b/app/api/alpha/utils/site.py @@ -1,18 +1,65 @@ -from app import db +from app import cache, db from app.api.alpha.views import user_view, community_view, instance_view from app.api.alpha.utils.validators import required, integer_expected, boolean_expected from app.utils import authorise_api_user -from app.models import InstanceBlock, Language +from app.models import CommunityMember, InstanceBlock, Language from app.shared.site import block_remote_instance, unblock_remote_instance from flask import current_app, g from sqlalchemy import text +@cache.memoize(timeout=86400) def users_total(): return db.session.execute(text( 'SELECT COUNT(id) as c FROM "user" WHERE ap_id is null AND verified is true AND banned is false AND deleted is false')).scalar() + +@cache.memoize(timeout=86400) +def moderating_communities(user): + cms = CommunityMember.query.filter_by(user_id=user.id, is_moderator=True) + moderates = [] + for cm in cms: + moderates.append({'community': community_view(cm.community_id, variant=1, stub=True), 'moderator': user_view(user, variant=1, stub=True)}) + return moderates + + +@cache.memoize(timeout=86400) +def joined_communities(user): + cms = CommunityMember.query.filter_by(user_id=user.id, is_banned=False) + follows = [] + for cm in cms: + follows.append({'community': community_view(cm.community_id, variant=1, stub=True), 'follower': user_view(user, variant=1, stub=True)}) + return follows + + +@cache.memoize(timeout=86400) +def blocked_people(user): + blocked = [] + blocked_ids = db.session.execute(text('SELECT blocked_id FROM "user_block" WHERE blocker_id = :blocker_id'), {"blocker_id": user.id}).scalars() + for blocked_id in blocked_ids: + blocked.append({'person': user_view(user, variant=1, stub=True), 'target': user_view(blocked_id, variant=1, stub=True)}) + return blocked + + +@cache.memoize(timeout=86400) +def blocked_communities(user): + blocked = [] + blocked_ids = db.session.execute(text('SELECT community_id FROM "community_block" WHERE user_id = :user_id'), {"user_id": user.id}).scalars() + for blocked_id in blocked_ids: + blocked.append({'person': user_view(user, variant=1, stub=True), 'community': community_view(blocked_id, variant=1, stub=True)}) + return blocked + + +@cache.memoize(timeout=86400) +def blocked_instances(user): + blocked = [] + blocked_ids = db.session.execute(text('SELECT instance_id FROM "instance_block" WHERE user_id = :user_id'), {"user_id": user.id}).scalars() + for blocked_id in blocked_ids: + blocked.append({'person': user_view(user, variant=1, stub=True), 'instance': instance_view(blocked_id, variant=1)}) + return blocked + + def get_site(auth): if auth: user = authorise_api_user(auth, return_type='model') @@ -74,31 +121,13 @@ def get_site(auth): "comment_count": user.post_reply_count } }, - #"moderates": [], - #"follows": [], - "community_blocks": [], - "instance_blocks": [], - "person_blocks": [], + "moderates": moderating_communities(user), + "follows": joined_communities(user), + "community_blocks": blocked_communities(user), + "instance_blocks": blocked_instances(user), + "person_blocks": blocked_people(user), "discussion_languages": [] # TODO } - """ - Note: Thunder doesn't use moderates[] and follows[] from here, but it would be more efficient if it did (rather than getting them from /user and /community) - cms = CommunityMember.query.filter_by(user_id=user_id, is_moderator=True) - for cm in cms: - my_user['moderates'].append({'community': Community.api_json(variant=1, id=cm.community_id, stub=True), 'moderator': User.api_json(variant=1, id=user_id, stub=True)}) - cms = CommunityMember.query.filter_by(user_id=user_id, is_banned=False) - for cm in cms: - my_user['follows'].append({'community': Community.api_json(variant=1, id=cm.community_id, stub=True), 'follower': User.api_json(variant=1, id=user_id, stub=True)}) - """ - blocked_ids = db.session.execute(text('SELECT blocked_id FROM "user_block" WHERE blocker_id = :blocker_id'), {"blocker_id": user.id}).scalars() - for blocked_id in blocked_ids: - my_user['person_blocks'].append({'person': user_view(user, variant=1, stub=True), 'target': user_view(blocked_id, variant=1, stub=True)}) - blocked_ids = db.session.execute(text('SELECT community_id FROM "community_block" WHERE user_id = :user_id'), {"user_id": user.id}).scalars() - for blocked_id in blocked_ids: - my_user['community_blocks'].append({'person': user_view(user, variant=1, stub=True), 'community': community_view(blocked_id, variant=1, stub=True)}) - blocked_ids = db.session.execute(text('SELECT instance_id FROM "instance_block" WHERE user_id = :user_id'), {"user_id": user.id}).scalars() - for blocked_id in blocked_ids: - my_user['instance_blocks'].append({'person': user_view(user, variant=1, stub=True), 'instance': instance_view(blocked_id, variant=1)}) data = { "version": "1.0.0", "site": site diff --git a/app/api/alpha/views.py b/app/api/alpha/views.py index 107b15d7..3270ec94 100644 --- a/app/api/alpha/views.py +++ b/app/api/alpha/views.py @@ -173,7 +173,8 @@ def cached_community_view_variant_1(community: Community, stub=False): 'actor_id': community.public_url(), 'local': community.is_local(), 'hidden': not community.show_all, - 'instance_id': community.instance_id if community.instance_id else 1}) + 'instance_id': community.instance_id if community.instance_id else 1, + 'ap_domain': community.ap_domain}) if community.description and not stub: v1['description'] = community.description if community.icon_id: diff --git a/app/templates/themes/x_api/js/site.js b/app/templates/themes/x_api/js/site.js index 2267c5cc..7c4b1993 100644 --- a/app/templates/themes/x_api/js/site.js +++ b/app/templates/themes/x_api/js/site.js @@ -14,36 +14,22 @@ if (session_jwt != null) { } export { jwt }; -const ul = document.getElementById('navbar_items'); +const navbar = document.getElementById('navbar_items'); if (jwt != null) { var request = {method: "GET", headers: {Authorization: `Bearer ${jwt}`}}; - ul.innerHTML = '' + - - '' + - - '' + - - ''; } else { var request = {method: "GET"}; - ul.innerHTML = '' + - '' + - '' + - ''; + navbar.innerHTML = '' + + '' + + '' + + ''; } fetch(api, request) @@ -60,6 +46,88 @@ fetch(api, request) // navbar document.querySelector('#navbar_title').innerHTML = 'Logo' + ' ' + data.site.name; + if (jwt != null) { + const all_communities_item = document.createElement('li'); + all_communities_item.innerHTML = 'All communities' + + const communities_menu = document.createElement('ul'); + communities_menu.className = 'dropdown-menu' + communities_menu.appendChild(all_communities_item) + + if (data.my_user.moderates.length > 0) { + const dropdown_divider = document.createElement('li'); + dropdown_divider.innerHTML = '' + communities_menu.appendChild(dropdown_divider) + const dropdown_header = document.createElement('li'); + dropdown_header.innerHTML = '' + communities_menu.appendChild(dropdown_header) + + for (let mods of data.my_user.moderates) { + let moderated_community_item = document.createElement('li'); + if (mods.community.local) { + moderated_community_item.innerHTML = '' + + mods.community.title + '' + ' (' + mods.community.ap_domain + ')' + + '' + } else { + moderated_community_item.innerHTML = '' + + mods.community.title + '' + ' (' + mods.community.ap_domain + ')' + + '' + } + communities_menu.appendChild(moderated_community_item) + } + } + + if (data.my_user.follows.length > 0) { + const dropdown_divider = document.createElement('li'); + dropdown_divider.innerHTML = '' + communities_menu.appendChild(dropdown_divider) + const dropdown_header = document.createElement('li'); + dropdown_header.innerHTML = '' + communities_menu.appendChild(dropdown_header) + + for (let follows of data.my_user.follows) { + let followed_community_item = document.createElement('li'); + if (follows.community.local) { + followed_community_item.innerHTML = '' + + follows.community.title + '' + ' (' + follows.community.ap_domain + ')' + + '' + } else { + followed_community_item.innerHTML = '' + + follows.community.title + '' + ' (' + follows.community.ap_domain + ')' + + '' + } + communities_menu.appendChild(followed_community_item) + } + } + + const communities_item = document.createElement('li') + communities_item.className = 'nav-item dropdown' + communities_item.innerHTML = '' + communities_item.appendChild(communities_menu) + navbar.appendChild(communities_item) + + + + /*const login_item = document.createElement('li') + login_item.className = 'nav-item' + login_item.innerHTML = 'Log in (via API)' + ul.appendChild(login_item) + + const communities_dropdown = document.createElement('li') + communities_dropdown.className = 'nav-item dropdown' + communities_dropdown.innerHTML = '' + const communities_dropdown_ul = document.createElement('ul') + communities_dropdown_ul.className = 'dropdown-menu' + const communities_dropdown_ul_item = document.createElement('li') + communities_dropdown_ul_item.className = 'dropdown-item' + communities_dropdown_ul_item.href = '/api/alpha/communities' + communities_dropdown_ul.appendChild(communities_dropdown_ul_item) + communities_dropdown.appendChild(communities_dropdown_ul) + ul.appendChild(communities_dropdown)*/ + } + // site info document.querySelector('#site_json').textContent = JSON.stringify(data, null, 2); })