diff --git a/web/app/Http/Controllers/Api/FeedController.php b/web/app/Http/Controllers/Api/FeedController.php index e44cc86..7e97f52 100644 --- a/web/app/Http/Controllers/Api/FeedController.php +++ b/web/app/Http/Controllers/Api/FeedController.php @@ -79,8 +79,18 @@ class FeedController extends Controller return response($posts); } - protected function handle() + protected function share(Request $request) { - // + $validated = $request->validate([ + 'content' => ['required', 'max:200'] + ]); + + $shout = new Shout(); + $shout->poster_id = Auth::id(); + $shout->poster_type = 'user'; + $shout->content = $validated['content']; + $shout->save(); + + return response(['success' => true]); } } diff --git a/web/resources/js/components/Feed.js b/web/resources/js/components/Feed.js index c6b7747..8a5a48c 100644 --- a/web/resources/js/components/Feed.js +++ b/web/resources/js/components/Feed.js @@ -1,7 +1,7 @@ // © XlXi 2021 // Graphictoria 5 -import { Component } from 'react'; +import { Component, createRef } from 'react'; import axios from 'axios'; @@ -17,12 +17,19 @@ class Feed extends Component { super(props); this.state = { feedLoaded: false, + feedDisabled: false, loadingCursor: false, + error: '', feedPosts: [], mouseHover: -1 }; + this.inputBox = createRef(); + + // XlXi: Thanks, React. + this.loadPosts = this.loadPosts.bind(this); this.loadMore = this.loadMore.bind(this); + this.sharePost = this.sharePost.bind(this); } componentWillMount() { @@ -34,6 +41,10 @@ class Feed extends Component { } componentDidMount() { + this.loadPosts(); + } + + loadPosts() { axios.get(buildGenericApiUrl('api', 'feed/v1/list-json')) .then(res => { const posts = res.data; @@ -61,14 +72,45 @@ class Feed extends Component { } } + sharePost() { + this.setState({ feedDisabled: true }); + + const postText = this.inputBox.current.value; + if (postText == '') { + this.setState({ feedDisabled: false, error: 'Your shout cannot be blank.' }); + this.inputBox.current.focus(); + return; + } + + axios.post(buildGenericApiUrl('api', `feed/v1/share`), { content: postText }) + .then(res => { + this.inputBox.current.value = ''; + this.setState({ feedLoaded: false, loadingCursor: false, feedDisabled: false }); + this.loadPosts(); + }) + .catch(err => { + const data = err.response.data; + + this.setState({ feedDisabled: false, error: data.message }); + this.inputBox.current.focus(); + }); + } + render() { return ( <>

My Feed

+ { + this.state.error != '' + ? +
{ this.state.error }
+ : + null + }
- - + this.setState({ error: '' }) } ref={ this.inputBox } /> +
{ diff --git a/web/routes/api.php b/web/routes/api.php index aa84c0f..9d58dda 100644 --- a/web/routes/api.php +++ b/web/routes/api.php @@ -6,7 +6,7 @@ Route::middleware('auth')->group(function () { Route::group(['as' => 'feed.', 'prefix' => 'feed'], function() { Route::group(['as' => 'v1.', 'prefix' => 'v1'], function() { Route::get('/list-json', 'FeedController@listjson')->name('list'); - Route::post('/handle ', 'FeedController@handle')->name('handle'); + Route::post('/share ', 'FeedController@share')->name('share')->middleware('throttle:3,2'); }); }); });