Compare commits

..

2 Commits

Author SHA1 Message Date
Matjaz
a347e79ded Cleanup. 2022-02-13 21:50:44 +01:00
Matjaz
da1ef02782 Začetek časovnice. 2022-02-13 21:48:01 +01:00
14 changed files with 397 additions and 40 deletions

2
app.js
View File

@ -10,6 +10,7 @@ var usersRouter = require('./routes/user');
var messagesRouter = require('./routes/message');
var loginRouter = require('./routes/login');
var registerRouter = require('./routes/register');
var followRouter = require('./routes/follow');
var app = express();
@ -33,6 +34,7 @@ app.use('/user', usersRouter);
app.use('/message', messagesRouter);
app.use('/login', loginRouter);
app.use('/register', registerRouter);
app.use('/follow', followRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {

Binary file not shown.

View File

@ -28,6 +28,7 @@ fs
db.Message.belongsTo(db.User, {through: 'UserMessages'});
db.User.hasMany(db.Session);
db.Session.belongsTo(db.User);
db.User.belongsToMany(db.User, {as: 'follow', through: 'UserFollows'});
Object.keys(db).forEach(modelName => {
if (db[modelName].associate) {

View File

@ -1,5 +1,9 @@
/*
! tailwindcss v3.0.18 | MIT License | https://tailwindcss.com
/*
npx tailwindcss -i ./src/style.css -o ./public/stylesheets/style.css --watch
*/
/*
! tailwindcss v3.0.18 | MIT License | https://tailwindcss.com
*/
/*
@ -562,6 +566,10 @@ Ensure the default browser behavior of the `hidden` attribute.
display: flex;
}
.inline-flex {
display: inline-flex;
}
.hidden {
display: none;
}
@ -852,16 +860,6 @@ Ensure the default browser behavior of the `hidden` attribute.
color: rgb(37 99 235 / var(--tw-text-opacity));
}
.text-gray-300 {
--tw-text-opacity: 1;
color: rgb(209 213 219 / var(--tw-text-opacity));
}
.text-gray-800 {
--tw-text-opacity: 1;
color: rgb(31 41 55 / var(--tw-text-opacity));
}
.text-gray-500 {
--tw-text-opacity: 1;
color: rgb(107 114 128 / var(--tw-text-opacity));

38
routes/follow.js Normal file
View File

@ -0,0 +1,38 @@
var express = require('express');
var router = express.Router();
var db = require('../models');
var User = db.User;
var Messages = db.Messages;
var Session = db.Session;
var lib = require('../lib');
/* GET home page. */
router.get('/add/:id', async function(req, res, next) {
var id = req.params.id;
console.log(req.cookies.sessionid);
var sessionId = req.cookies.sessionid;
var user = await lib.getAuthUser(sessionId);
if(user) {
var follow = await user.addFollow(id);
res.send(follow);
} else {
res.redirect('/login');
}
});
router.get('/get', async function(req, res, next) {
var id = req.params.id;
console.log(req.cookies.sessionid);
var sessionId = req.cookies.sessionid;
var user = await lib.getAuthUser(sessionId);
if(user) {
var follow = await user.getFollow({
attributes: ['id']
});
res.send(follow);
} else {
res.redirect('/login');
}
});
module.exports = router;

View File

@ -2,6 +2,7 @@ var express = require('express');
var router = express.Router();
var db = require('../models');
var User = db.User;
var Messages = db.Messages;
var Session = db.Session;
var lib = require('../lib');
@ -11,8 +12,14 @@ router.get('/', async function(req, res, next) {
var sessionId = req.cookies.sessionid;
var user = await lib.getAuthUser(sessionId);
if(user) {
var messages = await user.getMessages();
res.render('index', { auth:user, messages:messages });
var messages = await user.getMessages({
order: [
['id', 'DESC'],
],
limit: 10
});
var messageCount = await user.countMessages();
res.render('index', { auth:user, messages:messages, messageCount:messageCount });
} else {
res.redirect('/login');
}

View File

@ -2,6 +2,26 @@ var express = require('express');
const db = require('../models');
var router = express.Router();
var lib = require('../lib');
var Message = db.Message;
var User = db.User;
var Op = db.Sequelize.Op;
async function getAllMessages(user) {
if(user) {
var follows = await user.getFollow();
var timelineMessages = [];
for(var i = 0; i < follows.length; i++) {
timelineMessages[i] = follows[i]
timelineMessages[i].messages = [];
var messages = await follows[i].getMessages();
for(var j = 0; j < messages.length; j++) {
timelineMessages[i].messages.push(messages[j]);
}
}
//var messages = fore
return timelineMessages;
}
}
/* POST a new message */
router.post('/add', async function(req, res, next) {
@ -15,4 +35,37 @@ router.post('/add', async function(req, res, next) {
}
});
router.get('/timeline', async function(req, res, next) {
var sessionId = req.cookies.sessionid;
var user = await lib.getAuthUser(sessionId);
var timeline = await getAllMessages(user);
res.send(timeline);
});
router.get('/timeline2', async function(req, res, next) {
var sessionId = req.cookies.sessionid;
var user = await lib.getAuthUser(sessionId);
if(user) {
var follows = await user.getFollow();
var userList = [];
follows.forEach(element => {
userList.push(element.id);
});
var userMessages = await db.User.findAll({
include: Message,
//required: true,
where: {
id: userList,
'$Messages.createdAt$': {
[Op.like]: '2022%',
}
},
});
res.send(userMessages);
} else {
res.redirect('/login');
}
});
module.exports = router;

View File

@ -2,30 +2,31 @@ var express = require('express');
const db = require('../models');
var router = express.Router();
var User = db.User;
var lib = require('../lib');
/* GET users listing. */
router.get('/', async function(req, res, next) {
var users = await User.findAll();
res.send(users);
});
router.get('/get/:id', async function(req, res, next) {
var users = await User.findByPk (req.params.id);
res.send(users);
});
router.put('/update/:id', async function(req, res, next) {
var users = await User.update({'email':'eve@uplink.si'}, {where:{'ID':req.params.id}});
res.send(users);
});
router.get('/new', async function(req, res, next) {
var users = await User.create({'name':'EVE2', 'email':'eve@2uplink.si', 'password':'some-random-password'});
res.send(users);
});
router.get('/add', function(req, res, next) {
res.send('respond with a resource');
router.get('/:username', async function(req, res, next) {
var test = 123;
var sessionId = req.cookies.sessionid;
var search = req.params.username;
var auth = await lib.getAuthUser(sessionId);
if(auth) {
var user = await User.findOne({
where: {
name: search,
}
});
if(user) {
var messages = await user.getMessages();
var messageCount = await user.countMessages();
res.render('user', {auth:auth, user:user, messages:messages, messageCount:messageCount});
} else {
res.redirect('/');
}
} else {
res.redirect('/login');
}
});
module.exports = router;

View File

@ -0,0 +1,46 @@
'use strict';
module.exports = {
async up (queryInterface, Sequelize) {
/**
* Add seed commands here.
*
* Example:
* await queryInterface.bulkInsert('People', [{
* name: 'John Doe',
* isBetaMember: false
* }], {});
*/
await queryInterface.bulkInsert('users', [
{id: null, name: 'John Doe', email: 'John.Doe@email.com', password: 'password', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
{name: 'Valentin', password: 'random-password', email: 'valentin@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
{name: 'Helena', password: 'random-password', email: 'helena@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
{name: 'Oto', password: 'random-password', email: 'oto@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
{name: 'Peter', password: 'random-password', email: 'peter@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
{name: 'Igor', password: 'random-password', email: 'igor@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
{name: 'Matic', password: 'random-password', email: 'matic@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
{name: 'Jože', password: 'random-password', email: 'joze@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
{name: 'Marko', password: 'random-password', email: 'marko@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
{name: 'Marija', password: 'random-password', email: 'marija@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
{name: 'Brigita', password: 'random-password', email: 'brigita@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
{name: 'Andrej', password: 'random-password', email: 'andrej@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
{name: 'Jaka', password: 'random-password', email: 'jaka@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
{name: 'Natalija', password: 'random-password', email: 'natalija@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
{name: 'Lotta', password: 'random-password', email: 'lotta@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
{name: 'Sven', password: 'random-password', email: 'sven@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
{name: 'Bjorn', password: 'random-password', email: 'bjorn@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
{name: 'Lars', password: 'random-password', email: 'lars@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
{name: 'Matjaž', password: 'random-password', email: 'matjaz.m@uplink.si', createdAt: '2021-02-09 22:16:34.901 +00:00', updatedAt: '2022-02-09 22:16:34.901 +00:00'},
], {});
},
async down (queryInterface, Sequelize) {
/**
* Add commands to revert seed here.
*
* Example:
* await queryInterface.bulkDelete('People', null, {});
*/
//await queryInterface.bulkDelete('Users', null, {});
}
};

View File

@ -1,3 +1,7 @@
/*
npx tailwindcss -i ./src/style.css -o ./public/stylesheets/style.css --watch
*/
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@ -74,8 +74,8 @@
<hr class="my-4">
<div class="flex justify-end">
<button
class="place-content-end bg-blue-600 py-2 px-5 rounded-md mr-3 focus:outline-none focus:shadow-outline"
type="submit">TOOT!</button>
class="place-content-end bg-blue-600 py-2 px-5 rounded-md mr-3 focus:outline-none focus:shadow-outline font-bold"
type="submit">Send</button>
</div>
</form>
</div>
@ -112,7 +112,7 @@
<div class="text-sm text-gray-400 mt-3">
<p>Joined <%= auth.createdAt %></p>
<div class="flex">
<div class="pr-5"><span class="text-white"><%= messages.length %></span> Posts</div>
<div class="pr-5"><span class="text-white"><%= messageCount %></span> Posts</div>
<div class="pr-5"><span class="text-white">3</span> Following</div>
<div class="pr-5"><span class="text-white">7</span> Followers</div>
</div>

View File

@ -1,4 +1,4 @@
<% for(var i=messages.length - 1; i>= 0; i--) {%>
<% for(var i = 0; i < messages.length; i++) {%>
<div class="dark:bg-gray-700 flex p-4 border-b border-b-gray-400">
<div class="mr-4 flex-shrink-0">

View File

@ -0,0 +1,22 @@
<% for(var i = 0; i < messages.length; i++) {%>
<div class="dark:bg-gray-700 flex p-4 border-b border-b-gray-400">
<div class="mr-4 flex-shrink-0">
<img src="/images/avatar_48.png" alt="<%= user.name %>" class="rounded-md">
</div>
<div>
<div>
<h5 class="font-bold mb-4">
<%= user.name %>
</h5>
<p>
<%= messages[i].body%>
</p>
</div>
<div class="text-xs text-gray-500 mt-3">Posted on: <%= messages[i].createdAt %>
</div>
</div>
</div>
<% } %>

185
views/user.ejs Normal file
View File

@ -0,0 +1,185 @@
<!DOCTYPE html>
<html class="dark">
<head>
<title>Social Robot</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="/stylesheets/style.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.2.0/css/fork-awesome.min.css"
integrity="sha256-XoaMnoYC5TH6/+ihMEnospgm0J1PM/nioxbOUdnM8HY=" crossorigin="anonymous">
</head>
<body class="bg-white dark:bg-gray-800 dark:text-white">
<div class="lg:px-24 mx-auto">
<div class="lg:flex justify-center">
<div class="lg:w-72 lg:overflow-y-hidden">
<form method="GET">
<div class="relative text-gray-600 focus-within:text-gray-400">
<span class="absolute inset-y-0 left-0 flex items-center pl-2">
<button type="submit" class="p-1 focus:outline-none focus:shadow-outline">
<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
viewBox="0 0 24 24" class="w-6 h-6">
<path d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
</svg>
</button>
</span>
<input type="search" name="q"
class="w-full py-2 text-sm dark:text-white dark:bg-gray-900 pl-10 focus:outline-none dark:focus:bg-white dark:focus:text-gray-900"
placeholder="Search..." autocomplete="off">
</div>
</form>
<div class="flex items-center justify-between mt-5">
<div class="flex items-center">
<img src="/images/avatar_48.png" alt="<%= auth.name %>" class="rounded-md mr-2">
<div>
<div class="w-full font-bold text-sm"><%= auth.name %></div>
<div class="w-full text-sm text-gray-400"><%= auth.email %></div>
</div>
</div>
<div>
<button type="button" data-dropdown-toggle="dropdown" id="profileDropdownButton" class="bg-gray-700 rounded-md mx-2 px-2 focus:text-blue-400 text-lg font-bold" aria-expanded="true" aria-haspopup="true"><i class="fa fa-angle-down"></i></button>
<!-- This is an example component -->
<div class="max-w-lg mx-auto">
<!-- Dropdown menu -->
<div class="hidden dark:bg-gray-700 dark:text-white z-50 list-none divide-y divide-gray-100 rounded-md shadow my-4" id="dropdown">
<ul class="py-1" aria-labelledby="dropdown">
<li>
<a href="#" class="text-sm hover:bg-gray-600 text-white block px-3 py-1">Dashboard</a>
</li>
<li>
<a href="#" class="text-sm hover:bg-gray-600 text-white block px-3 py-1">Settings</a>
</li>
<li>
<a href="#" class="text-sm hover:bg-gray-600 text-white block px-3 py-1">Earnings</a>
</li>
<li>
<a href="#" class="text-sm hover:bg-gray-600 text-white block px-3 py-1">Sign out</a>
</li>
</ul>
</div>
</div>
<script src="/scripts/flowbite.js"></script>
</div>
</div>
<div class="my-5">
<form method="POST" action="/message/add">
<textarea
class="w-full h-36 p-1 dark:text-white dark:bg-gray-900 focus:outline-none dark:focus:bg-white dark:focus:text-gray-900 text-sm"
name="body" id="body" cols="20" placeholder="What's on your mind?"></textarea>
<hr class="my-4">
<div class="flex justify-end">
<button
class="place-content-end bg-blue-600 py-2 px-5 rounded-md mr-3 focus:outline-none focus:shadow-outline font-bold"
type="submit">Send</button>
</div>
</form>
</div>
</div>
<div
class="lg:flex-1 lg:mx-3 max-w-xl min-w-md dark:bg-gray-600 dark:text-white scrollbar-thin scrollbar-thumb-gray-900 scrollbar-track-gray-700 overflow-y-scroll">
<div class="lg:h-screen">
<div class="bg-gray-900 text-white p-4 flex justify-between w-full z-50"">
<div><i class=" fa fa-home mr-2"></i>Home</div>
<div><i class="fa fa-sliders"></i></div>
</div>
<div class="max-h-40 overflow-y-hidden align-bottom">
<img class="object-none object-center" src="/images/19187755.jpg" alt="paralax">
</div>
<div class="flex justify-between">
<div class="flex-shrink-0 max-h-10 relative -top-10 px-4">
<img src="/images/avatar_94.png" alt="<%= user.name %>" class="rounded-md overflow-visible">
</div>
<div class="flex items-center pt-3 px-2 mx-2">
<button class="bg-blue-600
py-2
px-5
rounded-md
mr-3
focus:outline-none
focus:shadow-outline"
type="submit">Follow</button>
<a class="bg-blue-600
py-2
px-5
rounded-md
mr-3
focus:outline-none
focus:shadow-outline
inline-flex
items-center
"
href="/follow/add/<%= user.id %>">Link</a>
<button
class="bg-gray-600 border border-b-gray-400 py-2 px-5 rounded-md focus:outline-none focus:shadow-outline shadow-xl"
type="submit"><i class="fa fa-ellipsis-v"></i></button>
</div>
</div>
<div class="p-4">
<div>
<h4 class="font-bold"><%= user.name %></h4>
<p class="text-sm text-gray-400"><%= user.email %></p>
</div>
<div class="text-sm text-gray-400 mt-3">
<p>Joined <%= user.createdAt %></p>
<div class="flex">
<div class="pr-5"><span class="text-white"><%= messageCount %></span> Posts</div>
<div class="pr-5"><span class="text-white">3</span> Following</div>
<div class="pr-5"><span class="text-white">7</span> Followers</div>
</div>
</div>
</div>
<%- include('partials/_user_timeline', {user:user, messages:messages}) %>
</div>
</div>
<div class="lg:w-72 lg:overflow-y-hidden">
<ul class="p-5">
<li>
<a class="font-bold text-lg mb-4 block"><i class="fa fa-home mr-2"></i>Home</a>
</li>
<li>
<a class="font-bold text-lg mb-4 block"><i class="fa fa-bell mr-2"></i>Notifications</a>
</li>
<li>
<a class="font-bold text-lg mb-4 block"><i class="fa fa-group mr-2"></i>Local</a>
</li>
<li>
<a class="font-bold text-lg mb-4 block"><i class="fa fa-globe mr-2"></i>Federated</a>
</li>
<li>
<a class="font-bold text-lg mb-4 block"><i class="fa fa-envelope mr-2"></i>Direct messages</a>
</li>
<li>
<a class="font-bold text-lg mb-4 block"><i class="fa fa-star mr-2"></i>Favourites</a>
</li>
<li>
<a class="font-bold text-lg mb-4 block"><i class="fa fa-bookmark mr-2"></i>Bookmarks</a>
</li>
<li>
<a class="font-bold text-lg mb-4 block"><i class="fa fa-list mr-2"></i>Lists</a>
</li>
<li>
<a class="font-bold text-lg mb-4 block"><i class="fa fa-address-book mr-2"></i>Profile directory</a>
</li>
<li>
<a class="font-bold text-lg mb-4 block"><i class="fa fa-cog mr-2"></i>Preferences</a>
</li>
<li>
<a class="font-bold text-lg mb-4 block"><i class="fa fa-group mr-2"></i>Follows and followers</a>
</li>
</ul>
</div>
</div>
</div>
</body>
</html>