Add: insert review
This commit is contained in:
@@ -92,6 +92,8 @@ func NewAPI(config Config) (*API, error) {
|
|||||||
apiMux.HandleFunc("/delete_tag_on_file", api.HandleDeleteTagOnFile)
|
apiMux.HandleFunc("/delete_tag_on_file", api.HandleDeleteTagOnFile)
|
||||||
// folder
|
// folder
|
||||||
apiMux.HandleFunc("/update_foldername", api.HandleUpdateFoldername)
|
apiMux.HandleFunc("/update_foldername", api.HandleUpdateFoldername)
|
||||||
|
// review
|
||||||
|
apiMux.HandleFunc("/insert_review", api.HandleInsertReview)
|
||||||
// below needs token
|
// below needs token
|
||||||
apiMux.HandleFunc("/walk", api.HandleWalk)
|
apiMux.HandleFunc("/walk", api.HandleWalk)
|
||||||
apiMux.HandleFunc("/reset", api.HandleReset)
|
apiMux.HandleFunc("/reset", api.HandleReset)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ var (
|
|||||||
ErrNotLoggedIn = errors.New("not logged in")
|
ErrNotLoggedIn = errors.New("not logged in")
|
||||||
ErrNotAdmin = errors.New("not admin")
|
ErrNotAdmin = errors.New("not admin")
|
||||||
ErrEmpty = errors.New("Empty field detected, please fill in all fields")
|
ErrEmpty = errors.New("Empty field detected, please fill in all fields")
|
||||||
|
ErrAnonymous = errors.New("Anonymous user detected, please login")
|
||||||
)
|
)
|
||||||
|
|
||||||
type Error struct {
|
type Error struct {
|
||||||
|
|||||||
42
pkg/api/handle_review.go
Normal file
42
pkg/api/handle_review.go
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"msw-open-music/pkg/database"
|
||||||
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// review.FileId, review.Content
|
||||||
|
func (api *API) HandleInsertReview(w http.ResponseWriter, r *http.Request) {
|
||||||
|
review := &database.Review{}
|
||||||
|
|
||||||
|
err := json.NewDecoder(r.Body).Decode(review)
|
||||||
|
if err != nil {
|
||||||
|
api.HandleError(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// check not anonymous
|
||||||
|
err = api.CheckNotAnonymous(w, r)
|
||||||
|
if err != nil {
|
||||||
|
api.HandleError(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
review.UserId, err = api.GetUserID(w, r)
|
||||||
|
if err != nil {
|
||||||
|
api.HandleError(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
review.CreatedAt = time.Now().Unix()
|
||||||
|
|
||||||
|
err = api.Db.InsertReview(review)
|
||||||
|
if err != nil {
|
||||||
|
api.HandleError(w, r, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
api.HandleOK(w, r)
|
||||||
|
}
|
||||||
@@ -165,6 +165,25 @@ func (api *API) CheckAdmin(w http.ResponseWriter, r *http.Request) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (api *API) CheckNotAnonymous(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
session, _ := api.store.Get(r, api.defaultSessionName)
|
||||||
|
userId, ok := session.Values["userId"]
|
||||||
|
if !ok {
|
||||||
|
return ErrNotLoggedIn
|
||||||
|
}
|
||||||
|
|
||||||
|
user, err := api.Db.GetUserById(userId.(int64))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if user.Role == database.RoleAnonymous {
|
||||||
|
return ErrAnonymous
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (api *API) GetUserID(w http.ResponseWriter, r *http.Request) (int64, error) {
|
func (api *API) GetUserID(w http.ResponseWriter, r *http.Request) (int64, error) {
|
||||||
session, _ := api.store.Get(r, api.defaultSessionName)
|
session, _ := api.store.Get(r, api.defaultSessionName)
|
||||||
userId, ok := session.Values["userId"]
|
userId, ok := session.Values["userId"]
|
||||||
|
|||||||
10
pkg/database/method_review.go
Normal file
10
pkg/database/method_review.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package database
|
||||||
|
|
||||||
|
func (database *Database) InsertReview(review *Review) error {
|
||||||
|
_, err := database.stmt.insertReview.Exec(
|
||||||
|
review.UserId,
|
||||||
|
review.FileId,
|
||||||
|
review.CreatedAt,
|
||||||
|
review.Content)
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -71,10 +71,12 @@ var initLikesTableQuery = `CREATE TABLE IF NOT EXISTS likes (
|
|||||||
var initReviewsTableQuery = `CREATE TABLE IF NOT EXISTS reviews (
|
var initReviewsTableQuery = `CREATE TABLE IF NOT EXISTS reviews (
|
||||||
id INTEGER PRIMARY KEY,
|
id INTEGER PRIMARY KEY,
|
||||||
user_id INTEGER NOT NULL,
|
user_id INTEGER NOT NULL,
|
||||||
time INTEGER NOT NULL,
|
file_id INTEGER NOT NULL,
|
||||||
modified_time INTEGER DEFAULT 0,
|
created_at INTEGER NOT NULL,
|
||||||
review TEXT NOT NULL,
|
updated_at INTEGER NOT NULL DEFAULT 0,
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
content TEXT NOT NULL,
|
||||||
|
FOREIGN KEY (user_id) REFERENCES users(id),
|
||||||
|
FOREIGN KEY (file_id) REFERENCES files(id)
|
||||||
);`
|
);`
|
||||||
|
|
||||||
var initPlaybacksTableQuery = `CREATE TABLE IF NOT EXISTS playbacks (
|
var initPlaybacksTableQuery = `CREATE TABLE IF NOT EXISTS playbacks (
|
||||||
@@ -202,6 +204,9 @@ var deleteTagOnFileQuery = `DELETE FROM file_has_tag WHERE tag_id = ? AND file_i
|
|||||||
|
|
||||||
var updateFoldernameQuery = `UPDATE folders SET foldername = ? WHERE id = ?;`
|
var updateFoldernameQuery = `UPDATE folders SET foldername = ? WHERE id = ?;`
|
||||||
|
|
||||||
|
var insertReviewQuery = `INSERT INTO reviews (user_id, file_id, created_at, content)
|
||||||
|
VALUES (?, ?, ?, ?);`
|
||||||
|
|
||||||
type Stmt struct {
|
type Stmt struct {
|
||||||
initFilesTable *sql.Stmt
|
initFilesTable *sql.Stmt
|
||||||
initFoldersTable *sql.Stmt
|
initFoldersTable *sql.Stmt
|
||||||
@@ -242,6 +247,7 @@ type Stmt struct {
|
|||||||
getTagsOnFile *sql.Stmt
|
getTagsOnFile *sql.Stmt
|
||||||
deleteTagOnFile *sql.Stmt
|
deleteTagOnFile *sql.Stmt
|
||||||
updateFoldername *sql.Stmt
|
updateFoldername *sql.Stmt
|
||||||
|
insertReview *sql.Stmt
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewPreparedStatement(sqlConn *sql.DB) (*Stmt, error) {
|
func NewPreparedStatement(sqlConn *sql.DB) (*Stmt, error) {
|
||||||
@@ -546,5 +552,11 @@ func NewPreparedStatement(sqlConn *sql.DB) (*Stmt, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// init insertReview
|
||||||
|
stmt.insertReview, err = sqlConn.Prepare(insertReviewQuery)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return stmt, err
|
return stmt, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,18 @@ type Tag struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
CreatedByUserId int64 `json:"created_by_user_id"`
|
CreatedByUserId int64 `json:"created_by_user_id"`
|
||||||
CreatedByUser *User `json:"created_by_user"`
|
CreatedByUser *User `json:"created_by_user"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Review struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
FileId int64 `json:"file_id"`
|
||||||
|
File *File `json:"file"`
|
||||||
|
UserId int64 `json:"user_id"`
|
||||||
|
User *User `json:"user"`
|
||||||
|
CreatedAt int64 `json:"created_at"`
|
||||||
|
UpdatedAt int64 `json:"updated_at"`
|
||||||
|
Content string `json:"content"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import Tags from "./component/Tags";
|
|||||||
import EditTag from "./component/EditTag";
|
import EditTag from "./component/EditTag";
|
||||||
import AudioPlayer from "./component/AudioPlayer";
|
import AudioPlayer from "./component/AudioPlayer";
|
||||||
import UserStatus from "./component/UserStatus";
|
import UserStatus from "./component/UserStatus";
|
||||||
|
import ReviewPage from "./component/ReviewPage";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
@@ -90,6 +91,10 @@ function App() {
|
|||||||
path="/files/:id/share"
|
path="/files/:id/share"
|
||||||
element={<Share setPlayingFile={setPlayingFile} />}
|
element={<Share setPlayingFile={setPlayingFile} />}
|
||||||
/>
|
/>
|
||||||
|
<Route
|
||||||
|
path="/files/:id/review"
|
||||||
|
element={<ReviewPage setPlayingFile={setPlayingFile} />}
|
||||||
|
/>
|
||||||
</Routes>
|
</Routes>
|
||||||
</main>
|
</main>
|
||||||
<footer>
|
<footer>
|
||||||
|
|||||||
@@ -106,6 +106,13 @@ function FileInfo(props) {
|
|||||||
>
|
>
|
||||||
Play
|
Play
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
navigate(`/files/${params.id}/review`);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Review
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
navigate(`/files/${params.id}/share`);
|
navigate(`/files/${params.id}/share`);
|
||||||
|
|||||||
43
web/src/component/ReviewPage.js
Normal file
43
web/src/component/ReviewPage.js
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { useParams } from "react-router";
|
||||||
|
|
||||||
|
function ReviewPage() {
|
||||||
|
let params = useParams();
|
||||||
|
const [newReview, setNewReview] = useState("");
|
||||||
|
|
||||||
|
function submitReview() {
|
||||||
|
fetch("/api/v1/insert_review", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
content: newReview,
|
||||||
|
file_id: parseInt(params.id),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
.then((res) => res.json())
|
||||||
|
.then((data) => {
|
||||||
|
if (data.error) {
|
||||||
|
alert(data.error);
|
||||||
|
} else {
|
||||||
|
setNewReview("");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="page">
|
||||||
|
<h3>Review Page</h3>
|
||||||
|
<div>
|
||||||
|
<textarea
|
||||||
|
value={newReview}
|
||||||
|
onChange={(e) => setNewReview(e.target.value)}
|
||||||
|
/>
|
||||||
|
<button onClick={() => submitReview()}>Submit</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ReviewPage;
|
||||||
Reference in New Issue
Block a user