diff --git a/controllers/moderator/announcements.go b/controllers/moderator/announcements.go index 64d6c7da..d4b594e6 100644 --- a/controllers/moderator/announcements.go +++ b/controllers/moderator/announcements.go @@ -59,15 +59,15 @@ func addAnnouncement(c *gin.Context) { c.AbortWithStatus(http.StatusNotFound) } } - delay := int(math.Ceil(math.Max(1, float64(announcement.Expire.Sub(time.Now())/(24*time.Hour))))) + duration := int(math.Ceil(math.Max(1, float64(announcement.Expire.Sub(time.Now())/(24*time.Hour))))) form := &announcementValidator.CreateForm{ ID: announcement.ID, Message: announcement.Content, - Delay: delay, + Duration: duration, } c.Bind(form) - if form.Delay == 0 { - form.Delay = delay + if form.Duration == 0 { + form.Duration = duration } templates.Form(c, "admin/announcement_form.jet.html", form) } @@ -102,7 +102,8 @@ func postAnnouncement(c *gin.Context) { } } else { // announcement doesn't exist, we create it var err error - announcement, err := notifications.NotifyAll(form.Message, time.Now().AddDate(0, 0, form.Delay)) + currentTime := time.Now() + announcement, err := notifications.NotifyAll(form.Message, currentTime.Add(time.Hour * time.Duration(form.Duration))) if err != nil { // Error, we add it as a message messages.AddErrorT("errors", "create_failed") @@ -120,7 +121,7 @@ func postAnnouncement(c *gin.Context) { // deleteAnnouncement : Controller for deleting an announcement func deleteAnnouncement(c *gin.Context) { - id, _ := strconv.ParseInt(c.Query("id"), 10, 32) + id, _ := strconv.ParseInt(c.PostForm("id"), 10, 32) announcement, err := notifications.FindByID(uint(id)) if err != nil { c.AbortWithStatus(http.StatusNotFound) diff --git a/controllers/moderator/helpers.go b/controllers/moderator/helpers.go index 26ac97e6..ded87655 100644 --- a/controllers/moderator/helpers.go +++ b/controllers/moderator/helpers.go @@ -146,7 +146,7 @@ func torrentManyAction(c *gin.Context) { query.Append("torrent_id", torrentID) reports, _, _ := reports.FindOrderBy(query, "", 0, 0) for _, report := range reports { - report.Delete(false) + report.Delete() } messages.AddInfoTf("infos", "torrent_reports_deleted", torrent.Name) } diff --git a/controllers/moderator/reports.go b/controllers/moderator/reports.go index d78d54bb..cee63d9d 100644 --- a/controllers/moderator/reports.go +++ b/controllers/moderator/reports.go @@ -1,7 +1,6 @@ package moderatorController import ( - "fmt" "html" "net/http" "strconv" @@ -39,13 +38,16 @@ func TorrentReportListPanel(c *gin.Context) { func TorrentReportDeleteModPanel(c *gin.Context) { id := c.PostForm("id") - fmt.Println(id) - idNum, _ := strconv.ParseUint(id, 10, 64) - _, _, _ = reports.Delete(uint(idNum)) - /* If we need to log report delete activity - if err == nil { - activity.Log(&models.User{}, torrent.Identifier(), "delete", "torrent_report_deleted_by", strconv.Itoa(int(report.ID)), router.GetUser(c).Username) + if c.Request.URL.Query()["all"] != nil { + reports.DeleteAll() + } else { + idNum, _ := strconv.ParseUint(id, 10, 64) + _, _, _ = reports.Delete(uint(idNum)) + /* If we need to log report delete activity + if err == nil { + activity.Log(&models.User{}, torrent.Identifier(), "delete", "torrent_report_deleted_by", strconv.Itoa(int(report.ID)), router.GetUser(c).Username) + } + */ } - */ c.Redirect(http.StatusSeeOther, "/mod/reports?deleted") } diff --git a/controllers/moderator/torrents.go b/controllers/moderator/torrents.go index 4b12eeef..b594f5e9 100644 --- a/controllers/moderator/torrents.go +++ b/controllers/moderator/torrents.go @@ -129,26 +129,19 @@ func TorrentDeleteModPanel(c *gin.Context) { var err error if definitely != nil { _, _, err = torrent.DefinitelyDelete() - - //delete reports of torrent - query := &search.Query{} - query.Append("torrent_id", id) - reports, _, _ := reports.FindOrderBy(query, "", 0, 0) - for _, report := range reports { - report.Delete(true) - } returnRoute = "/mod/torrents/deleted" } else { _, _, err = torrent.Delete(false) - - //delete reports of torrent - query := &search.Query{} - query.Append("torrent_id", id) - reports, _, _ := reports.FindOrderBy(query, "", 0, 0) - for _, report := range reports { - report.Delete(false) - } } + + //delete reports of torrent + query := &search.Query{} + query.Append("torrent_id", id) + reports, _, _ := reports.FindOrderBy(query, "", 0, 0) + for _, report := range reports { + report.Delete() + } + if err == nil { if torrent.Uploader == nil { torrent.Uploader = &models.User{} @@ -176,7 +169,7 @@ func DeleteTagsModPanel(c *gin.Context) { // TorrentBlockModPanel : Controller to lock torrents, redirecting to previous page func TorrentBlockModPanel(c *gin.Context) { - id, _ := strconv.ParseInt(c.Query("id"), 10, 32) + id, _ := strconv.ParseInt(c.PostForm("id"), 10, 32) torrent, _, err := torrents.ToggleBlock(uint(id)) var returnRoute, action string if torrent.IsDeleted() { diff --git a/controllers/report/report.go b/controllers/report/report.go index bdca0073..c04e408a 100644 --- a/controllers/report/report.go +++ b/controllers/report/report.go @@ -21,7 +21,7 @@ func ReportTorrentHandler(c *gin.Context) { messages := msg.GetMessages(c) captchaError := "?reported" currentUser := router.GetUser(c) - if currentUser.NeedsCaptcha() { + if currentUser.ID == 0 { userCaptcha := captcha.Extract(c) if !captcha.Authenticate(userCaptcha) { captchaError = "?badcaptcha" @@ -33,7 +33,11 @@ func ReportTorrentHandler(c *gin.Context) { messages.Error(err) } if !messages.HasErrors() { - _, err := reports.Create(c.PostForm("report_type"), torrent, currentUser) + reportMessage := c.PostForm("report_message") + if len(reportMessage) > 60 { + reportMessage = reportMessage[0:60] + } + _, err := reports.Create(c.PostForm("report_type"), reportMessage, torrent, currentUser) messages.AddInfoTf("infos", "report_msg", id) if err != nil { messages.ImportFromError("errors", err) diff --git a/controllers/themeToggle/themeToggle.go b/controllers/themeToggle/themeToggle.go index a0e9c639..d53de1a3 100644 --- a/controllers/themeToggle/themeToggle.go +++ b/controllers/themeToggle/themeToggle.go @@ -42,7 +42,9 @@ func toggleThemeHandler(c *gin.Context) { http.SetCookie(c.Writer, &http.Cookie{Name: "theme2", Value: theme, Domain: getDomainName(), Path: "/", Expires: timeHelper.FewDaysLater(365)}) //Redirect user to page he was in beforehand - c.Redirect(http.StatusSeeOther, c.Param("redirect") + "#footer") + if c.Request.URL.Query()["no_redirect"] == nil { + c.Redirect(http.StatusSeeOther, c.Param("redirect") + "#footer") + } return } diff --git a/controllers/torrent/delete.go b/controllers/torrent/delete.go index 2a84828f..5f853fa1 100644 --- a/controllers/torrent/delete.go +++ b/controllers/torrent/delete.go @@ -35,7 +35,7 @@ func TorrentDeleteUserPanel(c *gin.Context) { query.Append("torrent_id", id) torrentReports, _, _ := reports.FindOrderBy(query, "", 0, 0) for _, report := range torrentReports { - report.Delete(false) + report.Delete() } } c.Redirect(http.StatusSeeOther, "/?deleted") diff --git a/controllers/torrent/view.go b/controllers/torrent/view.go index 10934956..e32cbed2 100644 --- a/controllers/torrent/view.go +++ b/controllers/torrent/view.go @@ -40,9 +40,9 @@ func ViewHandler(c *gin.Context) { // Retrieve the torrent torrent, err := torrents.FindByID(uint(id)) - // If come from notification, toggle the notification as read - if c.Request.URL.Query()["notif"] != nil && user.ID > 0 { - notifications.ToggleReadNotification(torrent.Identifier(), user.ID) + // Toggle the notifications related to this torrent as read + if user.ID > 0 { + notifications.ToggleReadNotification(torrent.Identifier(), user) } // If torrent not found, display 404 diff --git a/controllers/user/follow.go b/controllers/user/follow.go index 85ffa976..ccd73add 100644 --- a/controllers/user/follow.go +++ b/controllers/user/follow.go @@ -15,7 +15,7 @@ func UserFollowHandler(c *gin.Context) { id, _ := strconv.ParseUint(c.Param("id"), 10, 32) currentUser := router.GetUser(c) user, _, errorUser := users.FindForAdmin(uint(id)) - if errorUser == nil && user.ID > 0 { + if errorUser == nil && user.ID > 0 && currentUser.ID > 0 && user.ID != currentUser.ID { if !currentUser.IsFollower(uint(id)) { followAction = "followed" currentUser.SetFollow(user) @@ -28,5 +28,8 @@ func UserFollowHandler(c *gin.Context) { if c.Query("id") != "" { url = "/view/" + c.Query("id") + "?" + followAction } + if currentUser.ID == 0 { + url = "/login" + } c.Redirect(http.StatusSeeOther, url) } diff --git a/controllers/user/profile.go b/controllers/user/profile.go index 4a900b81..634ac395 100644 --- a/controllers/user/profile.go +++ b/controllers/user/profile.go @@ -8,7 +8,6 @@ import ( "net/http" "github.com/NyaaPantsu/nyaa/controllers/router" - "github.com/NyaaPantsu/nyaa/models" "github.com/NyaaPantsu/nyaa/models/notifications" "github.com/NyaaPantsu/nyaa/models/users" "github.com/NyaaPantsu/nyaa/templates" @@ -190,9 +189,13 @@ func UserProfileFormHandler(c *gin.Context) { validator.ValidateForm(&userForm, messages) if !messages.HasErrors() { if userForm.Email != userProfile.Email { - email.SendVerificationToUser(currentUser, userForm.Email) - messages.AddInfoTf("infos", "email_changed", userForm.Email) - userForm.Email = userProfile.Email // reset, it will be set when user clicks verification + if currentUser.HasAdmin() { + userProfile.Email = userForm.Email + } else { + email.SendVerificationToUser(currentUser, userForm.Email) + messages.AddInfoTf("infos", "email_changed", userForm.Email) + userForm.Email = userProfile.Email // reset, it will be set when user clicks verification + } } user, _, err := users.UpdateFromRequest(c, &userForm, &userSettingsForm, currentUser, uint(id)) if err != nil { @@ -204,6 +207,7 @@ func UserProfileFormHandler(c *gin.Context) { } if !messages.HasErrors() { messages.AddInfoT("infos", "profile_updated") + userProfile = user } } } @@ -215,11 +219,13 @@ func UserProfileFormHandler(c *gin.Context) { func UserNotificationsHandler(c *gin.Context) { currentUser := router.GetUser(c) if currentUser.ID > 0 { - messages := msg.GetMessages(c) if c.Request.URL.Query()["clear"] != nil { - notifications.DeleteAllNotifications(currentUser.ID) - messages.AddInfoT("infos", "notifications_cleared") - currentUser.Notifications = []models.Notification{} + notifications.DeleteNotifications(currentUser, false) + + } else if c.Request.URL.Query()["clear_all"] != nil { + notifications.DeleteNotifications(currentUser, true) + } else if c.Request.URL.Query()["read_all"] != nil { + notifications.MarkAllNotificationsAsRead(currentUser) } templates.UserProfileNotifications(c, currentUser) } else { diff --git a/models/comments/helpers.go b/models/comments/helpers.go index 97960d7b..21e24bbb 100644 --- a/models/comments/helpers.go +++ b/models/comments/helpers.go @@ -12,6 +12,9 @@ import ( // When a new comment is added this is called func NewCommentEvent(comment *models.Comment, torrent *models.Torrent) { comment.Torrent = torrent + if comment.UserID == torrent.UploaderID { + return + } url := "/view/" + strconv.FormatUint(uint64(torrent.ID), 10) if torrent.UploaderID > 0 { torrent.Uploader.ParseSettings() diff --git a/models/notification.go b/models/notification.go index 963e48b1..1a0f3451 100644 --- a/models/notification.go +++ b/models/notification.go @@ -15,13 +15,14 @@ type Notification struct { Identifier string URL string Expire time.Time + Date time.Time UserID uint // User *User `gorm:"AssociationForeignKey:UserID;ForeignKey:user_id"` // Don't think that we need it here } // NewNotification : Create a new notification func NewNotification(identifier string, c string, url string) Notification { - return Notification{Identifier: identifier, Content: c, URL: url} + return Notification{Identifier: identifier, Content: c, URL: url, Date: time.Now()} } // TableName : Return the name of notification table diff --git a/models/notifications/notifier.go b/models/notifications/notifier.go index 04314319..60fb0383 100644 --- a/models/notifications/notifier.go +++ b/models/notifications/notifier.go @@ -18,11 +18,38 @@ func NotifyUser(user *models.User, name string, msg string, url string, email bo } // ToggleReadNotification : Make a notification as read according to its identifier -func ToggleReadNotification(identifier string, id uint) { // - models.ORM.Model(&models.Notification{}).Where("identifier = ? AND user_id = ?", identifier, id).Updates(models.Notification{Read: true}) +func ToggleReadNotification(identifier string, user *models.User) { // + models.ORM.Model(&models.Notification{}).Where("identifier = ? AND user_id = ?", identifier, user.ID).Updates(models.Notification{Read: true}) + for i, notif := range user.Notifications { + if notif.Identifier == identifier { + user.Notifications[i].Read = true + } + } + //Need to update both DB and variable, otherwise when the function is called the user still needs to do an additional refresh to see the notification gone/read } -// DeleteAllNotifications : Erase notifications from a user -func DeleteAllNotifications(id uint) { // - models.ORM.Where("user_id = ?", id).Delete(&models.Notification{}) +// MarkAllNotificationsAsRead : Force every notification as read +func MarkAllNotificationsAsRead(user *models.User) { // + models.ORM.Model(&models.Notification{}).Where("user_id = ?", user.ID).Updates(models.Notification{Read: true}) + for i := range user.Notifications { + user.Notifications[i].Read = true + } + //Need to update both DB and variable, otherwise when the function is called the user still needs to do an additional refresh to see the notification gone/read +} + +// DeleteNotifications : Erase notifications from a user +func DeleteNotifications(user *models.User, all bool) { // + if all { + models.ORM.Where("user_id = ?", user.ID).Delete(&models.Notification{}) + user.Notifications = []models.Notification{} + } else { + models.ORM.Where("user_id = ? AND read = ?", user.ID, true).Delete(&models.Notification{}) + NewNotifications := []models.Notification{} + for _, notif := range user.Notifications { + if !notif.Read { + NewNotifications = append(NewNotifications, notif) + } + } + user.Notifications = NewNotifications + } } diff --git a/models/notifications/system.go b/models/notifications/system.go index 58a9575c..df9ebb7b 100644 --- a/models/notifications/system.go +++ b/models/notifications/system.go @@ -27,8 +27,8 @@ func NotifyAll(msg string, expire time.Time) (*models.Notification, error) { // UpdateAnnouncement updates an announcement func UpdateAnnouncement(announcement *models.Notification, form *announcementValidator.CreateForm) error { announcement.Content = form.Message - if form.Delay > 0 { - announcement.Expire = time.Now().AddDate(0, 0, form.Delay) + if form.Duration > 0 { + announcement.Expire = time.Now().Add(time.Hour * time.Duration(form.Duration)) } if models.ORM.Model(announcement).UpdateColumn(announcement).Error != nil { return errors.New("Announcement was not updated") diff --git a/models/report.go b/models/report.go index 5b39bb74..f38f2344 100644 --- a/models/report.go +++ b/models/report.go @@ -11,8 +11,9 @@ import ( // User can be null (anonymous reports) // FIXME can't preload field Torrents for models.TorrentReport type TorrentReport struct { - ID uint `gorm:"column:torrent_report_id;primary_key"` + ID uint `gorm:"column:torrent_report_id;primary_key"` Description string `gorm:"column:type"` + Message string `gorm:"column:message"` TorrentID uint `gorm:"column:torrent_id"` UserID uint `gorm:"column:user_id"` @@ -31,6 +32,7 @@ func (report TorrentReport) TableName() string { type TorrentReportJSON struct { ID uint `json:"id"` Description string `json:"description"` + Message string `json:"message"` Torrent TorrentJSON `json:"torrent"` User UserJSON `json:"user"` } @@ -45,7 +47,7 @@ func (report *TorrentReport) ToJSON() TorrentReportJSON { if report.User != nil { u = report.User.ToJSON() } - json := TorrentReportJSON{report.ID, report.Description, t, u} + json := TorrentReportJSON{report.ID, report.Description, report.Message, t, u} return json } @@ -59,9 +61,6 @@ func TorrentReportsToJSON(reports []TorrentReport) []TorrentReportJSON { } // Delete : Delete torrent report -func (report *TorrentReport) Delete(definitely bool) (int, error) { - if definitely { - return 0, ORM.Unscoped().Delete(report).Error - } - return http.StatusOK, nil +func (report *TorrentReport) Delete() (int, error) { + return http.StatusOK, ORM.Unscoped().Delete(report).Error } diff --git a/models/reports/create.go b/models/reports/create.go index fc1dec68..2c094390 100644 --- a/models/reports/create.go +++ b/models/reports/create.go @@ -7,9 +7,10 @@ import ( "errors" ) -func Create(desc string, torrent *models.Torrent, user *models.User) (*models.TorrentReport, error) { +func Create(desc string, message string, torrent *models.Torrent, user *models.User) (*models.TorrentReport, error) { report := &models.TorrentReport{ Description: desc, + Message: message, TorrentID: torrent.ID, UserID: user.ID, CreatedAt: time.Now(), diff --git a/models/reports/interaction.go b/models/reports/interaction.go index 6a93d68f..bbe52f6c 100644 --- a/models/reports/interaction.go +++ b/models/reports/interaction.go @@ -20,31 +20,22 @@ type Query interface { Prepend(string, ...interface{}) } -// Delete : Delete a torrent report by id func Delete(id uint) (*models.TorrentReport, int, error) { - return delete(id, false) -} - -// DeleteDefinitely : Delete definitely a torrent report by id -func DeleteDefinitely(id uint) (*models.TorrentReport, int, error) { - return delete(id, true) -} - -func delete(id uint, definitely bool) (*models.TorrentReport, int, error) { var torrentReport models.TorrentReport - db := models.ORM - if definitely { - db = models.ORM.Unscoped() - } + db := models.ORM.Unscoped() if db.First(&torrentReport, id).RecordNotFound() { return &torrentReport, http.StatusNotFound, errors.New("try_to_delete_report_inexistant") } - if _, err := torrentReport.Delete(false); err != nil { + if _, err := torrentReport.Delete(); err != nil { return &torrentReport, http.StatusInternalServerError, err } return &torrentReport, http.StatusOK, nil } +func DeleteAll() { + models.ORM.Delete(&models.TorrentReport{}) +} + func findOrderBy(parameters Query, orderBy string, limit int, offset int, countAll bool) ( torrentReports []models.TorrentReport, count int, err error, ) { diff --git a/models/torrent.go b/models/torrent.go index e5237bdf..e68ed7d0 100644 --- a/models/torrent.go +++ b/models/torrent.go @@ -216,6 +216,14 @@ func (t *Torrent) ParseTrackers(trackers []string) { } } } + tempTrackers := []string{} + for _, line := range trackers { + if !contains(tempTrackers, line) { + tempTrackers = append(tempTrackers, line) + } + } + trackers = tempTrackers + v["tr"] = trackers t.Trackers = v.Encode() } @@ -517,3 +525,12 @@ func (t *Torrent) DeleteTags() { log.CheckErrorWithMessage(err, "LOAD_TAGS_ERROR: Couldn't delete tags!") } } + +func contains(s []string, e string) bool { + for _, a := range s { + if a == e { + return true + } + } + return false +} diff --git a/public/css/main.css b/public/css/main.css index e7e01042..9fb0c1c0 100644 --- a/public/css/main.css +++ b/public/css/main.css @@ -252,7 +252,7 @@ select.form-input { .not-important { font-size: 9pt; - margin: 2px 3px; + margin: 0 3px 2px 3px; color: #8a8a8a; } @@ -346,10 +346,11 @@ select.form-input { color: #292929; background: #fd6b6b; padding: 1px 4px; - border-radius: 7px; - font-size: 10px; + font-size: 8px; top: 37px; - right: 19px; + right: 22px; + max-height: 17px; + line-height: 10px; } #content { @@ -662,6 +663,9 @@ th { .website-nav table { width: auto; } +.website-nav table tr { + background: none!important; +} .website-nav #nav-category-list { width: 70%; margin-bottom: 7px; @@ -758,6 +762,9 @@ html, body { .header .h-user>a.nav-btn { padding: 0!important; } + .user-avatar span { + right: 25px; + } .nav-btn.log-in span { display: none; } @@ -901,6 +908,9 @@ html, body { .header .h-user .user-avatar { margin: 0; } + .user-avatar span { + right: 20px; + } .header .h-user { max-width: 46px; width: auto; @@ -944,7 +954,9 @@ html, body { .header .h-user .nav-btn { height: 57px; } - + .user-avatar span { + right: 14px; + } h3 { margin-bottom: 5px; } @@ -1062,8 +1074,7 @@ html, body { margin-bottom: 2px; } -.profile-usertitle-uploadcount span { - font-weight: bold; +.profile-usertitle-uploadcount b { margin-left: 2px; } @@ -1182,7 +1193,7 @@ html, body { .comment-box { padding: 0 7px; margin: 10px 30px 0 30px; - min-height: 70px; + min-height: 67px; word-break: break-word; text-align: justify; } @@ -1191,11 +1202,16 @@ html, body { margin-top: 9px; } -.comment-box .comment-user { - font-size: 12px; +.comment-box .comment-userinfo { + display: block; + margin-top: 8px; } -.comment-box span+p img { +.comment-box .comment-user { + font-size: 12px; +} + +.comment-userinfo img { width: 50px; height: 50px; float: left; @@ -1215,6 +1231,11 @@ html, body { margin-left: 4px; } +.comment-content { + max-width: 100%; + max-height: 500px; +} + .comment-content :last-child { margin-bottom: 2px; } @@ -1226,8 +1247,12 @@ html, body { padding-bottom: 5px; } +.comment-form textarea { + margin-bottom: 0; +} + .comment-form h3 { - margin-bottom: 8px; + margin-bottom: 8px; } .comment-index { @@ -1276,7 +1301,7 @@ div.profile-content.box>nav>ul>a>li { width: 100%; } -div.profile-content.box>nav>ul>a>li, nav.adminNav>ul>li { +div.profile-content.box>nav>ul>a>li { border-right-width: 1px; } @@ -1538,7 +1563,9 @@ input.filelist-checkbox:checked+table.table-filelist { .modal-body :first-child { margin-top: 0; } - +.modal-body h4 { + margin-bottom: 6px; +} /* Modal Footer */ @@ -1560,7 +1587,7 @@ input.filelist-checkbox:checked+table.table-filelist { margin-top: 7px; padding: 0.7em 1.5em; background: none; - border: 1px solid white; + border: 1px solid black; border-radius: 3px; color: white; font-weight: bold; @@ -1757,11 +1784,11 @@ input.filelist-checkbox:checked+table.table-filelist { padding: 0 10px 10px; } -.btn-blue:hover, .btn-red:hover, .btn-green:hover, .btn-orange:hover { +[class^="btn-"]:hover { opacity: 0.7; } -.btn-blue, .btn-red, .btn-green, .btn-orange { +[class^="btn-"] { font-weight: bold; color: white; } @@ -2196,6 +2223,9 @@ iframe { height: 36px; margin-bottom: 0; } +.adminNav { + margin: 12px 0 5px 0px; +} table.multiple-upload { @@ -2299,6 +2329,11 @@ table.multiple-upload { right: 16px; } +.user-search-notice { + margin: 10px 0 0 1px; + font-weight: bold; +} + .torrent-info-row .tr-se span, .torrent-info-row .tr-le span, .torrent-info-row .tr-dl span { font-weight: bold; background-color: #ffe0bf; @@ -2348,6 +2383,61 @@ form.delete-form button.form-input.btn-red { bottom: 9px; } +#clear-notification { + bottom: 8px; + right: 8px; + position: absolute; + width: calc(100% - 16px); +} +#clear-notification a { + float: right; + margin-left: 3px; +} +.notification-table { + margin-bottom: 44px; +} +.notification-table td { + text-align: center; + padding: 6px 0; + border-bottom: 1px solid; +} +.notification-table tr:hover td { + filter: brightness(1.2); +} +.notification-status { + width: 140px; +} +.notification-event { + text-align: left!important; + padding: 6px 10px!important; +} +.notification-date { + width: 195px; +} +td.notification-status { + border: 1px solid black; +} +td.notification-status { + background-color: #e4e4e4; +} +td.notification-status.notification-unread { + background-color: rgb(161, 211, 253); + color: white; +} + +.torrent-report-table td, .torrent-report-table th { + width: 165px; +} +.td-report-message { + width: auto!important; + white-space: normal; + word-break: break-word; +} + +.locked { + background: hsla(216, 10%, 73%, 0.2) !important; +} + /* Language specific CSS */ html[lang="ja-jp"] .form-refine span.spacing { diff --git a/public/css/themes/classic.css b/public/css/themes/classic.css index a7e8cd9a..36f6e7a6 100644 --- a/public/css/themes/classic.css +++ b/public/css/themes/classic.css @@ -26,7 +26,7 @@ body, .header { font-family: Arial, sans-serif!important; } .torrent-info-data { - width: 59%; + width: 52%; } #torrent-view-data { margin-left: 10px; @@ -37,8 +37,8 @@ body, .header { width: 87%; } -.comment-box p:nth-child(2) { - margin-top: auto; +.comment-userinfo { + margin-top: 0!important; } .form-refine span.spacing { @@ -54,7 +54,7 @@ body, .header { #sort-list-order { width: auto; - margin-left: 4px; + margin-left: 3px; } a { @@ -63,12 +63,12 @@ a { .sukebei a { color: #660000; } -a:hover { +a:hover, .h-nav a:hover, .h-nav:active a:hover { text-decoration: underline; } .upload-form-table .checkbox-container+input { - width: 385px; + width: 385px;1 } .upload-form-table .table-checkboxes { padding: 3px 0!important; @@ -95,7 +95,7 @@ th.tr-name a { font-size: 0.9em; } .tr-links { - width: 29px; + width: 22px; text-align: right; } .tr-links .icon-magnet::before { @@ -158,7 +158,7 @@ th.tr-name a { } .header .container>div { line-height: 40px; - padding: 0 0.2rem; + padding: 0 0.4rem; } .header .nav-btn { @@ -245,6 +245,8 @@ select.form-input { } .sukebei .pagination span:hover { background-color: #993333; + color: white; + font-weight: normal; } .website-nav .pagination p { display: none; @@ -254,7 +256,7 @@ select.form-input { padding-top: 4px!important; } .website-nav .pagination { - padding: .5rem; + padding: .5rem 0 0rem 0; font-size: 1em; } .website-nav .pagination a { @@ -327,7 +329,7 @@ span.comment-index+p { margin-top: 0; } -span.comment-index+p a { +.comment-user { font-weight: bold; padding-top: 2px; font-size: .9em; @@ -335,12 +337,11 @@ span.comment-index+p a { text-decoration: none; line-height: 22px; } -span.comment-index+p a:hover { +.comment-user:hover { text-decoration: underline; } - .comment-index { - margin: 3px 0 0 0; + margin: 1px 0; } #solution { @@ -382,6 +383,7 @@ span.comment-index+p a:hover { #description-box { font-size: 0.8em; + border-radius: 5px; } .form-input { border-color: #c4c4c4 !important; @@ -395,6 +397,11 @@ span.comment-index+p a:hover { width: 24px; margin-top: 8px; } +.user-avatar span { + font-size: 8px; + top: 20px; + right: 9px; +} .torrent-info-data.uploader-link { font-weight: bold; @@ -402,13 +409,16 @@ span.comment-index+p a:hover { .torrent-info-data.uploader-anon { font-style: italic; } -.torrent-info-data.uploader-link a, .torrent-info-data.uploader-anon a{ +.torrent-info-data.uploader-link a, .torrent-info-data.uploader-anon a, .user-search-notice a{ color: green; } #torrent-description-hr { margin-top: 40px; } +.torrent-hr { + font-size: 15px; +} .comment-submit h3 { font-size: 1em; @@ -451,7 +461,7 @@ span.comment-index+p a:hover { float: left; } .sukebei .torrent-buttons a, .sukebei .torrent-buttons button { - background: linear-gradient(to bottom, #CA3346 5%, #482120 80%); + background: linear-gradient(to bottom, #CA3346 5%, #482120 80%); } .torrent-buttons a.hidden { opacity: 0.6!important; @@ -489,12 +499,17 @@ th { td { font-size: 0.9em; padding: 2px 0!important; - } -.results td { +.results td, .profile-content td { border-bottom: 1px solid #666666!important; border-top: 1px solid #666666!important; } +.torrent-view-data { + margin-left: 10px; +} +.torrent-view-data td { + padding: 1px 0!important; +} td a { color: #106655; } @@ -558,35 +573,39 @@ td.tr-size { .container.bottom { padding: 5px 10px; padding-top: 0; - margin-top: -8px; + margin-top: -11px; } .container.bottom .pagination { border-top: none; - padding: 0; + padding: 0 14px; } .container.bottom .pagination p { - margin: 4px 0 6px 0px; + margin: 2px 0 4px 0px } .bottom.center { width: 87%; max-width: 1328px; padding: 0 8px; -} +} .content > .centered { - padding: 0; - margin: 0; + padding: 0; + margin: 0; } #content > .centered { - width: 87%; + width: 87%; max-width: 1328px; padding: 0 8px; } .pagination .active, .pagination .active:hover { - background: #fbfbfb; - font-weight: bold; + background: none!important; + font-weight: bold!important; border: none; color: #106655; + cursor: text; +} +.sukebei .pagination .active, .pagination .active:hover { + color: #111111!important; } a.nav-btn.log-in { @@ -713,3 +732,49 @@ span.tag { .torrent-info-data #subscribe-link::before, .torrent-info-data #subscribe-link:: after { color: #111111; } +.content > p:first-child+div.centered+div.refine+div #reportPopup { + top: 145px; +} +.content > p:first-child+div#announce+div.refine+div #reportPopup { + top: 110px; +} +.content > div#announce:first-child+div.refine+div #reportPopup { + top: 65px; +} +#reportPopup { + text-decoration: underline dotted; + height: 16px!important; + font-size: 13px!important; + background: none; + color: #106655!important; + position: absolute; + top: 103px; + right: 11px; +} +.comment-content :first-child { +margin-top: 5px; +} +.sukebei #reportPopup { + color: #660000!important; +} +#reportPopup:hover { + text-decoration: underline; +} +.modal-header { + background: linear-gradient(to bottom, #33ca98 0%, #337372 72%); +} +.sukebei .modal-header { + background: linear-gradient(to bottom, #c54f6a 5%, #482120 80%); +} +.modal-footer{ + background: #26332e; +} +.sukebei .modal-footer { + background: #332626; +} +.user-search-notice { + margin: 9px 0 0 3px; + font-size: 13px; + font-weight: bold; + +} diff --git a/public/css/themes/tomorrow.css b/public/css/themes/tomorrow.css index ff5bbaa9..d9bd6513 100644 --- a/public/css/themes/tomorrow.css +++ b/public/css/themes/tomorrow.css @@ -62,6 +62,7 @@ a:hover { } .user-avatar span { background-color: #d02727; + color: #272727; } .header .h-user .user-menu { @@ -102,6 +103,9 @@ td.tr-le, .error-text { .sukebei .btn-red { color: #c5c8c6; } +.btn-grey { + background-color: #777777; +} .alt-colors tr:nth-child(even) { background: hsla(244, 11%, 21%, 0.2); @@ -348,5 +352,13 @@ span.tag { } #subscribe-link::before, #subscribe-link::after { - color: #c5c8c6; + color: #c5c8c6!important; +} + +td.notification-status { + background-color: #505255; +} +td.notification-status.notification-unread { + background-color: rgba(144, 103, 24, 0.4); + color: #c5c8c6; } diff --git a/public/img/avatar_130.jpg b/public/img/avatar_130.jpg new file mode 100644 index 00000000..a38d28a6 Binary files /dev/null and b/public/img/avatar_130.jpg differ diff --git a/public/img/avatar_50.jpg b/public/img/avatar_50.jpg new file mode 100644 index 00000000..19ab4619 Binary files /dev/null and b/public/img/avatar_50.jpg differ diff --git a/public/img/sukebei_avatar_130.jpg b/public/img/sukebei_avatar_130.jpg new file mode 100644 index 00000000..d5c54dc1 Binary files /dev/null and b/public/img/sukebei_avatar_130.jpg differ diff --git a/public/img/sukebei_avatar_50.jpg b/public/img/sukebei_avatar_50.jpg new file mode 100644 index 00000000..991a97dd Binary files /dev/null and b/public/img/sukebei_avatar_50.jpg differ diff --git a/public/js/main.js b/public/js/main.js index f7248549..eb41498d 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -219,7 +219,7 @@ function toggleTheme(e) { document.getElementById("theme").href = "/css/themes/" + CurrentTheme + ".css"; if(UserID > 0 ){ - Query.Get("/dark", function(data) {}) + Query.Get("/dark?no_redirect", function(data) {}) //If user logged in, we're forced to go through this page in order to save the new user theme } else { diff --git a/templates/admin/announcement_form.jet.html b/templates/admin/announcement_form.jet.html index 92c6b684..5ce2bbe3 100644 --- a/templates/admin/announcement_form.jet.html +++ b/templates/admin/announcement_form.jet.html @@ -11,11 +11,11 @@ {{ yield errors(name="Message")}}
- - - {{ yield errors(name="Delay")}} + + + {{ yield errors(name="Duration")}}
-{{end}} \ No newline at end of file +{{end}} diff --git a/templates/admin/index.jet.html b/templates/admin/index.jet.html index a6cb3505..00cde9b2 100644 --- a/templates/admin/index.jet.html +++ b/templates/admin/index.jet.html @@ -25,7 +25,7 @@
- +
@@ -33,19 +33,19 @@

{{ T("last_reports") }}

- +
+ @@ -58,6 +58,7 @@ +
{{ T("name") }} {{ T("username") }} {{ T("reason") }}{{ T("message") }} {{ T("actions") }}
{{.User.Username}} {{ getReportDescription(.Description,T) }}{{.Message}}
@@ -69,9 +70,7 @@

{{ T("last_users") }}

@@ -91,7 +90,7 @@ {{if .ID > 0}} {{ yield csrf_field()}} - + {{end}} @@ -100,8 +99,7 @@
@@ -136,8 +134,7 @@ diff --git a/templates/admin/torrent_report.jet.html b/templates/admin/torrent_report.jet.html index 443cc2f5..7ac557cb 100644 --- a/templates/admin/torrent_report.jet.html +++ b/templates/admin/torrent_report.jet.html @@ -3,12 +3,13 @@ {{ block content_body()}}

{{ T("reports_list") }}

- +
+ @@ -21,10 +22,11 @@ +
{{ T("name") }} {{ T("username") }} {{ T("reason") }}{{ T("message") }} {{ T("actions") }}
{{.User.Username}} {{ getReportDescription(.Description, T) }}{{.Message}}
- +
@@ -35,5 +37,9 @@ {{end}}
+
+ + +
{{end}} diff --git a/templates/admin/torrentlist.jet.html b/templates/admin/torrentlist.jet.html index 41ae3c76..8689887b 100644 --- a/templates/admin/torrentlist.jet.html +++ b/templates/admin/torrentlist.jet.html @@ -54,18 +54,15 @@ {{ .Uploader.Username }} {{ else }}れんちょん{{end}} - - - {{ if .IsBlocked }} - {{ T("torrent_unblock") }} - {{else}} - {{ T("torrent_block") }} - {{end}} - +
+
+ + +
{{ if .IsDeleted }}{{ end }} - +
diff --git a/templates/admin/userlist.jet.html b/templates/admin/userlist.jet.html index 3ec9261d..a7600796 100644 --- a/templates/admin/userlist.jet.html +++ b/templates/admin/userlist.jet.html @@ -21,7 +21,7 @@ {{if .ID > 0}}
{{ yield csrf_field()}} - +
{{end}} diff --git a/templates/layouts/partials/base.jet.html b/templates/layouts/partials/base.jet.html index 947165e7..f9ca65d8 100644 --- a/templates/layouts/partials/base.jet.html +++ b/templates/layouts/partials/base.jet.html @@ -45,7 +45,7 @@ {{block menu()}}{{end}}
- {{ AdType := kilo_rand(2) }} + {{ AdType := rand(2) }}
{{ yield infos()}} diff --git a/templates/layouts/partials/helpers/ad.jet.html b/templates/layouts/partials/helpers/ad.jet.html index 42923d92..4e7b3147 100644 --- a/templates/layouts/partials/helpers/ad.jet.html +++ b/templates/layouts/partials/helpers/ad.jet.html @@ -1,5 +1,5 @@ {{block ad_wide(Type=0)}} -{{ if !kilo_strcmp(URL.String(), "/mod", 4, 1) }} +{{ if !strcmp(URL.String(), "/mod", 4, 1) }} {{if Type == 0}} {{ aAdsId := Sukebei() ? 634159 : 634157 }} diff --git a/templates/layouts/partials/helpers/badgemenu.jet.html b/templates/layouts/partials/helpers/badgemenu.jet.html index e81c6f36..0798cbf6 100644 --- a/templates/layouts/partials/helpers/badgemenu.jet.html +++ b/templates/layouts/partials/helpers/badgemenu.jet.html @@ -5,6 +5,7 @@
- {{if User.ID > 0 }} - {{if !User.CurrentUserIdentical(UserProfile.ID) }} - {{if !User.IsFollower(UserProfile.ID)}} - {{ T("follow")}} - {{else}} - {{ T("unfollow")}} - {{end}} - {{end}} + {{if UserProfile.ID > 0 && !User.CurrentUserIdentical(UserProfile.ID) }} + {{if User.ID > 0 }} + {{if !User.IsFollower(UserProfile.ID)}} + {{ T("follow")}} + {{else}} + {{ T("unfollow")}} + {{end}} + {{else}} + {{T("follow")}} + {{end}} {{end}} {{ if User.ID > 0 && (User.CurrentUserIdentical(UserProfile.ID) || User.CurrentOrAdmin(UserProfile.ID)) }} diff --git a/templates/site/torrents/listing.jet.html b/templates/site/torrents/listing.jet.html index 42f9fb0f..32458901 100644 --- a/templates/site/torrents/listing.jet.html +++ b/templates/site/torrents/listing.jet.html @@ -1,6 +1,6 @@ {{ extends "layouts/index_site" }} {{ import "layouts/partials/helpers/search" }} -{{block title()}}{{ T("home")}}{{end}} +{{block title()}}{{if Search.UserName == ""}}{{ T("home")}}{{else}}{{Search.UserName}}{{end}}{{end}} {{block contclass()}}{{if User.HasAdmin() }}content-admin{{end}}{{end}} {{block content_body()}} {{ if OldNav || Theme == "classic"}} @@ -91,7 +91,7 @@ - {{ fileSize(.Filesize, T) }} + {{ fileSize(.Filesize, T, true) }} {{if .StatsObsolete[0] }} - diff --git a/templates/site/torrents/upload.jet.html b/templates/site/torrents/upload.jet.html index 9607c8cb..22679067 100644 --- a/templates/site/torrents/upload.jet.html +++ b/templates/site/torrents/upload.jet.html @@ -50,10 +50,10 @@
- +
- +
diff --git a/templates/site/torrents/view.jet.html b/templates/site/torrents/view.jet.html index 74c33f48..72beeb25 100644 --- a/templates/site/torrents/view.jet.html +++ b/templates/site/torrents/view.jet.html @@ -8,7 +8,7 @@ {{block title()}}{{Torrent.Name}}{{end}} {{block content_body()}}
-
+

{{Torrent.Name}}


@@ -28,8 +28,14 @@ {{else}} {{ genUploaderLink(Torrent.UploaderID, Torrent.UploaderName, Torrent.Hidden)|raw }} - {{if !Torrent.Hidden && Torrent.UploaderID != User.ID && User.ID > 0}}{{if User.IsFollower(Torrent.UploaderID)}}{{T("unfollow")}}{{else}}{{T("follow")}}{{end}}{{end}} - + {{if !Torrent.Hidden && Torrent.UploaderID != User.ID && Torrent.UploaderID != 0}} + {{if User.ID > 0}} + {{if User.IsFollower(Torrent.UploaderID)}}{{T("unfollow")}}{{else}}{{T("follow")}}{{end}} + {{else}} + {{T("follow")}} + {{end}} + {{end}} + {{end}} @@ -46,7 +52,7 @@ {{ T("size")}}: - {{ fileSize(Torrent.Filesize, T) }} + {{ fileSize(Torrent.Filesize, T, true) }} {{ if len(Torrent.Languages) > 0 && Torrent.Languages[0] != "" }} @@ -155,8 +161,8 @@
{{ T("torrent_file")}}
- {{ if User.ID > 0}} {{ T("report_btn") }} + {{ if User.ID > 0}} {{ if User.HasAdmin()}}
{{ yield csrf_field()}} @@ -211,11 +217,12 @@
{{idx}} - {{formatDate(element.Date, false)}} + {{formatDate(element.Date, false)}} -

+ {{if element.UserID > 0}}{{element.Username}}{{if element.UserStatus != ""}}{{T(element.UserStatus)}}{{end}}{{else}} - れんちょん{{end}} + れんちょん{{end}} +

{{element.Content|raw}}
{{idx = idx + 1}} @@ -233,6 +240,7 @@

{{ if User.ID > 0}} {{ T("submit_a_comment_as_username", User.Username) }} {{else}} {{ T("submit_a_comment_as_anonymous")|raw}} {{end}}

+

{{T("comment_markdown_notice")}}

{{ yield captcha(captchaid=CaptchaID)}} @@ -243,7 +251,6 @@
-{{ if User.ID > 0 }}
+{{ if User.ID > 0 }}