Skip to content

Commit

Permalink
Merge pull request #1 from tyr-rust-bootcamp/feature/v11-1-replace-cs…
Browse files Browse the repository at this point in the history
…s-with-tailwind

feature: replace css with tailwind
  • Loading branch information
tyrchen authored Aug 30, 2024
2 parents dd21644 + 8892334 commit 2e5c286
Show file tree
Hide file tree
Showing 18 changed files with 989 additions and 646 deletions.
45 changes: 41 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,44 @@
# Tauri + Vue 3
# Chat App

This template should help get you started developing with Tauri + Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
A modern, real-time chat application built with Vue.js and Tauri. It connects to the chat server which was introduced in [chat server](https://github.com/tyr-rust-bootcamp/05-chat).

## Recommended IDE Setup
## Features

- [VS Code](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)
- Real-time messaging
- User-friendly interface
- work across web and desktop
- Lightweight and fast performance

## Prerequisites

Before you begin, ensure you have met the following requirements:

- Node.js (v18 or later)
- Rust (latest stable version)
- Tauri CLI

## Setup

1. Clone the repository:
```
git clone https://github.com/yourusername/chat-app.git
cd chat-app
```

2. Install dependencies:
```
yarn
```


## Running the App

To run the desktop app, you could use:
```
cargo tauri dev
```

To run the web app, you could use:
```
yarn dev
```
7 changes: 2 additions & 5 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Slack-like Chat UI</title>
<!-- Add Google Font -->
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap"
rel="stylesheet"
/>
<!-- Inter font from Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet" />
</head>

<body>
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
"devDependencies": {
"@tauri-apps/cli": ">=2.0.0-rc.0",
"@vitejs/plugin-vue": "^5.0.5",
"autoprefixer": "^10.4.20",
"postcss": "^8.4.41",
"tailwindcss": "^3.4.10",
"vite": "^5.3.1"
}
}
6 changes: 6 additions & 0 deletions postcss.config.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module.exports = {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
]
}
17 changes: 3 additions & 14 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,11 @@
<template>
<router-view />
<div class="h-full flex flex-col overflow-hidden">
<router-view />
</div>
</template>

<script>
export default {
name: 'App',
};
</script>

<style>
html, body, #app {
height: 100%;
margin: 0;
overflow: hidden; /* Prevent scrolling */
}
#app {
display: flex;
flex-direction: column;
}
</style>
35 changes: 0 additions & 35 deletions src/assets/styles.css

This file was deleted.

97 changes: 27 additions & 70 deletions src/components/MessageList.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<template>
<div class="message-list">
<div v-if="messages.length === 0" class="no-messages">
<div class="flex-1 overflow-y-auto p-5 mb-10" ref="messageContainer">
<div v-if="messages.length === 0" class="text-center text-gray-400 mt-5">
No messages in this channel yet.
</div>
<div v-else>
<div v-for="message in messages" :key="message.id" class="message">
<img :src="`https://ui-avatars.com/api/?name=${getSender(message.senderId).fullname.replace(' ', '+')}`" class="avatar" alt="Avatar" />
<div class="message-content">
<div class="message-header">
<span class="message-user">{{ getSender(message.senderId).fullname }}</span>
<span class="message-time">{{ formatTime(message.createdAt) }}</span>
<div v-for="message in messages" :key="message.id" class="flex items-start mb-5">
<img :src="`https://ui-avatars.com/api/?name=${getSender(message.senderId).fullname.replace(' ', '+')}`" class="w-10 h-10 rounded-full mr-3" alt="Avatar" />
<div class="max-w-4/5">
<div class="flex items-center mb-1">
<span class="font-bold mr-2">{{ getSender(message.senderId).fullname }}</span>
<span class="text-xs text-gray-500">{{ message.formattedCreatedAt }}</span>
</div>
<div class="message-text">{{ message.content }}</div>
<div class="text-sm leading-relaxed break-words whitespace-pre-wrap">{{ message.content }}</div>
</div>
</div>
</div>
Expand All @@ -33,85 +33,42 @@ export default {
}
},
watch: {
messages: {
handler() {
this.$nextTick(() => {
this.scrollToBottom();
});
},
deep: true
},
activeChannelId(newChannelId) {
if (newChannelId) {
this.fetchMessages(newChannelId);
}
}
},
methods: {
formatTime(time) {
const date = new Date(time);
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
},
fetchMessages(channelId) {
this.$store.dispatch('fetchMessagesForChannel', channelId);
},
getSender(userId) {
return this.$store.getters.getUserById(userId);
},
scrollToBottom() {
const container = this.$refs.messageContainer;
if (container) {
container.scrollTop = container.scrollHeight;
}
}
},
mounted() {
if (this.activeChannelId) {
this.fetchMessages(this.activeChannelId);
}
this.scrollToBottom();
},
updated() {
this.scrollToBottom();
}
};
</script>

<style scoped>
/* Container styling */
.message-list {
flex: 1;
overflow-y: auto;
padding: 20px;
}
/* Individual message styling */
.message {
display: flex;
align-items: flex-start;
margin-bottom: 20px;
}
.avatar {
width: 40px;
height: 40px;
border-radius: 50%;
margin-right: 10px;
}
.message-content {
max-width: 80%;
}
/* Header styling: username and timestamp */
.message-header {
display: flex;
align-items: center;
margin-bottom: 5px;
}
.message-user {
font-weight: bold;
margin-right: 10px;
}
.message-time {
font-size: 12px;
}
/* Message text styling */
.message-text {
font-size: 14px;
line-height: 1.4;
word-wrap: break-word;
white-space: pre-wrap;
}
.no-messages {
text-align: center;
color: #b9bbbe;
margin-top: 20px;
}
</style>
57 changes: 4 additions & 53 deletions src/components/MessageSend.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<template>
<div class="message-send">
<div class="flex items-center p-4 bg-white border-t border-gray-200">
<input
v-model="message"
@keyup.enter="sendMessage"
placeholder="Type a message..."
class="message-input"
class="flex-1 px-4 py-3 mr-2 text-sm bg-gray-100 border-none rounded-lg focus:outline-none"
type="text"
/>
<button @click="sendMessage" class="send-button">
<button @click="sendMessage" class="p-2 text-white bg-blue-600 rounded-full hover:bg-blue-700 focus:outline-none">
<svg
xmlns="http://www.w3.org/2000/svg"
class="icon"
class="w-5 h-5"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
Expand Down Expand Up @@ -66,52 +66,3 @@ export default {
},
};
</script>

<style scoped>
/* Container styling */
.message-send {
display: flex;
align-items: center;
padding: 10px 0px;
background-color: #fff;
border-top: 1px solid #eee;
}
/* Input field styling */
.message-input {
flex: 1;
padding: 12px 12px;
border: none;
border-radius: 10px;
background-color: #eee;
font-size: 14px;
margin: 0px 10px;
}
.message-input::placeholder {
color: #72767d;
}
/* Send button styling */
.send-button {
background-color: #5865f2;
border: none;
border-radius: 50%;
padding: 10px;
margin-right: 5px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: white;
}
.send-button .icon {
width: 20px;
height: 20px;
}
.send-button:hover {
background-color: #4752c4;
}
</style>
Loading

0 comments on commit 2e5c286

Please sign in to comment.