Skip to content

Commit

Permalink
Merge pull request #457 from fluxsocial/agent-visibility-channel
Browse files Browse the repository at this point in the history
Agent visibility channel
  • Loading branch information
lucksus authored Dec 14, 2023
2 parents f838d2a + 06a369a commit 1d982d2
Show file tree
Hide file tree
Showing 9 changed files with 12,212 additions and 51 deletions.
6 changes: 5 additions & 1 deletion app/src/containers/CreateCommunity.vue
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,11 @@ export default defineComponent({
const langExpression = await client.expression.getMany(
linkLangs.map((l) => `lang://${l}`)
);
const langMeta = langExpression.map((l) => JSON.parse(l.data)).filter(l => !l.description.includes("Holochain"));
const langMeta = langExpression
.map((l) => JSON.parse(l.data))
.filter((l) => !l.description.includes("Holochain"));
const { perspectives, neighbourhoods } = usePerspectives(client);
const { communities } = useCommunities(neighbourhoods);
Expand Down
42 changes: 42 additions & 0 deletions app/src/views/community/community-sidebar/ActiveAgent.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<template>
<div>
<Avatar
size="xxs"
:did="did"
:url="profile?.profileThumbnailPicture"
></Avatar>
</div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import Avatar from "@/components/avatar/Avatar.vue";
// @ts-ignore
import { getAd4mClient } from "@coasys/ad4m-connect/utils";
import { useAgent } from "@coasys/flux-vue";
import { Ad4mClient } from "@coasys/ad4m";
export default defineComponent({
components: { Avatar },
props: {
did: {
type: String,
required: true,
},
},
async setup(props) {
const client: Ad4mClient = await getAd4mClient();
const { profile } = useAgent(client.agent, () => props.did);
return {
profile,
};
},
computed: {},
methods: {},
});
</script>

<style lang="scss" scoped></style>
154 changes: 115 additions & 39 deletions app/src/views/community/community-sidebar/ChannelList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,10 @@
tag="j-menu-item"
class="channel"
:class="{ 'channel--muted': channel.notifications?.mute }"
:selected="
channel.id === $route.params.channelId && !channel.expanded
"
:selected="channel.id === activeChannelId && !channel.expanded"
@click="() => navigateToChannel(channel.id)"
>
{{ channel.name }}
<j-icon
size="xs"
slot="end"
v-if="channel?.notifications?.mute"
name="bell-slash"
/>
<div
slot="end"
class="channel__notification"
Expand All @@ -43,6 +35,14 @@
size="xs"
:name="getIcon(channel.views[0])"
></j-icon>
<div class="active-agents">
<j-box
v-for="(agent, did) in activeAgents[channel.id]"
:key="did"
>
<ActiveAgent :key="did" :did="did" v-if="agent" />
</j-box>
</div>
</j-menu-item>
<div class="channel-views" v-if="channel.expanded">
<j-menu-item
Expand All @@ -67,21 +67,6 @@
<j-icon size="xs" slot="start" name="pencil" />
Edit Channel
</j-menu-item>
<j-menu-item
@click="
() =>
setChannelNotificationState({
channelId: channel.id,
})
"
>
<j-icon
size="xs"
slot="start"
:name="channel?.notifications?.mute ? 'bell-slash' : 'bell'"
/>
{{ `${channel?.notifications?.mute ? "Unmute" : "Mute"} Channel` }}
</j-menu-item>
<j-menu-item
v-if="isChannelCreator(channel.id)"
@click="() => deleteChannel(channel.id)"
Expand All @@ -100,45 +85,60 @@
</template>

<script lang="ts">
import { defineComponent, ref, watch } from "vue";
import { useRoute } from "vue-router";
import { defineComponent, ref } from "vue";
import { mapActions } from "pinia";
import { useAppStore } from "@/store/app";
import { Channel } from "@coasys/flux-api";
import { useSubjects, usePerspective, useMe } from "@coasys/flux-vue";
import { useSubjects, useMe } from "@coasys/flux-vue";
import { ChannelView } from "@coasys/flux-types";
import { viewOptions as channelViewOptions } from "@/constants";
import { Ad4mClient } from "@coasys/ad4m";
import {
Ad4mClient,
NeighbourhoodProxy,
PerspectiveProxy,
PerspectiveExpression,
} from "@coasys/ad4m";
import { getAd4mClient } from "@coasys/ad4m-connect/utils";
import ActiveAgent from "./ActiveAgent.vue";
export default defineComponent({
components: { ActiveAgent },
props: {
community: {
type: Object,
required: true,
},
perspective: {
type: Object,
type: PerspectiveProxy,
required: true,
},
},
async setup(props) {
const route = useRoute();
const client: Ad4mClient = await getAd4mClient();
mounted() {
this.neighbhourhoodProxy.addSignalHandler(this.handleBroadcastCb);
const { data } = usePerspective(client, () => route.params.communityId);
this.polling = setInterval(() => {
this.checkWhoIsHere();
}, 5000);
this.checkWhoIsHere();
},
unmounted() {
clearInterval(this.polling);
this.neighbhourhoodProxy.removeSignalHandler(this.handleBroadcastCb);
},
async setup(props) {
const client: Ad4mClient = await getAd4mClient();
const neighbhourhoodProxy = props.perspective.getNeighbourhoodProxy();
const { me } = useMe(client.agent);
const { entries: channels, repo: channelRepo } = useSubjects({
perspective: () => data.value.perspective,
perspective: () => props.perspective,
source: () => "ad4m://self",
subject: Channel,
});
return {
me,
activeAgents: ref<Record<string, Record<string, boolean>>>({}),
neighbhourhoodProxy,
channelRepo,
channels,
userProfileImage: ref<null | string>(null),
Expand All @@ -147,11 +147,78 @@ export default defineComponent({
},
data: function () {
return {
polling: null as any,
neighbhourhoodProxy: null as NeighbourhoodProxy | null,
showCommunityMenu: false,
communityImage: null,
};
},
computed: {
activeChannelId() {
return this.$route.params.channelId as string;
},
},
methods: {
checkWhoIsHere() {
if (this.neighbhourhoodProxy) {
this.channels.forEach((channel) => {
this.neighbhourhoodProxy.sendBroadcastU({
links: [
{
source: channel.id,
predicate: "is-anyone-here",
target: "just checking",
},
],
});
});
}
},
handleBroadcastCb(perspectiveExpression: PerspectiveExpression) {
const link = perspectiveExpression.data.links[0];
if (
link &&
link.author !== this.me?.did &&
link.data.predicate === "i-am-here"
) {
this.activeAgents[link.data.source] = {
...this.activeAgents[link.data.source],
[link.author]: true,
};
}
if (
link &&
link.author !== this.me?.did &&
link.data.predicate === "leave"
) {
this.activeAgents[link.data.source] = {
...this.activeAgents[link.data.source],
[link.author]: false,
};
}
if (
link &&
link.author === this.me?.did &&
link.data.predicate === "leave" &&
this.me?.did
) {
this.activeAgents[link.data.source] = {
...this.activeAgents[link.data.source],
[this.me.did]: false,
};
}
if (
link &&
link.author === this.me?.did &&
link.data.predicate === "peer-signal" &&
this.me?.did
) {
this.activeAgents[link.data.source] = {
...this.activeAgents[link.data.source],
[this.me.did]: true,
};
}
},
...mapActions(useAppStore, ["setSidebar", "setShowCreateChannel"]),
handleToggleClick(channelId: string) {
// TODO: Toggle channel collapse
Expand All @@ -177,7 +244,6 @@ export default defineComponent({
},
isChannelCreator(channelId: string): boolean {
const channel = this.channels.find((e) => e.id === channelId);
if (channel) {
return channel.author === this.me?.did;
} else {
Expand All @@ -188,7 +254,7 @@ export default defineComponent({
return channelViewOptions.filter((o) => views.includes(o.type));
},
getIcon(view: ChannelView) {
console.log({channelViewOptions, view, channels: this.channels})
console.log({ channelViewOptions, view, channels: this.channels });
return channelViewOptions.find((o) => o.pkg === view)?.icon || "hash";
},
async deleteChannel(channelId: string) {
Expand Down Expand Up @@ -224,4 +290,14 @@ export default defineComponent({
border-radius: 50%;
background: var(--j-color-primary-500);
}
.active-agents {
display: flex;
align-items: center;
position: absolute;
gap: var(--j-space-100);
right: var(--j-space-400);
top: 50%;
transform: translateY(-50%);
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { defineComponent } from "vue";
import ChannelList from "./ChannelList.vue";
import Members from "./Members.vue";
import Header from "./Header.vue";
import { PerspectiveProxy } from "@coasys/ad4m";
export default defineComponent({
components: { ChannelList, Members, Header },
Expand All @@ -18,7 +19,7 @@ export default defineComponent({
required: true,
},
perspective: {
type: Object,
type: PerspectiveProxy,
required: true,
},
isSynced: Boolean,
Expand Down
1 change: 1 addition & 0 deletions packages/api/src/post/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export class Post {
@subjectProperty({
through: TITLE,
writable: true,
required: true,
resolveLanguage: "literal",
})
title: string;
Expand Down
8 changes: 4 additions & 4 deletions packages/vue/src/useAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ const {
HAS_USERNAME,
} = profile;

const agent = ref<Agent | null>(null);

export function useAgent(client: AgentClient, did: string | Function) {
const agent = ref<Agent | null>(null);
const didRef = typeof did === "function" ? (did as any) : ref(did);

watch(
Expand All @@ -35,7 +34,7 @@ export function useAgent(client: AgentClient, did: string | Function) {
const profile = computed<Profile | null>(() => {
if (agent.value?.perspective) {
const perspective = agent.value.perspective;
return mapLiteralLinks(
const prof = mapLiteralLinks(
perspective.links.filter((e) => e.data.source === FLUX_PROFILE),
{
username: HAS_USERNAME,
Expand All @@ -47,7 +46,8 @@ export function useAgent(client: AgentClient, did: string | Function) {
profileThumbnailPicture: HAS_THUMBNAIL_IMAGE,
profileBackground: HAS_BG_IMAGE,
}
) as Profile;
);
return { ...prof, did: didRef.value } as Profile;
} else {
return null;
}
Expand Down
2 changes: 2 additions & 0 deletions packages/webrtc/src/WebRTCManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,8 @@ export class WebRTCManager {
* Join the chat room, listen for signals
*/
async join(initialSettings?: Settings) {
console.log("trying to join");

let settings = { audio: true, video: false, ...initialSettings };

this.localStream = await navigator.mediaDevices.getUserMedia({
Expand Down
Loading

0 comments on commit 1d982d2

Please sign in to comment.