Chunter fixes (#419)

Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
Andrey Sobolev 2021-11-29 18:32:46 +07:00 committed by GitHub
parent 4ae06a7677
commit 40c1d33fa3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 70 additions and 55 deletions

View File

@ -3,6 +3,13 @@
"ApplicationLabelChunter": "Chat", "ApplicationLabelChunter": "Chat",
"LeftComment": "left a comment", "LeftComment": "left a comment",
"AddAttachment": "uploaded an attachment", "AddAttachment": "uploaded an attachment",
"Channels": "Channels",
"CreateChannel": "New Channel",
"ChannelName": "Name",
"ChannelDescription": "Description",
"MakePrivate": "Make private",
"MakePrivateDescription": "Only members can see it",
"Channel": "Channel",
"EditUpdate": "Save...", "EditUpdate": "Save...",
"EditCancel": "Cancel" "EditCancel": "Cancel"
} }

View File

@ -15,46 +15,21 @@
--> -->
<script lang="ts"> <script lang="ts">
import { Avatar, getClient } from '@anticrm/presentation'
import type { Comment } from '@anticrm/chunter' import type { Comment } from '@anticrm/chunter'
import contact, { EmployeeAccount, formatName } from '@anticrm/contact' import { formatName } from '@anticrm/contact'
import { Avatar, getClient, MessageViewer } from '@anticrm/presentation'
import { MessageViewer } from '@anticrm/presentation' import { getTime, getUser } from '../utils'
import { Account, Ref } from '@anticrm/core'
export let value: Comment export let value: Comment
const client = getClient() const client = getClient()
async function getUser (user: Ref<EmployeeAccount> | Ref<Account>): Promise<EmployeeAccount | undefined> {
return await client.findOne(contact.class.EmployeeAccount, { _id: user as Ref<EmployeeAccount> })
}
function getTime (time: number): string {
let options: Intl.DateTimeFormatOptions = { hour: 'numeric', minute: 'numeric'}
if (!isToday(time)) {
options = {
month: 'numeric',
day: 'numeric',
...options
}
}
return new Date(value.modifiedOn).toLocaleString('default', options)
}
function isToday (time: number): boolean {
const current = new Date()
const target = new Date(time)
return current.getDate() === target.getDate() && current.getMonth() === target.getMonth() && current.getFullYear() === target.getFullYear()
}
</script> </script>
<div class="container"> <div class="container">
<div class="avatar"><Avatar size={'medium'} /></div> <div class="avatar"><Avatar size={'medium'} /></div>
<div class="message"> <div class="message">
<div class="header"> <div class="header">
{#await getUser(value.modifiedBy) then user} {#await getUser(client, value.modifiedBy) then user}
{#if user}{formatName(user.name)}{/if} {#if user}{formatName(user.name)}{/if}
{/await} {/await}
<span>{getTime(value.modifiedOn)}</span> <span>{getTime(value.modifiedOn)}</span>

View File

@ -15,39 +15,40 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from 'svelte' import { createEventDispatcher } from 'svelte'
import { TextArea, EditBox, Dialog, ToggleWithLabel, Grid, Section, IconToDo } from '@anticrm/ui' import { IconFolder, EditBox, ToggleWithLabel, Grid } from '@anticrm/ui'
import { getClient } from '@anticrm/presentation' import { getClient, SpaceCreateCard } from '@anticrm/presentation'
import chunter from '../plugin' import chunter from '../plugin'
import core from '@anticrm/core' import core, { getCurrentAccount } from '@anticrm/core'
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
let name: string = '' let name: string = ''
let description: string = '' let description: string = ''
export function canClose(): boolean {
return name === ''
}
const client = getClient() const client = getClient()
function createChannel() { function createChannel() {
client.createDoc(chunter.class.Channel, core.space.Model, { client.createDoc(chunter.class.Channel, core.space.Model, {
name, name,
description, description,
private: false private: false,
members: [getCurrentAccount()._id]
}) })
} }
</script> </script>
<Dialog label={chunter.string.CreateChannel} <SpaceCreateCard
okLabel={chunter.string.CreateChannel} label={chunter.string.CreateChannel}
okAction={createChannel} okAction={createChannel}
on:close={() => { dispatch('close') }}> canSave={name ? true : false}
<Grid column={1}> on:close={() => { dispatch('close') }}
<EditBox label={chunter.string.ChannelName} bind:value={name} focus/> >
<TextArea label={chunter.string.ChannelDescription} bind:value={description}/> <Grid column={1} rowGap={1.5}>
<EditBox label={chunter.string.ChannelName} icon={IconFolder} bind:value={name} placeholder={'Channel'} focus/>
<ToggleWithLabel label={chunter.string.MakePrivate} description={chunter.string.MakePrivateDescription}/> <ToggleWithLabel label={chunter.string.MakePrivate} description={chunter.string.MakePrivateDescription}/>
</Grid> </Grid>
<!-- <Section icon={IconToDo} label={`To Do's`}> </SpaceCreateCard>
<CheckBoxList label={'Add a To Do'} editable />
</Section> -->
</Dialog>

View File

@ -14,30 +14,37 @@
--> -->
<script lang="ts"> <script lang="ts">
import { Avatar } from '@anticrm/presentation' import { Avatar, getClient } from '@anticrm/presentation'
import type { Message } from '@anticrm/chunter' import type { Message } from '@anticrm/chunter'
import { ActionIcon, IconMoreH } from '@anticrm/ui' // import { ActionIcon, IconMoreH } from '@anticrm/ui'
import Emoji from './icons/Emoji.svelte' // import Emoji from './icons/Emoji.svelte'
import Share from './icons/Share.svelte' // import Share from './icons/Share.svelte'
import Bookmark from './icons/Bookmark.svelte' // import Bookmark from './icons/Bookmark.svelte'
import Reactions from './Reactions.svelte' import Reactions from './Reactions.svelte'
import Replies from './Replies.svelte' import Replies from './Replies.svelte'
import { MessageViewer } from '@anticrm/presentation' import { MessageViewer } from '@anticrm/presentation'
import { getTime, getUser } from '../utils'
import { formatName } from '@anticrm/contact'
export let message: Message export let message: Message
let name: string
let time: string
let reactions: boolean = false let reactions: boolean = false
let replies: boolean = false let replies: boolean = false
let thread: boolean = false let thread: boolean = false
const client = getClient()
</script> </script>
<div class="container"> <div class="container">
<div class="avatar"><Avatar size={'medium'} /></div> <div class="avatar"><Avatar size={'medium'} /></div>
<div class="message"> <div class="message">
<div class="header">{name}<span>{time}</span></div> <div class="header">
{#await getUser(client, message.modifiedBy) then user}
{#if user}{formatName(user.name)}{/if}
{/await}
<span>{getTime(message.modifiedOn)}</span>
</div>
<div class="text"><MessageViewer message={message.content}/></div> <div class="text"><MessageViewer message={message.content}/></div>
{#if (reactions || replies) && !thread} {#if (reactions || replies) && !thread}
<div class="footer"> <div class="footer">
@ -46,14 +53,14 @@
</div> </div>
{/if} {/if}
</div> </div>
{#if !thread} <!-- {#if !thread}
<div class="buttons"> <div class="buttons">
<div class="tool"><ActionIcon icon={IconMoreH} size={'medium'}/></div> <div class="tool"><ActionIcon icon={IconMoreH} size={'medium'}/></div>
<div class="tool"><ActionIcon icon={Bookmark} size={'medium'}/></div> <div class="tool"><ActionIcon icon={Bookmark} size={'medium'}/></div>
<div class="tool"><ActionIcon icon={Share} size={'medium'}/></div> <div class="tool"><ActionIcon icon={Share} size={'medium'}/></div>
<div class="tool"><ActionIcon icon={Emoji} size={'medium'}/></div> <div class="tool"><ActionIcon icon={Emoji} size={'medium'}/></div>
</div> </div>
{/if} {/if} -->
</div> </div>
<style lang="scss"> <style lang="scss">

View File

@ -0,0 +1,25 @@
import contact, { EmployeeAccount } from '@anticrm/contact'
import { Account, Client, Ref, Timestamp } from '@anticrm/core'
export async function getUser (client: Client, user: Ref<EmployeeAccount> | Ref<Account>): Promise<EmployeeAccount | undefined> {
return await client.findOne(contact.class.EmployeeAccount, { _id: user as Ref<EmployeeAccount> })
}
export function getTime (time: number): string {
let options: Intl.DateTimeFormatOptions = { hour: 'numeric', minute: 'numeric'}
if (!isToday(time)) {
options = {
month: 'numeric',
day: 'numeric',
...options
}
}
return new Date(time).toLocaleString('default', options)
}
export function isToday (time: number): boolean {
const current = new Date()
const target = new Date(time)
return current.getDate() === target.getDate() && current.getMonth() === target.getMonth() && current.getFullYear() === target.getFullYear()
}