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

V1.0.8 RELEASE #217

Merged
merged 43 commits into from
Jul 28, 2022
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
6884571
Fixing overlapping avatar status with navigation
ZihxS Jul 26, 2022
bc42bda
fix: hover transition on button comment
farhanreizha Jul 26, 2022
75481d9
fix: saved post author image
faruqmaulana Jul 26, 2022
44fa4c2
fix: hover transition on button createpost
farhanreizha Jul 26, 2022
6a0b58b
fix: hover button dropdown authnavbara on dark mode
farhanreizha Jul 26, 2022
3abb0e8
fix: dropdown background on dark mode
farhanreizha Jul 26, 2022
2ee77c9
fix bug toggle theme on mobile view
anandarizkyrm Jul 26, 2022
6b35b6b
Add statistics page in dashboard
mohrizkifajar Jul 26, 2022
f55f428
feat(mention_users): fix #201 performance issue on mentioning users
kbiits Jul 26, 2022
4cccd4c
fix double request on first visit
AsfahanX Jul 26, 2022
377bba9
Merge pull request #193 from ZihxS/dev
deaafrizal Jul 27, 2022
cd11e3f
Merge pull request #195 from farhanreizha/dev
deaafrizal Jul 27, 2022
2352877
Merge pull request #196 from faruqmaulana/dev
deaafrizal Jul 27, 2022
b44c786
Merge pull request #197 from anandarizkyrm/dev
deaafrizal Jul 27, 2022
81631fd
Merge pull request #204 from kbiits/dev
deaafrizal Jul 27, 2022
b83c234
Merge pull request #205 from AsfahanX/dev
deaafrizal Jul 27, 2022
1f43c53
fix conflict
mohrizkifajar Jul 27, 2022
66d699d
Merge branch 'deaaprizal-dev' into dev
mohrizkifajar Jul 27, 2022
f4ef193
feat(rate_limit): add rate limit for post and comment
kbiits Jul 27, 2022
4ec4efe
fix: is like and save button color and text color notification alert
farhanreizha Jul 27, 2022
695b1f0
new hashtag feature
sirilusrifal Jul 27, 2022
e21e01d
Removing border in navbar and adding different color when user contri…
vinoaryo Jul 27, 2022
33a8ea2
Adding width effect when hover
vinoaryo Jul 27, 2022
4cc338b
Merge pull request #207 from kbiits/dev
deaafrizal Jul 28, 2022
ecc44a4
Merge branch 'dev' into feature/hashtag
deaafrizal Jul 28, 2022
6912d2a
Merge pull request #209 from deaaprizal/feature/hashtag
deaafrizal Jul 28, 2022
df6d554
Merge branch 'dev' into dev
deaafrizal Jul 28, 2022
2b85652
Merge pull request #208 from farhanreizha/dev
deaafrizal Jul 28, 2022
d2fe441
Merge pull request #203 from mohrizkifajar/dev
deaafrizal Jul 28, 2022
008e665
Merge pull request #211 from vinoaryo/dev
deaafrizal Jul 28, 2022
9ccb060
fix ui on home
sirilusrifal Jul 28, 2022
33a5a3a
auto hide notification
anandarizkyrm Jul 28, 2022
c4f04ff
Merge pull request #212 from anandarizkyrm/dev
deaafrizal Jul 28, 2022
420b371
setup aos and memasang smooth scroll all page
Jul 28, 2022
cfeec1e
Merge branch 'dev' into dev
Rychhhh Jul 28, 2022
442a9e5
Merge pull request #213 from Ryhann/dev
deaafrizal Jul 28, 2022
c157e75
put animation on every page
Jul 28, 2022
3a766f0
fix team pages
Jul 28, 2022
43e94b3
Merge pull request #215 from Ryhann/dev
deaafrizal Jul 28, 2022
de02925
remove unused state
sirilusrifal Jul 28, 2022
f4ad18f
fix filter ui hidden when open
sirilusrifal Jul 28, 2022
1925865
fix nav responsive mid device
sirilusrifal Jul 28, 2022
8a20213
Merge pull request #216 from deaaprizal/dev
deaafrizal Jul 28, 2022
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
5 changes: 4 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ APP_NAME=CUYUNIVERSE
APP_ENV=local
APP_KEY=genlaravelkey
APP_DEBUG=true
APP_URL=127.0.0.1
APP_URL=http://localhost:8000
APP_THEME="pastel"

