Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple Twitter 專案提交 #73

Open
wants to merge 83 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
2b7769e
Create model association
bluesmy Mar 12, 2020
dd509ea
Add signin, signup, logout, and authentication features and pages.
bluesmy Mar 13, 2020
28329c8
add main nav bar
a62262002 Mar 15, 2020
6a825cd
Add user and tweet seed data
a62262002 Mar 16, 2020
44f19fd
Create adminController and admin/tweets page. Add getTweets and authe…
bluesmy Mar 19, 2020
a9dab8c
Add deleteTweet feature
bluesmy Mar 19, 2020
96e62b4
Add getUsers and putUser feature and admin/users page
bluesmy Mar 19, 2020
dd9ecc7
Add user page and tweets page
a62262002 Mar 20, 2020
478b628
user can update tweet
a62262002 Mar 20, 2020
5734263
add popular feature
a62262002 Mar 21, 2020
1997ee7
Merge pull request #1 from bluesmy/feature/admin
bluesmy Mar 23, 2020
01da57d
update the main layout, tweetcontroller, tweets
a62262002 Mar 26, 2020
29948f8
update handlebars-helpers, seeders and tweetController
a62262002 Mar 27, 2020
81cb11e
Add user profile page and related data. Update passport and adminCont…
bluesmy Mar 28, 2020
c04db1e
Update getUser feature
bluesmy Mar 29, 2020
c652b70
Add getLikes feature
bluesmy Mar 29, 2020
ded130c
Add getFollowings feature
bluesmy Mar 29, 2020
8ab2347
Add getFollowers feature and update display if user's following or fo…
bluesmy Mar 29, 2020
230c0eb
Merge branch 'master' into feature/addTweets
bluesmy Mar 29, 2020
03757ee
Delete config.json
bluesmy Mar 29, 2020
1291245
Update app.js
bluesmy Mar 29, 2020
c585d2c
Update passport.js
bluesmy Mar 29, 2020
3469e11
Update package-lock.json and package.json
bluesmy Mar 29, 2020
ac4c1a5
Update index.js
bluesmy Mar 29, 2020
78b5d95
Add follow and unfollow feature
bluesmy Mar 29, 2020
9fc974f
Install socket.io and initialize chat feature
bluesmy Mar 29, 2020
4d1f8e1
Set max length in tweets
bluesmy Mar 31, 2020
061d002
Merge pull request #2 from bluesmy/feature/addTweets
bluesmy Mar 31, 2020
9c03c98
Add files via upload
bluesmy Mar 31, 2020
ade1a9e
Delete .DS_Store
bluesmy Mar 31, 2020
e12c586
Update users pages
bluesmy Mar 31, 2020
56d068b
Merge branch 'master' into feature/user-data
bluesmy Mar 31, 2020
70afb58
Update userController.js
bluesmy Mar 31, 2020
e67abf8
Add User edit feature and update users views
bluesmy Mar 31, 2020
d832636
Merge with remote feature/user-data
bluesmy Mar 31, 2020
0470208
Update views
bluesmy Mar 31, 2020
b243c52
Update tweets.handelbars
bluesmy Mar 31, 2020
25f68c7
Not yet
bluesmy Mar 31, 2020
54071f1
Update getFollowers and getFollowings by removing substring of introd…
bluesmy Mar 31, 2020
f0462f6
Update like model to pass the test
bluesmy Mar 31, 2020
58e4f59
Set cookie and add max limit of msg
bluesmy Mar 31, 2020
467821c
Add add like and reply function
a62262002 Mar 31, 2020
2b666b9
add fontawesome
a62262002 Mar 31, 2020
015809d
Update Chat feature and remove cookie
bluesmy Mar 31, 2020
b0448c0
Return package-lock.json to origin one
bluesmy Apr 1, 2020
89d4040
change the like button and reply messages
a62262002 Apr 1, 2020
af55db4
Merge pull request #5 from bluesmy/feature/addLikeReply
bluesmy Apr 1, 2020
e10945e
Merge branch 'master' into feature/user-data
bluesmy Apr 1, 2020
a655c7f
Merge pull request #3 from bluesmy/feature/user-data
bluesmy Apr 1, 2020
2e17636
update tweets details
a62262002 Apr 2, 2020
b44c929
update the reply function to pass the test
a62262002 Apr 2, 2020
6f78b23
update the profile and likes details
a62262002 Apr 3, 2020
3475e0b
Fix like and reply feature in user profile and like page
bluesmy Apr 4, 2020
6884a79
Merge pull request #7 from bluesmy/feature/updateDetails
bluesmy Apr 4, 2020
1d710f1
Reset config files
bluesmy Apr 4, 2020
3f3281e
Fix merge
bluesmy Apr 4, 2020
a454c38
Update main.handlebars
bluesmy Apr 4, 2020
ac6e333
Update main.handlebars
bluesmy Apr 4, 2020
2f49d8e
Update index.js
bluesmy Apr 4, 2020
b0f5871
Update style to chatroom and add scroll to bottom feature
bluesmy Apr 4, 2020
ce03acf
Add Heroku cofig
bluesmy Apr 4, 2020
934f0bf
Add .env.example
bluesmy Apr 4, 2020
854fdff
Update config.json for heroku
bluesmy Apr 4, 2020
be52fd6
Update heroku config
bluesmy Apr 4, 2020
dac651d
Add Procfile
bluesmy Apr 4, 2020
237b3c2
Update seeder
bluesmy Apr 4, 2020
f236a5f
Fix getUser order
bluesmy Apr 4, 2020
ee43ec2
Add README.md
bluesmy Apr 4, 2020
8c2991f
Update README
bluesmy Apr 4, 2020
da3116c
add share post function
a62262002 Apr 5, 2020
2ec3fe6
add like, profile, replies share button
a62262002 Apr 5, 2020
f4fd531
Adjust style to img
bluesmy Apr 5, 2020
804e2d2
Add submitOnEnter function in chatroom
bluesmy Apr 5, 2020
150210f
Merge pull request #6 from bluesmy/feature/chat
bluesmy Apr 5, 2020
a78dbbe
change the share button
a62262002 Apr 5, 2020
0d910b2
Update admin tweets page, delete show button
bluesmy Apr 5, 2020
0f0e5da
Update chatroom link on navbar
bluesmy Apr 5, 2020
50592f1
Add notes to chatroom link
bluesmy Apr 5, 2020
8e82eb2
Update README.md about chatroom link change
bluesmy Apr 5, 2020
bfcd2c1
Update README
bluesmy Apr 5, 2020
451a7da
add share information
a62262002 Apr 5, 2020
5142a38
Merge pull request #8 from bluesmy/feature/sharePost
bluesmy Apr 5, 2020
90cb6d2
Update package-lock.json
bluesmy Apr 5, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
IMGUR_CLIENT_ID=
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,6 @@ typings/
.fusebox/

