Update some styles and fix channel settings

This commit is contained in:
2025-08-12 03:45:52 +02:00
parent 3edab7fbd7
commit 9f0943748f
7 changed files with 108 additions and 174 deletions

View File

@@ -152,126 +152,77 @@ const handleKeydown = (event: KeyboardEvent) => {
<style scoped>
.message {
padding: 0.75rem 1rem;
border: 1px solid transparent;
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 8px;
margin-bottom: 0.5rem;
transition: all 0.2s ease;
padding: 12px 16px;
margin-bottom: 8px;
}
.message:hover,
.message:focus {
background: rgba(0, 0, 0, 0.02);
border-color: #e5e7eb;
outline: none;
.message:hover {
background: #f1f3f4;
}
.message:focus {
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.1);
border-color: #3b82f6;
outline: 2px solid #1976d2;
outline-offset: 2px;
}
.message--unsent {
opacity: 0.7;
background: #fef3c7;
border-color: #fbbf24;
background: #fff3e0;
border-color: #ff9800;
}
.message--highlighted {
background: #dbeafe;
border-color: #3b82f6;
animation: highlight-fade 2s ease-out;
}
@keyframes highlight-fade {
0% {
background: #bfdbfe;
border-color: #2563eb;
}
100% {
background: #dbeafe;
border-color: #3b82f6;
}
background: #e3f2fd;
border-color: #2196f3;
}
.message__content {
font-size: 0.875rem;
line-height: 1.5;
color: #111827;
margin-bottom: 0.5rem;
white-space: pre-wrap;
word-wrap: break-word;
color: #212529;
font-size: 14px;
line-height: 1.4;
margin-bottom: 8px;
}
.message__files {
margin: 0.5rem 0;
display: flex;
flex-direction: column;
gap: 0.25rem;
margin: 8px 0;
}
.message__meta {
display: flex;
align-items: center;
justify-content: flex-end;
gap: 0.5rem;
gap: 8px;
}
.message__time {
font-size: 0.75rem;
color: #6b7280;
color: #6c757d;
font-size: 12px;
}
.message__status {
font-size: 0.75rem;
color: #f59e0b;
color: #ff9800;
font-size: 12px;
font-weight: 500;
}
/* Dark mode */
@media (prefers-color-scheme: dark) {
.message:hover,
.message:focus {
background: rgba(255, 255, 255, 0.05);
border-color: #374151;
.message {
background: #2d3748;
border-color: #4a5568;
color: #e2e8f0;
}
.message:focus {
border-color: #60a5fa;
box-shadow: 0 0 0 2px rgba(96, 165, 250, 0.1);
}
.message--unsent {
background: #451a03;
border-color: #92400e;
}
.message--highlighted {
background: #1e3a8a;
border-color: #60a5fa;
}
@keyframes highlight-fade {
0% {
background: #1e40af;
border-color: #3b82f6;
}
100% {
background: #1e3a8a;
border-color: #60a5fa;
}
.message:hover {
background: #374151;
}
.message__content {
color: rgba(255, 255, 255, 0.87);
color: #e2e8f0;
}
.message__time {
color: rgba(255, 255, 255, 0.6);
}
.message__status {
color: #fbbf24;
color: #a0aec0;
}
}
</style>

View File

@@ -8,6 +8,7 @@
:is-active="channel.id === currentChannelId"
:unread-count="unreadCounts[channel.id]"
@select="$emit('select-channel', $event)"
@info="$emit('channel-info', $event)"
/>
</ul>
</div>
@@ -27,6 +28,7 @@ defineProps<Props>()
defineEmits<{
'select-channel': [channelId: number]
'channel-info': [channel: Channel]
}>()
</script>

View File

@@ -43,6 +43,7 @@ defineProps<Props>()
defineEmits<{
select: [channelId: number]
info: [channel: Channel]
}>()
</script>
@@ -52,6 +53,12 @@ defineEmits<{
margin: 0;
}
.channel-wrapper {
display: flex;
align-items: center;
gap: 0.5rem;
}
.channel-button {
display: flex;
align-items: center;
@@ -117,6 +124,35 @@ defineEmits<{
color: #3b82f6;
}
.channel-info-button {
display: flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
padding: 0;
background: none;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 1rem;
opacity: 0.6;
transition: all 0.2s ease;
flex-shrink: 0;
}
.channel-info-button:hover {
opacity: 1;
background: rgba(0, 0, 0, 0.05);
}
.channel-info-button:focus {
outline: none;
background: rgba(59, 130, 246, 0.1);
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
opacity: 1;
}
/* Dark mode */
@media (prefers-color-scheme: dark) {
.channel-button {
@@ -142,5 +178,14 @@ defineEmits<{
.channel-item--active .channel-button:hover {
background: #2563eb;
}
.channel-info-button:hover {
background: rgba(255, 255, 255, 0.1);
}
.channel-info-button:focus {
background: rgba(96, 165, 250, 0.1);
box-shadow: 0 0 0 2px rgba(96, 165, 250, 0.2);
}
}
</style>

View File

@@ -18,6 +18,7 @@
:current-channel-id="currentChannelId"
:unread-counts="unreadCounts"
@select-channel="$emit('select-channel', $event)"
@channel-info="$emit('channel-info', $event)"
/>
</div>
@@ -50,6 +51,7 @@ defineProps<Props>()
defineEmits<{
'create-channel': []
'select-channel': [channelId: number]
'channel-info': [channel: Channel]
'settings': []
}>()
</script>

View File

@@ -112,7 +112,7 @@ export const useAppStore = defineStore('app', () => {
const updateSettings = async (newSettings: Partial<AppSettings>) => {
settings.value = { ...settings.value, ...newSettings }
await set('app_settings', settings.value)
await set('app_settings', JSON.parse(JSON.stringify(settings.value)))
}
const loadState = async () => {

View File

@@ -1,18 +1,4 @@
:root {
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* Minimal reset styles only */
* {
box-sizing: border-box;
}
@@ -23,6 +9,13 @@ body {
width: 100vw;
height: 100vh;
overflow: hidden;
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
#app {
@@ -33,61 +26,6 @@ body {
overflow: hidden;
}
/* Button styles */
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
color: inherit;
cursor: pointer;
transition: border-color 0.25s;
outline: none;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 2px solid #646cff;
outline-offset: 2px;
}
button:disabled {
opacity: 0.6;
cursor: not-allowed;
}
/* Input styles */
input, textarea {
border-radius: 8px;
border: 1px solid #3a3a3a;
padding: 0.6em 1.2em;
font-size: 1em;
font-family: inherit;
background-color: #2a2a2a;
color: inherit;
outline: none;
}
input:focus, textarea:focus {
border-color: #646cff;
outline: 2px solid #646cff;
outline-offset: 2px;
}
/* List styles */
ul {
list-style: none;
padding: 0;
margin: 0;
}
/* Accessibility helpers */
.sr-only {
position: absolute;
@@ -99,27 +37,4 @@ ul {
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
/* Focus indicators */
.focus-visible {
outline: 2px solid #646cff;
outline-offset: 2px;
}
/* Light mode */
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
button {
background-color: #f9f9f9;
}
input, textarea {
background-color: #ffffff;
border-color: #d1d5db;
}
}

View File

@@ -7,6 +7,7 @@
:unread-counts="unreadCounts"
@create-channel="showChannelDialog = true"
@select-channel="selectChannel"
@channel-info="handleChannelInfo"
@settings="showSettings = true"
/>
@@ -80,6 +81,14 @@
@sent="handleCameraSent"
/>
</BaseDialog>
<BaseDialog v-model:show="showChannelInfoDialog" title="Channel Settings">
<ChannelInfoDialog
v-if="selectedChannelForInfo"
:channel="selectedChannelForInfo"
@close="showChannelInfoDialog = false"
/>
</BaseDialog>
</div>
</template>
@@ -108,9 +117,10 @@ import SearchDialog from '@/components/dialogs/SearchDialog.vue'
import FileUploadDialog from '@/components/dialogs/FileUploadDialog.vue'
import VoiceRecordingDialog from '@/components/dialogs/VoiceRecordingDialog.vue'
import CameraCaptureDialog from '@/components/dialogs/CameraCaptureDialog.vue'
import ChannelInfoDialog from '@/components/dialogs/ChannelInfoDialog.vue'
// Types
import type { ExtendedMessage } from '@/types'
import type { ExtendedMessage, Channel } from '@/types'
const router = useRouter()
const appStore = useAppStore()
@@ -130,12 +140,16 @@ const messageInput = ref()
// Dialog states
const showChannelDialog = ref(false)
const showChannelInfoDialog = ref(false)
const showSettings = ref(false)
const showSearchDialog = ref(false)
const showFileDialog = ref(false)
const showVoiceDialog = ref(false)
const showCameraDialog = ref(false)
// Channel info state
const selectedChannelForInfo = ref<Channel | null>(null)
// Mock unread counts (implement real logic later)
const unreadCounts = ref<Record<number, number>>({})
@@ -362,6 +376,11 @@ const handleChannelCreated = async (channelId: number) => {
await selectChannel(channelId)
}
const handleChannelInfo = (channel: Channel) => {
selectedChannelForInfo.value = channel
showChannelInfoDialog.value = true
}
const isUnsentMessage = (messageId: string | number): boolean => {
return typeof messageId === 'string' && messageId.startsWith('unsent_')
}