LOG_CHANNEL=stack
Expand Down Expand Up @@ -62,3 +62,6 @@ VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

FILESYSTEM_DISK=public

RATE_LIMIT_POST=3
RATE_LIMIT_COMMENT=3
5 changes: 0 additions & 5 deletions .vscode/settings.json

This file was deleted.

2 changes: 1 addition & 1 deletion app/Http/Controllers/DashboardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public function markNotificationAsRead($id)

public function showSavedPost()
{
$savedPosts = SavedPosts::orderByDesc('id')->where('user_id', auth()->user()->id)->with('posts')->with('comments')->get();
$savedPosts = SavedPosts::orderByDesc('id')->where('user_id', auth()->user()->id)->with(['posts.users', 'comments'])->get();
return Inertia::render('Dashboard/SavedPosts', [
'data' => $savedPosts,
'title' => 'SAVED POST',
Expand Down
68 changes: 50 additions & 18 deletions app/Http/Controllers/PostsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
use App\Models\SavedPosts;
use App\Notifications\UserMentioned;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;

class PostsController extends Controller
Expand All @@ -36,6 +38,24 @@ public function index()
]);
}


/**
* @param string $postType Ones of "post" | "comment"
* @param int $perMinute maximum post or comment per minute
*
* @return \Illuminate\Http\RedirectResponse
*/
private function checkRateLimiter(string $postType, $perMinute = 3): \Illuminate\Http\RedirectResponse|null
{
$key = "posts-store-{$postType}-" . Auth::id();
if (RateLimiter::tooManyAttempts($key, $perMinute)) {
return redirect()->back()->with('message', 'Too many attempts');
}

RateLimiter::hit($key);
return null;
}

/**
* Show the form for creating a new resource.
*
Expand All @@ -46,11 +66,15 @@ public function index()
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/

public function store(Request $request)
{
if ($redirect = $this->checkRateLimiter("post", Config::get('rate-limit.post'))) {
return $redirect;
}

$request->validate(
[
'description' => 'required|string|min:4|max:200',
Expand All @@ -71,7 +95,7 @@ public function store(Request $request)

$posts->save();

$this->mentionUser($request->description, $posts);
$this->mentionUsers($request->description, $posts);

return to_route('posts.main')->with('message', 'Posting Berhasil');
}
Expand Down Expand Up @@ -110,14 +134,18 @@ public function storeComment(Request $request)

$post = Posts::find($request->post_id);

if ($redirect = $this->checkRateLimiter("comment-in-" . $post->getKey(), Config::get('rate-limit.comment'))) {
return $redirect;
}

$saveComment = $post->comments()->save($comment);

$user = User::find($post->user_id);
if ($post->user_id !== Auth::id()) {
$user->notify(new UserComment($saveComment));
}

$this->mentionUser($request->description, $post);
$this->mentionUsers($request->description, $post);

return to_route('outer.byId', ['id' => $request->post_id])->with('message', 'Komentar telah dikirim');
}
Expand Down Expand Up @@ -170,24 +198,28 @@ public function destroy(Request $request)
return to_route('posts.main');
}

private function mentionUser($description, Posts $post)
/**
* @param string $content
* @param Posts $post
*
* @return void
*/
public function mentionUsers(string $content, Posts $post)
{
$users = User::select('id', 'username')->get()->pluck('username')->map(function ($item) {
return '@' . $item;
})->all();
$pattern = "/(?:^| )(@[A-Za-z0-9-_]+)/m";
$mentionedUsers = [];

$mentionedUser = Arr::where($users, function ($value, $key) use ($description) {
return Str::contains($description, $value);
});
$res = preg_match_all($pattern, $content, $mentionedUsers);
if (!$res || empty($mentionedUsers[1])) {
return;
}

$mentionedUser = collect($mentionedUser)->map(function ($item) {
return substr($item, 1);
})->all();
$mentionedUsers = array_map(function ($username) {
return Str::after($username, "@");
}, $mentionedUsers[1]);

$notifyUsers = User::whereIn('username', $mentionedUser)->get();
$notifyUsers = User::whereIn('username', $mentionedUsers)->get();

$notifyUsers->each(function ($notifyUser) use ($post) {
$notifyUser->notify(new UserMentioned($post));
});
Notification::send($notifyUsers, new UserMentioned(Auth::user(), $post));
}
}
18 changes: 9 additions & 9 deletions app/Notifications/UserMentioned.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ class UserMentioned extends Notification
* @return void
*/
public $postOrComment;
public User $from;