# DynamoDB Local files
.dynamodb/
.dynamodb/

temp/
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: node app.js
173 changes: 173 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
# Simple Twitter

A simple web app with simple features similar to Twitter. Built with Node.js, Express, and MySQL.

## Prerequisites

* [npm](https://www.npmjs.com/get-npm)
* [Node.js](https://nodejs.org/en/download/)
* [MySQL](https://dev.mysql.com/downloads/mysql/)
* [MySQL Workbench](https://dev.mysql.com/downloads/workbench/)

## Installing and execution

### Clone

**Clone this repository to your local machine**

```
git clone https://github.com/bluesmy/simple-twitter-express-starter.git
```

### Setup Database

**Create and use ac_twitter_workspace database via MySQL Workbench**

> Run the following code

```
drop database if exists ac_twitter_workspace;
create database ac_twitter_workspace;
use ac_twitter_workspace;
```

### Setup App

**1. Open terminal, change directory to the project folder**

```
$ cd simple-twitter-express-starter
```

**2. Install npm packages**

```
$ npm install
```

**3. Create .env file**

```
$ touch .env
```

**4. Store API Key in .env file and save**

> /.env
```
IMGUR_CLIENT_ID=<YOUR_IMGUR_CLIENT_ID>
```

**5. Edit password in config.json file and delete "operatorsAliases": false**

> /config/config.json
```
"development": {
"username": "root",
"password": "<YOUR_WORKBENCH_PASSWORD>",
"database": "ac_twitter_workspace",
"host": "127.0.0.1",
"dialect": "mysql"
}
```

**6. Create models in database**

> Run the following code in console
```
$ npx sequelize db:migrate
```

**7. Running seeds in database**

> Run the following code in console
```
$ npx sequelize db:seed:all
```

**8. Change chatroom link in views/layouts/main.handlebars**

> /views/layouts/main.handlebars line 28

Change
```
onclick="window.open('https://simple-twitter-express-demo.herokuapp.com/chat', 'Chatroom', config='height=900, width=600')"
```
to
```
onclick="window.open('http://localhost:3000/chat', 'Chatroom', config='height=900, width=600')"
```

**9. Activate the server**

```
$ npm run dev
```

**10. Activation success if you find the message**

```
> Example app listening on port 3000!
```

You may visit the application on browser with the URL: [http://localhost:3000](http://localhost:3000)

## Features

- User can register an account
- User can view all tweets
- User can create tweets
- User can like & unlike tweets
- User can follow other users
- User can reply to tweets
- User can view each user's tweets, followers, followings, likes
- User can edit his/her own profile
- User can view the most followed 10 users
- User can share others' tweets
- User can chat in public chatroom
- Admin can view all tweets
- Admin can delete tweets
- Admin can view all users' data including number of tweets, followings, followers, likes received

## Test Accounts & Passwords

| Email | Password | role |
| ----------------- | -------- | ----- |
| [email protected] | 12345678 | admin |
| [email protected] | 12345678 | user |
| [email protected] | 12345678 | user |

## Built with

* [Bcryptjs ^2.4.3](https://www.npmjs.com/package/bcryptjs) - Password hashing function used
* [Body-Parser ^1.18.3](https://www.npmjs.com/package/body-parser) - Parse incoming request bodies in a middleware before handlers
* [Chai ^4.2.0](https://www.chaijs.com/) - A BDD / TDD assertion library for node and the browser that can be delightfully paired with any javascript testing framework
* [Connect-Flash ^0.1.1](https://www.npmjs.com/package/connect-flash) - Display flash message to user
* [Dotenv ^8.2.0](https://www.npmjs.com/package/dotenv) - Load environment variables from .env file into process.env
* [Express ^4.16.4](https://expressjs.com) - The web framework used
* [Express-Handlebars ^3.0.0](https://www.npmjs.com/package/express-handlebars) - The template engine used
* [Express-Session ^1.15.6](https://www.npmjs.com/package/express-session) - Enable session in express
* [Faker ^4.1.0](https://www.npmjs.com/package/faker) - Generate massive amounts of fake data in the browser and node.js
* [Imgur-Node-Api ^0.1.0](https://www.npmjs.com/package/imgur-node-api) - Imgur anonymous upload in nodejs using the imgur api
* [Method-Override ^3.0.0](https://www.npmjs.com/package/method-override) - Enable usage of HTTP verbs such as PUT or DELETE
* [Mocha ^6.0.2](https://mochajs.org/) - A feature-rich JavaScript test framework
* [Moment ^6.0.2](https://momentjs.com/) - Parse, validate, manipulate, and display dates and times in JavaScript
* [Multer ^1.4.2](https://github.com/expressjs/multer) - A node.js middleware for handling multipart/form-data
* [MySQL2 ^1.6.4](https://www.npmjs.com/package/mysql2) - A relational database management system
* [Node.js](https://nodejs.org/)- A JavaScript runtime built on Chrome's V8 JavaScript engine
* [Passport ^0.4.0](https://www.npmjs.com/package/passport)- Authentication middleware for Node.js
* [Passport-Local ^1.0.0](http://www.passportjs.org/packages/passport-local/) - Passport strategy for authenticating with a username and password
* [Sequelize ^4.42.0](https://sequelize.org/) - A promise-based Node.js ORM for MySQL
* [Sequelize-CLI ^5.5.0](https://github.com/sequelize/cli) - The Sequelize Command Line Interface (CLI)
* [Sequelize-Test-Helpers ^1.0.7](https://www.npmjs.com/package/sequelize-test-helpers) - A collection of utilities to help with unit-testing Sequelize models and code that needs those models
* [Sinon ^7.2.3](https://sinonjs.org/) - Standalone test spies, stubs and mocks for JavaScript
* [Sinon-Chai ^3.3.0](https://www.npmjs.com/package/sinon-chai) - Provide a set of custom assertions for using the Sinon.JS spy, stub, and mocking framework with the Chai assertion library
* [Socket.io ^2.3.0](https://socket.io/) - Enable real-time, bidirectional and event-based communication
* [Supertest ^3.3.0](https://www.npmjs.com/package/supertest) - HTTP assertions made easy via superagent
* [Visual Studio Code](https://code.visualstudio.com/) - The integrated development environment used


## Contributor

* **Sheri Su** - [bluesmy](https://github.com/bluesmy)
* **Emily** - [a62262002](https://github.com/a62262002)
117 changes: 111 additions & 6 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,118 @@
const express = require('express')
const helpers = require('./_helpers');
const helpers = require('./_helpers')

const app = express()
const port = 3000
const port = process.env.PORT || 3000
if (process.env.NODE_ENV !== 'production') {
require('dotenv').config()
}

// use helpers.getUser(req) to replace req.user
// use helpers.ensureAuthenticated(req) to replace req.isAuthenticated()
const server = require('http').Server(app)
const io = require('socket.io')(server)
const records = require('./public/javascripts/records.js')

app.get('/', (req, res) => res.send('Hello World!'))
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
const exphbs = require('express-handlebars')
const bodyParser = require('body-parser')
const flash = require('connect-flash')
const session = require('express-session')
const passport = require('./config/passport')
const methodOverride = require('method-override')

app.engine('handlebars', exphbs({ defaultLayout: 'main', helpers: require('./config/handlebars-helpers') }))
app.set('view engine', 'handlebars')

app.use(express.static('public'))

app.use(bodyParser.urlencoded({ extended: true }))
app.use(bodyParser.json())

const sessionMiddleware = session({
secret: 'secret',
resave: false,
saveUninitialized: false
})

app.use(sessionMiddleware)

io.use((socket, next) => {
sessionMiddleware(socket.request, socket.request.res, next)
})

app.use(passport.initialize())
app.use(passport.session())

app.use(flash())

app.use(methodOverride('_method'))
app.use('/upload', express.static(__dirname + '/upload'))

app.use((req, res, next) => {
res.locals.user = helpers.getUser(req)
res.locals.isAuthenticated = helpers.ensureAuthenticated(req)
res.locals.success_messages = req.flash('success_messages')
res.locals.error_messages = req.flash('error_messages')
next()
})

app.use('/', require('./routes/index'))

// 線上人數計數
let onlineCount = 0

io.on('connection', socket => {
console.log('io connected!')
// 有連線發生時增加人數
onlineCount++
// 發送人數給網頁
io.emit('online', onlineCount)
// 有人進入聊天室時發送通知
socket.on('login', () => {
console.log('A User is connected')
io.emit('user-online')
})

// 新增記錄最大值,用來讓前端網頁知道要放多少筆
socket.emit('maxRecord', records.getMax())

socket.on('send', msg => {
console.log(`send ${msg}`)
// 如果 msg 內容鍵值小於 2 等於是訊息傳送不完全
// 因此我們直接 return ,終止函式執行。
if (Object.keys(msg).length < 2) return
records.push(msg)
})

// 有人正在打字
socket.on('typing', sender => {
console.log(`${sender} is typing`)
// let others know who is typing
socket.broadcast.emit('sender_typing', sender)
})

// 沒有人在打字
socket.on('not_typing', () => {
console.log(`nobody is typing`)
socket.emit('nobody_typing')
})

socket.on('disconnect', () => {
console.log('io disconnected!')
// 有人離線了,扣人
onlineCount = (onlineCount < 0) ? 0 : onlineCount -= 1
io.emit('online', onlineCount)
// 有人離開聊天室時發送通知
console.log('A user is disconnected')
io.emit('user-offline')
})
})

// 新增 Records 的事件監聽器
records.on('new_message', msg => {
console.log(`new message ${msg}`)
// 廣播訊息到聊天室
io.emit("msg", msg)
})

server.listen(port, () => console.log(`Example app listening on port ${port}!`))

module.exports = app
11 changes: 11 additions & 0 deletions config/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const helpers = require('../_helpers')

module.exports = {
authenticated: (req, res, next) => {
if (helpers.ensureAuthenticated(req)) {
return next()
}
req.flash('warning_msg', '請先登入才能使用')
res.redirect('/users/login')
}
}
14 changes: 8 additions & 6 deletions config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,22 @@
"password": "password",
"database": "ac_twitter_workspace",
"host": "127.0.0.1",
"dialect": "mysql"
"dialect": "mysql",
"operatorsAliases": false
},
"test": {
"username": "travis",
"database": "ac_twitter_workspace_test",
"host": "127.0.0.1",
"dialect": "mysql",
"logging" : false
"logging": false
},
"production": {
"username": "root",
"password": null,
"database": "database_production",
"host": "127.0.0.1",
"use_env_variable": "CLEARDB_DATABASE_URL",
"username": "bc07201efc9b46",
"password": "fafe9d4e",
"database": "heroku_db7a4c4fe38de4f",
"host": "us-cdbr-iron-east-01.cleardb.net",
"dialect": "mysql"
}
}
13 changes: 13 additions & 0 deletions config/handlebars-helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const moment = require('moment')

module.exports = {
ifCond: function (a, b, options) {
if (a === b) {
return options.fn(this)
}
return options.inverse(this)
},
moment: function (a) {
return moment(a).format('YYYY-MM-DD,HH:mm')
}
}
Loading