Skip to content

Commit

Permalink
i should sleep
Browse files Browse the repository at this point in the history
  • Loading branch information
yofukashino committed Jun 10, 2024
1 parent 32b95c8 commit 78fe11c
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 41 deletions.
157 changes: 120 additions & 37 deletions plugins/pindms/components/GuildPins.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,13 @@ import { Store } from "replugged/dist/renderer/modules/common/flux";
import {
ChannelStore,
GuildChannelStore,
SelectedChannelStore,
ReadStateStore,
StatusStore,
TypingStore,
ApplicationStreamingStore,
ChannelRTCStore,
RTCConnectionStore,
} from "../stores";

const classes = webpack.getByProps<{ listItem: string; listItemWrapper: string; pill: string }>(
Expand All @@ -36,13 +40,55 @@ const transitionTo = (transtionRaw &&
'"transitionTo - Transitioning to "',
)!) as ((to: string) => void) | undefined;

function DropEndWrapper({ id }: { id: string }) {
if (!useDrop) return null;

const [{ isOver }, drop] = useDrop<Channel>(() => ({
accept: "GUILDPIN",
drop: (item, monitor) => {
if (item.id == id) return;
const pins = pluginSettings.get("guildPins", []);
const draggedIndex = pins.findIndex((pin) => pin === item.id);
const droppedIndex = pins.findIndex((pin) => pin === id);

if (draggedIndex == -1 || droppedIndex == -1) return;

pluginSettings.set(
"guildPins",
pins.reduce((acc: string[], item, index) => {
if (index === draggedIndex) return acc;
if (index === droppedIndex) return [...acc, item, pins[draggedIndex]];
return [...acc, item];
}, []),
);

common.fluxDispatcher.dispatch({ type: GUILDLIST_UPDATE });
},
collect: (e) => ({
isOver: e.isOver(),
}),
}));

return (
<span
className={isOver ? "pindms-guildList-dragTarget" : ""}
ref={(node) => drop(node)}
style={{ padding: "10% 0% 10% 100%" }}
/>
);
}