public function __construct(Posts $postOrComment)
public function __construct(User $from, Posts $postOrComment)
{
$this->postOrComment = $postOrComment;
$this->postOrComment = $postOrComment;
$this->from = $from;
}

/**
Expand All @@ -47,9 +49,9 @@ public function via($notifiable)
public function toMail($notifiable)
{
return (new MailMessage)
->line('The introduction to the notification.')
->action('Notification Action', url('/'))
->line('Thank you for using our application!');
->line('The introduction to the notification.')
->action('Notification Action', url('/'))
->line('Thank you for using our application!');
}

/**
Expand All @@ -67,11 +69,9 @@ public function toArray($notifiable)

public function toDatabase($notifiable)
{
$user = Auth::user();

return [
'from' => $user->username,
// 'notifiable' => $notifiable,
'from' => $this->from->username,
'notifiable' => $notifiable,
'post_id' => $this->postOrComment?->id,
'description' => $this->postOrComment?->description,
'type' => 'mention',
Expand Down
7 changes: 7 additions & 0 deletions config/rate-limit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?php

// Rate limit per minute
return [
'post' => env('RATE_LIMIT_POST', 3),
'comment' => env('RATE_LIMIT_COMMENT', 3),
];
4 changes: 2 additions & 2 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
<env name="APP_ENV" value="testing"/>
<env name="BCRYPT_ROUNDS" value="4"/>
<env name="CACHE_DRIVER" value="array"/>
<!-- <env name="DB_CONNECTION" value="sqlite"/> -->
<!-- <env name="DB_DATABASE" value=":memory:"/> -->
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="MAIL_MAILER" value="array"/>
<env name="QUEUE_CONNECTION" value="sync"/>
<env name="SESSION_DRIVER" value="array"/>
Expand Down
3 changes: 3 additions & 0 deletions resources/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ html.dark body {
@apply bg-slate-800 text-white;
}

.avatar {
z-index: 1;
}

.avatar svg {
display: none;
Expand Down
24 changes: 17 additions & 7 deletions resources/js/Components/Dashboard/CreatePost.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ const CreatePost = ({ props }) => {
let mount = true;
if (limiter > 0) {
const isEmptySpace = /^\s*$/.test(description);
mount && description.length >= 10 && description.length <= 200 && !isEmptySpace ? setIsValid(true) : setIsValid(false);
mount && description.length >= 10 && description.length <= 200 && !isEmptySpace
? setIsValid(true)
: setIsValid(false);
}


return () => {
mount = false;
};
Expand Down Expand Up @@ -69,14 +69,24 @@ const CreatePost = ({ props }) => {
return (
<div className="max-w-7xl overflow-auto mx-auto px-4 sm:px-6 lg:px-8 ">
<div className="flex flex-col justify-center items-center p-4 gap-4">
<div className="alert alert-sm rounded-md shadow-lg w-full lg:w-1/2 dark:bg-slate-700">
<div className="alert alert-sm bg-secondary text-secondary-content rounded-md shadow-lg w-full lg:w-1/2 dark:bg-slate-700 dark:text-slate-300">
<div>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" className="stroke-current flex-shrink-0 w-6 h-6 ">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
className="stroke-current flex-shrink-0 w-6 h-6 ">
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
{isErrorNotif && <NotificationAlert message={props.errors.description} />}
<span>
{!limiter ? "Ngetiknya udah dulu ya, simpen buat postingan berikutnya 👍" : `Saat ini postingan kamu dibatasi ${limiter} karakter`}
{!limiter
? "Ngetiknya udah dulu ya, simpen buat postingan berikutnya 👍"
: `Saat ini postingan kamu dibatasi ${limiter} karakter`}
</span>
</div>
</div>
Expand Down
57 changes: 21 additions & 36 deletions resources/js/Components/Default/Dropdown.jsx
Original file line number Diff line number Diff line change
@@ -1,47 +1,37 @@
import React, { useState, useContext, Fragment } from "react";
import { Link } from "@inertiajs/inertia-react";
import { Transition } from "@headlessui/react";
import React, {useState, useContext, Fragment} from "react";
import {Link} from "@inertiajs/inertia-react";
import {Transition} from "@headlessui/react";

const DropDownContext = React.createContext();

const Dropdown = ({ children }) => {
const Dropdown = ({children}) => {
const [open, setOpen] = useState(false);

const toggleOpen = () => {
setOpen((previousState) => !previousState);
setOpen(previousState => !previousState);
};

return (
<DropDownContext.Provider value={{ open, setOpen, toggleOpen }}>
<DropDownContext.Provider value={{open, setOpen, toggleOpen}}>
<div className="relative">{children}</div>
</DropDownContext.Provider>
);
};

const Trigger = ({ children }) => {
const { open, setOpen, toggleOpen } = useContext(DropDownContext);
const Trigger = ({children}) => {
const {open, setOpen, toggleOpen} = useContext(DropDownContext);

return (
<>
<div onClick={toggleOpen}>{children}</div>

{open && (
<div
className="fixed inset-0 z-40"
onClick={() => setOpen(false)}
></div>
)}
{open && <div className="fixed inset-0 z-40" onClick={() => setOpen(false)}></div>}
</>
);
};

const Content = ({
align = "right",
width = "48",
contentClasses = "py-1",
children,
}) => {
const { open, setOpen } = useContext(DropDownContext);
const Content = ({align = "right", width = "48", contentClasses = "py-1", children}) => {
const {open, setOpen} = useContext(DropDownContext);

let alignmentClasses = "origin-top";

Expand All @@ -67,33 +57,28 @@ const Content = ({
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
leaveTo="transform opacity-0 scale-95">
<div
className={`absolute bg-base-100 z-50 mt-2 rounded-md shadow-lg ${alignmentClasses} ${widthClasses}`}
onClick={() => setOpen(false)}
>
<div
className={
`rounded-md ring-1 ring-secondary ring-opacity-5 ` + contentClasses
}
>
{children}
</div>
className={`absolute bg-base-100 dark:bg-slate-500 z-50 mt-2 rounded-md shadow-lg ${alignmentClasses} ${widthClasses}`}
onClick={() => setOpen(false)}>
<div className={`rounded-md ring-1 ring-secondary ring-opacity-5 ` + contentClasses}>{children}</div>
</div>
</Transition>
</>
);
};

const DropdownLink = ({ href, method = "post", as = "a", children, active }) => {
const DropdownLink = ({href, method = "post", as = "a", children, active}) => {
return (
<Link
href={href}
method={method}
as={as}
className={`block w-full px-4 py-2 text-left dark:text-slate-900 text-sm leading-5 hover:bg-primary hover:text-primary-content focus:border-b-primary dark:hover:text-white focus:outline-none focus:bg-primary transition duration-150 ease-in-out ${active ? 'bg-primary text-primary-content' : 'bg-transparent hover:text-primary-content'}`}
>
className={`block w-full px-4 py-2 text-left dark:bg-slate-500 dark:hover:bg-primary text-sm leading-5 hover:bg-primary hover:text-primary-content focus:border-b-primary dark:hover:text-white focus:outline-none focus:bg-primary transition duration-150 ease-in-out ${
active
? "bg-primary text-primary-content dark:bg-primary dark:text-primary-content"
: "bg-transparent hover:text-primary-content"
}`}>
{children}
</Link>
);
Expand Down
Loading