Skip to content

Commit

Permalink
Merge pull request #479 from h3poteto/iss-464
Browse files Browse the repository at this point in the history
refs #464 Show account name in server lists
  • Loading branch information
h3poteto authored Mar 2, 2023
2 parents 4019be8 + 3495a19 commit 25b8ed6
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 25 deletions.
36 changes: 34 additions & 2 deletions src-tauri/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,40 @@ pub(crate) async fn migrate_database(pool: &SqlitePool) -> DBResult<()> {
Ok(())
}

pub(crate) async fn list_servers(pool: &SqlitePool) -> DBResult<Vec<entities::Server>> {
let servers = query_as::<_, entities::Server>("select * from servers")
pub(crate) async fn list_servers(
pool: &SqlitePool,
) -> DBResult<Vec<(entities::Server, Option<entities::Account>)>> {
let servers = sqlx::query(
r#"
SELECT servers.id, servers.domain, servers.base_url, servers.sns, servers.favicon, servers.account_id,
accounts.id, accounts.username, accounts.account_id, accounts.avatar, accounts.client_id, accounts.client_secret,
accounts.access_token, accounts.refresh_token, accounts.usual
FROM servers LEFT JOIN accounts ON servers.account_id = accounts.id"#,
).map(|row: SqliteRow| {
let server = entities::Server {
id: row.get(0),
domain: row.get(1),
base_url: row.get(2),
sns: row.get(3),
favicon: row.get(4),
account_id: row.get(5),
};
if row.get(6) {
(server, Some(entities::Account {
id: row.get(6),
username: row.get(7),
account_id: row.get(8),
avatar: row.get(9),
client_id: row.get(10),
client_secret: row.get(11),
access_token: row.get(12),
refresh_token: row.get(13),
usual: row.get(14),
}))
} else {
(server, None)
}
})
.fetch_all(pool)
.await?;

Expand Down
2 changes: 1 addition & 1 deletion src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ rust_i18n::i18n!("locales");
#[tauri::command]
async fn list_servers(
sqlite_pool: State<'_, sqlx::SqlitePool>,
) -> Result<Vec<entities::Server>, String> {
) -> Result<Vec<(entities::Server, Option<entities::Account>)>, String> {
let servers = database::list_servers(&sqlite_pool)
.await
.map_err(|e| e.to_string())?;
Expand Down
25 changes: 18 additions & 7 deletions src/components/Navigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import { ReactElement, useEffect, useState } from 'react'
import { Icon } from '@rsuite/icons'
import { Popover, Dropdown, Sidebar, Sidenav, Whisper, Button, Avatar, Badge, FlexboxGrid } from 'rsuite'
import { BsPlus, BsGear, BsPencilSquare } from 'react-icons/bs'
import { Server } from 'src/entities/server'
import { Server, ServerSet } from 'src/entities/server'
import FailoverImg from 'src/utils/failoverImg'
import { Unread } from 'src/entities/unread'
import { Instruction } from 'src/entities/instruction'
import { listen } from '@tauri-apps/api/event'
import { useTranslation } from 'react-i18next'

type NavigatorProps = {
servers: Array<Server>
servers: Array<ServerSet>
unreads: Array<Unread>
addNewServer: () => void
openAuthorize: (server: Server) => void
Expand Down Expand Up @@ -87,19 +87,30 @@ const Navigator: React.FC<NavigatorProps> = (props): ReactElement => {
</div>
)}
{servers.map(server => (
<div key={server.id}>
<div key={server.server.id}>
<Whisper
placement="right"
controlId="control-id-context-menu"
trigger="contextMenu"
onOpen={closeWalkthrough}
speaker={({ className, left, top, onClose }, ref) =>
serverMenu({ className, left, top, onClose, server, openAuthorize }, ref)
serverMenu({ className, left, top, onClose, server: server.server, openAuthorize }, ref)
}
>
<Button appearance="link" size="xs" style={{ padding: '8px' }} title={server.domain}>
<Badge content={props.unreads.find(u => u.server_id === server.id && u.count > 0) ? true : false}>
<Avatar size="sm" src={FailoverImg(server.favicon)} className="server-icon" alt={server.domain} key={server.id} />
<Button
appearance="link"
size="xs"
style={{ padding: '8px' }}
title={server.account ? server.account.username + '@' + server.server.domain : server.server.domain}
>
<Badge content={props.unreads.find(u => u.server_id === server.server.id && u.count > 0) ? true : false}>
<Avatar
size="sm"
src={FailoverImg(server.server.favicon)}
className="server-icon"
alt={server.server.domain}
key={server.server.id}
/>
</Badge>
</Button>
</Whisper>
Expand Down
4 changes: 2 additions & 2 deletions src/components/compose/Compose.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { invoke } from '@tauri-apps/api/tauri'
import generator, { MegalodonInterface } from 'megalodon'

import { USER_AGENT } from 'src/defaults'
import { Server } from 'src/entities/server'
import { Server, ServerSet } from 'src/entities/server'
import { Account } from 'src/entities/account'
import failoverImg from 'src/utils/failoverImg'
import Status from './Status'
Expand Down Expand Up @@ -38,7 +38,7 @@ const renderAccountIcon = (props: any, ref: any, account: [Account, Server] | un

type Props = {
setOpened: (value: boolean) => void
servers: Array<Server>
servers: Array<ServerSet>
}

const Compose: React.FC<Props> = props => {
Expand Down
12 changes: 6 additions & 6 deletions src/components/timelines/New.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
} from 'rsuite'
import { Icon } from '@rsuite/icons'
import { BsPlus, BsHouseDoor, BsBell, BsPeople, BsGlobe2, BsStar, BsListUl, BsChevronLeft, BsBookmark, BsEnvelope } from 'react-icons/bs'
import { Server } from '../../entities/server'
import { Server, ServerSet } from '../../entities/server'
import { useEffect, useState } from 'react'
import { invoke } from '@tauri-apps/api/tauri'
import generator, { Entity } from 'megalodon'
Expand Down Expand Up @@ -125,7 +125,7 @@ const AuthorizedTimelines: React.FC<AuthorizedProps> = props => {
}

type Props = {
servers: Array<Server>
servers: Array<ServerSet>
}

const New: React.FC<Props> = props => {
Expand Down Expand Up @@ -160,15 +160,15 @@ const New: React.FC<Props> = props => {
const addTimelineMenu = ({ onClose, left, top, className }, ref: any) => {
const handleSelect = (eventKey: string) => {
onClose()
const target = props.servers.find(s => s.id === parseInt(eventKey))
setServer(target)
const target = props.servers.find(s => s.server.id === parseInt(eventKey))
setServer(target.server)
}
return (
<Popover ref={ref} className={className} style={{ left, top }} full>
<Dropdown.Menu onSelect={handleSelect}>
{props.servers.map(server => (
<Dropdown.Item eventKey={server.id} key={server.id}>
{server.domain}
<Dropdown.Item eventKey={server.server.id} key={server.server.id}>
{server.account ? server.account.username + '@' + server.server.domain : server.server.domain}
</Dropdown.Item>
))}
</Dropdown.Menu>
Expand Down
7 changes: 7 additions & 0 deletions src/entities/server.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Account } from './account'

export type Server = {
id: number
domain: string
Expand All @@ -6,3 +8,8 @@ export type Server = {
favicon: string | null
account_id: number | null
}

export type ServerSet = {
server: Server
account: Account | null
}
26 changes: 19 additions & 7 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Container, Content, useToaster, Animation } from 'rsuite'
import { isPermissionGranted, requestPermission, sendNotification } from '@tauri-apps/api/notification'
import dayjs from 'dayjs'

import { Server } from 'src/entities/server'
import { Server, ServerSet } from 'src/entities/server'
import { Timeline } from 'src/entities/timeline'
import { Unread } from 'src/entities/unread'
import alert from 'src/components/utils/alert'
Expand All @@ -23,11 +23,12 @@ import { Settings } from 'src/entities/settings'
import SettingsPage from 'src/components/settings/Settings'
import Detail from 'src/components/detail/Detail'
import { useTranslation } from 'react-i18next'
import { Account } from 'src/entities/account'

function App() {
const { t, i18n } = useTranslation()

const [servers, setServers] = useState<Array<Server>>([])
const [servers, setServers] = useState<Array<ServerSet>>([])
const [timelines, setTimelines] = useState<Array<[Timeline, Server]>>([])
const [unreads, setUnreads] = useState<Array<Unread>>([])
const [composeOpened, setComposeOpened] = useState<boolean>(false)
Expand All @@ -44,13 +45,19 @@ function App() {

useEffect(() => {
loadAppearance()
invoke<Array<Server>>('list_servers').then(res => {
invoke<Array<[Server, Account | null]>>('list_servers').then(res => {
if (res.length === 0) {
console.debug('There is no server')
dispatch({ target: 'newServer', value: true })
toaster.push(alert('info', t('alert.no_server')), { placement: 'topCenter' })
} else {
setServers(res)
console.debug('list_servers: ', res)
setServers(
res.map(r => ({
server: r[0],
account: r[1]
}))
)
}
})

Expand All @@ -60,8 +67,13 @@ function App() {
loadTimelines()
})
listen('updated-servers', async () => {
const res = await invoke<Array<Server>>('list_servers')
setServers(res)
const res = await invoke<Array<[Server, Account | null]>>('list_servers')
setServers(
res.map(r => ({
server: r[0],
account: r[1]
}))
)
})

listen<ReceiveNotificationPayload>('receive-notification', async ev => {
Expand Down Expand Up @@ -105,7 +117,7 @@ function App() {
}

const toggleCompose = () => {
if (servers.find(s => s.account_id !== null)) {
if (servers.find(s => s.account !== null)) {
setComposeOpened(previous => !previous)
} else {
toaster.push(alert('info', t('alert.need_auth')), { placement: 'topStart' })
Expand Down

0 comments on commit 25b8ed6

Please sign in to comment.