function GuildPin({ id }: { id: string }) {
if (
// !useStateFromStore ||
!ChannelStore ||
!ReadStateStore ||
!StatusStore ||
!TypingStore ||
!SelectedChannelStore ||
!ApplicationStreamingStore ||
!ChannelRTCStore ||
!RTCConnectionStore ||
!useDrop ||
!useDrag ||
!Pill ||
Expand All @@ -56,7 +102,7 @@ function GuildPin({ id }: { id: string }) {

if (!channel || !user) return null;

const [, drop] = useDrop<Channel>(() => ({
const [{ isOver }, drop] = useDrop<Channel>(() => ({
accept: "GUILDPIN",
drop: (item, monitor) => {
if (item.id == id) return;
Expand All @@ -68,22 +114,27 @@ function GuildPin({ id }: { id: string }) {

pluginSettings.set(
"guildPins",
pins.map((pin, index) => {
if (index === draggedIndex) return id;
else if (index === droppedIndex) return item.id;

return pin;
}),
pins.reduce((acc: string[], item, index) => {
if (index === draggedIndex) return acc;
if (index === droppedIndex) return [...acc, pins[draggedIndex], item];
return [...acc, item];
}, []),
);

common.fluxDispatcher.dispatch({ type: GUILDLIST_UPDATE });
},
collect: (e) => ({
isOver: e.isOver(),
}),
}));

const [, drag] = useDrag(() => ({
const [{ dragging }, drag] = useDrag(() => ({
type: "GUILDPIN",
item: channel,
options: { dropEffect: "copy" },
collect: (e) => ({
dragging: e.isDragging(),
}),
}));
const [hovered, setHovered] = useState(false);
const isMobileOnline = common.flux.useStateFromStores<boolean>([StatusStore], () =>
Expand All @@ -98,13 +149,37 @@ function GuildPin({ id }: { id: string }) {
const isTyping = common.flux.useStateFromStores<boolean>([TypingStore], () =>
TypingStore!.isTyping(channel.id, user.id),
);
const selected = common.flux.useStateFromStores<boolean>(
[SelectedChannelStore],
() => SelectedChannelStore!.getCurrentlySelectedChannelId() === channel.id,
);
const mediaInfo = common.flux.useStateFromStores<{
video: boolean;
audio: boolean;
screenshare: boolean;
isCurrentUserConnected: boolean;
}>([ApplicationStreamingStore, ChannelRTCStore, RTCConnectionStore], () => {
const connectedVoiceChannelId = RTCConnectionStore!.getChannelId();
const streams = ApplicationStreamingStore?.getAllApplicationStreamsForChannel(id);
const voiceChannelMode = connectedVoiceChannelId === id ? ChannelRTCStore?.getMode(id) : "";
return {
video: voiceChannelMode === "video",
audio: voiceChannelMode === "voice",
screenshare: Boolean(streams?.length),
isCurrentUserConnected: connectedVoiceChannelId === id,
};
});

const showStatus = pluginSettings.get("showStatus", true);

return (
<components.Tooltip shouldShow={hovered} text={getChannelName(channel)} position="right">
<components.Tooltip
key={`${dragging}`}
className={!dragging && isOver ? "pindms-guildList-dragTarget" : ""}
shouldShow={hovered}
text={getChannelName(channel)}
position="right">
<div
ref={(node) => drop(drag(node))}
className={[
classes?.listItem,
"pindms-guildlist-pin",
Expand All @@ -113,50 +188,58 @@ function GuildPin({ id }: { id: string }) {
{Pill ? (
<Pill
className={classes?.pill}
selected={false}
hovered={hovered}
selected={selected}
hovered={!dragging && hovered}
unread={Boolean(unreadCount)}
/>
) : undefined}
<div>
<Avatar
isMobile={isMobileOnline}
isTyping={isTyping}
size="SIZE_48"
src={getChannelIcon(channel)!}
status={channel.type === 1 && showStatus ? status : undefined}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
onClick={() => transitionTo?.(`/channels/@me/${id}`)}
onContextMenu={(e) =>
common.contextMenu.open(e, () => <Categories selectedId={channel.id} />)
}
/>
{Badge && (unreadCount ?? 0) > 0 ? <Badge count={unreadCount} /> : undefined}
</div>
<span ref={(node) => drop(drag(node))}>
{!dragging && (
<>
<Avatar
isMobile={isMobileOnline}
isTyping={isTyping}
size="SIZE_48"
src={getChannelIcon(channel)!}
status={channel.type === 1 && showStatus ? status : undefined}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
onClick={() => transitionTo?.(`/channels/@me/${id}`)}
onContextMenu={(e) =>
common.contextMenu.open(e, () => <Categories selectedId={channel.id} />)
}
/>
{Badge && (unreadCount ?? 0) > 0
? Badge.renderMentionBadge(unreadCount)
: Badge?.renderMediaBadge(mediaInfo)}
</>
)}
</span>
</div>
</components.Tooltip>
);
}

export default () => {
const [guildPins, setGuildPins] = useState(pluginSettings.get("guildPins", [] as string[]));

const [key, setKey] = useState(Date.now());
useEffect(() => {
const update = () => {
setGuildPins([]);
setTimeout(() => setGuildPins([...pluginSettings.get("guildPins", [])]));
setTimeout(() => {
setGuildPins([...pluginSettings.get("guildPins", [])]);
setKey(Date.now());
}, 500);
};

common.fluxDispatcher.subscribe(GUILDLIST_UPDATE, update);
return () => common.fluxDispatcher.unsubscribe(GUILDLIST_UPDATE, update);
}, []);

}, [pluginSettings.get("guildPins", [] as string[])]);
return (
<>
{guildPins.map((id) => (
<GuildPin id={id} />
<span key={key}>
{guildPins.map((id, index) => (
<GuildPin id={id} key={id} />
))}
</>
<DropEndWrapper id={guildPins[guildPins.length - 1]} />
</span>
);
};
16 changes: 13 additions & 3 deletions plugins/pindms/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,19 @@ export const StatusBlob = AvatarRaw?.X as FC | undefined;

const BadgeRaw = webpack.getBySource('"count","color","disableColor","shape","className","style"');

export const Badge = webpack.getByProps<{ NumberBadge: FC<{ count: number }> }>(
"NumberBadge",
)?.NumberBadge;
export const Badge = webpack.getByProps<{
renderMediaBadge: (props: {
activeEvent?: boolean;
activity?: boolean;
audio?: boolean;
gaming?: boolean;
isCurrentUserConnected?: boolean;
liveStage?: boolean;
screenshare?: boolean;
video?: boolean;
}) => JSX.Element;
renderMentionBadge: (count: number, color?: string) => JSX.Element;
}>("renderMediaBadge", "renderMentionBadge");

export const SearchBar = webpack.getBySource<
FC<{ className: string; query: string; onChange: (value: string) => void; onClear: () => void }>
Expand Down
2 changes: 1 addition & 1 deletion plugins/pindms/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ function patchUnreadDMs(component: JSX.Element) {
}, []);

res.props.children = res.props.children.filter(
(c: ReactElement) => !pins.includes(c.key as string),
(c: ReactElement) => !pins.includes(c?.key as string),
);

return res;
Expand Down
16 changes: 16 additions & 0 deletions plugins/pindms/stores.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,19 @@ export const ChannelStore = webpack.getByStoreName<
export const GuildChannelStore = webpack.getByStoreName<
Store & { getChannels: (guildId: string) => { SELECTABLE: Array<{ channel: Channel }> } }
>("GuildChannelStore");

export const SelectedChannelStore = webpack.getByStoreName<
Store & { getCurrentlySelectedChannelId: () => string }
>("SelectedChannelStore");

export const ApplicationStreamingStore = webpack.getByStoreName<
Store & { getAllApplicationStreamsForChannel: (channelId: string) => unknown[] }
>("ApplicationStreamingStore");

export const ChannelRTCStore = webpack.getByStoreName<
Store & { getMode: (channelId: string) => string }
>("ChannelRTCStore");

export const RTCConnectionStore = webpack.getByStoreName<Store & { getChannelId: () => string }>(
"RTCConnectionStore",
);
18 changes: 18 additions & 0 deletions plugins/pindms/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,21 @@
position: absolute;
top: 0;
}

.pindms-guildlist-pin [class*="iconBadge"] {
right: 8px;
position: absolute;
top: 0;
}

.pindms-guildList-dragTarget:before {
content: "";
position: absolute;
z-index: 1;
left: 4px;
right: 4px;
height: 4px;
background-color: var(--green-360);
border-radius: 2px;
box-shadow: 0 0 3px hsl(var(--black-500-hsl) / 0.3);
}

0 comments on commit 78fe11c

Please sign in to comment.