-
-
Notifications
You must be signed in to change notification settings - Fork 47
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
319 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
...ager/src/main/java/com/rtm516/mcxboxbroadcast/manager/models/response/FriendResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.rtm516.mcxboxbroadcast.manager.models.response; | ||
|
||
import com.rtm516.mcxboxbroadcast.core.models.session.FollowerResponse; | ||
|
||
public record FriendResponse( | ||
String xuid, | ||
boolean isFollowingCaller, | ||
boolean isFollowedByCaller, | ||
String gamertag, | ||
String presenceState | ||
|
||
) { | ||
public FriendResponse(FollowerResponse.Person person) { | ||
this(person.xuid, person.isFollowingCaller, person.isFollowedByCaller, person.gamertag, person.presenceState); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
bootstrap/manager/src/ui/src/components/specialised/Friend.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { UserCircleIcon, UserMinusIcon } from '@heroicons/react/16/solid' | ||
|
||
import Button from '../basic/Button' | ||
import { addNotification } from '../layout/NotificationContainer' | ||
import { useState } from 'react' | ||
|
||
function Friend ({ botId, friend, updateData }) { | ||
const [disabled, setDisabled] = useState(false) | ||
|
||
const callRemove = () => { | ||
setDisabled(true) | ||
fetch('/api/bots/' + botId + '/friends/' + friend.xuid, { method: 'DELETE' }).then((res) => { | ||
if (!res.ok) { | ||
return addNotification('Failed to remove friend', 'error') | ||
} | ||
updateData() | ||
}).finally(() => setDisabled(false)) | ||
} | ||
|
||
return ( | ||
<> | ||
<div className='flex hover:bg-slate-100 rounded p-2 gap-2 items-center'> | ||
<UserCircleIcon className={'w-4 h-4 ' + (friend.presenceState === 'Online' ? 'text-green-600' : 'text-red-600')} /> | ||
<div className='grow content-center'>{friend.gamertag}<small className='text-xs text-gray-400'> {friend.xuid}</small></div> | ||
<Button title='Remove friend' color='red' onClick={() => callRemove()} disabled={disabled}><UserMinusIcon className='size-4' aria-hidden='true' /></Button> | ||
</div> | ||
</> | ||
) | ||
} | ||
|
||
export default Friend |
84 changes: 84 additions & 0 deletions
84
bootstrap/manager/src/ui/src/components/specialised/FriendsPanel.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { useEffect, useState } from 'react' | ||
import Friend from './Friend' | ||
import Button from '../basic/Button' | ||
import Input from '../basic/Input' | ||
import { ChevronDoubleLeftIcon, ChevronDoubleRightIcon, ChevronLeftIcon, ChevronRightIcon } from '@heroicons/react/16/solid' | ||
|
||
function FriendPanel ({ botId }) { | ||
const [friends, setFriends] = useState([]) | ||
const [page, setPage] = useState(1) | ||
const [maxPage, setMaxPage] = useState(1) | ||
const [filteredFriends, setFilteredFriends] = useState([]) | ||
const [query, setQuery] = useState('') | ||
|
||
const perPage = 10 | ||
|
||
const updateData = () => { | ||
fetch('/api/bots/' + botId + '/friends').then((res) => res.json()).then((friendsData) => { | ||
setFriends(friendsData.filter(f => f.isFollowingCaller && f.isFollowedByCaller).sort((f1, f2) => f1.xuid - f2.xuid)) | ||
}) | ||
} | ||
|
||
useEffect(() => { | ||
updateData() | ||
const interval = setInterval(updateData, 2500) // Update every 2.5 seconds | ||
return () => clearInterval(interval) | ||
}, []) | ||
|
||
useEffect(() => { | ||
setFilteredFriends(friends.filter(f => f.xuid.includes(query) || f.gamertag.toLowerCase().includes(query.toLowerCase()))) | ||
}, [friends, query]) | ||
|
||
useEffect(() => { | ||
changePage(0) // Make sure the page is still valid when friend data changes | ||
}, [filteredFriends]) | ||
|
||
const changePage = (pageAdjustment) => { | ||
let newPage = page + pageAdjustment | ||
let maxPage = Math.floor(filteredFriends.length / perPage) | ||
|
||
// If there are any friends left over, add another page | ||
if (maxPage * perPage < filteredFriends.length) maxPage++ | ||
|
||
// Make sure the page is within bounds | ||
if (newPage < 1) newPage = 1 | ||
if (maxPage < 1) maxPage = 1 | ||
if (newPage > maxPage) newPage = maxPage | ||
|
||
setPage(newPage) | ||
setMaxPage(maxPage) | ||
} | ||
|
||
return ( | ||
<> | ||
<div className='bg-white p-6 rounded shadow-lg max-w-6xl w-full'> | ||
<h3 className='text-3xl text-center'>Friends</h3> | ||
<h4 className='text-xl text-center text-gray-400'> | ||
{friends.length}/1000 | ||
</h4> | ||
<Input | ||
value={query} | ||
onChange={(e) => setQuery(e.target.value)} | ||
placeholder='Search' | ||
className='pb-4' | ||
/> | ||
<div className='flex flex-col'> | ||
{filteredFriends.slice(perPage * (page - 1), perPage * page).map((friend, i) => ( | ||
<Friend key={i} botId={botId} friend={friend} updateData={updateData} /> | ||
))} | ||
<div className='flex justify-center items-center gap-1'> | ||
<Button onClick={() => changePage(-maxPage)}><ChevronDoubleLeftIcon className='h-5 w-5' aria-hidden='true' /></Button> | ||
<Button onClick={() => changePage(-1)}><ChevronLeftIcon className='h-5 w-5' aria-hidden='true' /></Button> | ||
<div> | ||
{page} / {maxPage} | ||
</div> | ||
<Button onClick={() => changePage(1)}><ChevronRightIcon className='h-5 w-5' aria-hidden='true' /></Button> | ||
<Button onClick={() => changePage(maxPage)}><ChevronDoubleRightIcon className='h-5 w-5' aria-hidden='true' /></Button> | ||
</div> | ||
</div> | ||
</div> | ||
</> | ||
) | ||
} | ||
|
||
export default FriendPanel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.