mirror of
https://github.com/miniflux/v2.git
synced 2025-09-15 18:57:04 +00:00
Make reading speed user-configurable
This commit is contained in:
parent
3a0aaddafd
commit
6e50ce3293
31 changed files with 395 additions and 173 deletions
|
@ -34,6 +34,14 @@ func (h *handler) fetchContent(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
user, err := h.store.UserByID(entry.UserID)
|
||||
if err != nil {
|
||||
json.ServerError(w, r, err)
|
||||
}
|
||||
if user == nil {
|
||||
json.NotFound(w, r)
|
||||
}
|
||||
|
||||
feedBuilder := storage.NewFeedQueryBuilder(h.store, loggedUserID)
|
||||
feedBuilder.WithFeedID(entry.FeedID)
|
||||
feed, err := feedBuilder.GetFeed()
|
||||
|
@ -47,12 +55,14 @@ func (h *handler) fetchContent(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if err := processor.ProcessEntryWebPage(feed, entry); err != nil {
|
||||
if err := processor.ProcessEntryWebPage(feed, entry, user); err != nil {
|
||||
json.ServerError(w, r, err)
|
||||
return
|
||||
}
|
||||
|
||||
h.store.UpdateEntryContent(entry)
|
||||
if err := h.store.UpdateEntryContent(entry); err != nil {
|
||||
json.ServerError(w, r, err)
|
||||
}
|
||||
|
||||
json.OK(w, r, map[string]string{"content": proxy.ImageProxyRewriter(h.router, entry.Content)})
|
||||
}
|
||||
|
|
|
@ -14,20 +14,22 @@ import (
|
|||
|
||||
// SettingsForm represents the settings form.
|
||||
type SettingsForm struct {
|
||||
Username string
|
||||
Password string
|
||||
Confirmation string
|
||||
Theme string
|
||||
Language string
|
||||
Timezone string
|
||||
EntryDirection string
|
||||
EntryOrder string
|
||||
EntriesPerPage int
|
||||
KeyboardShortcuts bool
|
||||
ShowReadingTime bool
|
||||
CustomCSS string
|
||||
EntrySwipe bool
|
||||
DisplayMode string
|
||||
Username string
|
||||
Password string
|
||||
Confirmation string
|
||||
Theme string
|
||||
Language string
|
||||
Timezone string
|
||||
EntryDirection string
|
||||
EntryOrder string
|
||||
EntriesPerPage int
|
||||
KeyboardShortcuts bool
|
||||
ShowReadingTime bool
|
||||
CustomCSS string
|
||||
EntrySwipe bool
|
||||
DisplayMode string
|
||||
DefaultReadingSpeed int
|
||||
CJKReadingSpeed int
|
||||
}
|
||||
|
||||
// Merge updates the fields of the given user.
|
||||
|
@ -44,6 +46,8 @@ func (s *SettingsForm) Merge(user *model.User) *model.User {
|
|||
user.Stylesheet = s.CustomCSS
|
||||
user.EntrySwipe = s.EntrySwipe
|
||||
user.DisplayMode = s.DisplayMode
|
||||
user.CJKReadingSpeed = s.CJKReadingSpeed
|
||||
user.DefaultReadingSpeed = s.DefaultReadingSpeed
|
||||
|
||||
if s.Password != "" {
|
||||
user.Password = s.Password
|
||||
|
@ -58,6 +62,10 @@ func (s *SettingsForm) Validate() error {
|
|||
return errors.NewLocalizedError("error.settings_mandatory_fields")
|
||||
}
|
||||
|
||||
if s.CJKReadingSpeed <= 0 || s.DefaultReadingSpeed <= 0 {
|
||||
return errors.NewLocalizedError("error.settings_reading_speed_is_positive")
|
||||
}
|
||||
|
||||
if s.Confirmation == "" {
|
||||
// Firefox insists on auto-completing the password field.
|
||||
// If the confirmation field is blank, the user probably
|
||||
|
@ -78,20 +86,30 @@ func NewSettingsForm(r *http.Request) *SettingsForm {
|
|||
if err != nil {
|
||||
entriesPerPage = 0
|
||||
}
|
||||
defaultReadingSpeed, err := strconv.ParseInt(r.FormValue("default_reading_speed"), 10, 0)
|
||||
if err != nil {
|
||||
defaultReadingSpeed = 0
|
||||
}
|
||||
cjkReadingSpeed, err := strconv.ParseInt(r.FormValue("cjk_reading_speed"), 10, 0)
|
||||
if err != nil {
|
||||
cjkReadingSpeed = 0
|
||||
}
|
||||
return &SettingsForm{
|
||||
Username: r.FormValue("username"),
|
||||
Password: r.FormValue("password"),
|
||||
Confirmation: r.FormValue("confirmation"),
|
||||
Theme: r.FormValue("theme"),
|
||||
Language: r.FormValue("language"),
|
||||
Timezone: r.FormValue("timezone"),
|
||||
EntryDirection: r.FormValue("entry_direction"),
|
||||
EntryOrder: r.FormValue("entry_order"),
|
||||
EntriesPerPage: int(entriesPerPage),
|
||||
KeyboardShortcuts: r.FormValue("keyboard_shortcuts") == "1",
|
||||
ShowReadingTime: r.FormValue("show_reading_time") == "1",
|
||||
CustomCSS: r.FormValue("custom_css"),
|
||||
EntrySwipe: r.FormValue("entry_swipe") == "1",
|
||||
DisplayMode: r.FormValue("display_mode"),
|
||||
Username: r.FormValue("username"),
|
||||
Password: r.FormValue("password"),
|
||||
Confirmation: r.FormValue("confirmation"),
|
||||
Theme: r.FormValue("theme"),
|
||||
Language: r.FormValue("language"),
|
||||
Timezone: r.FormValue("timezone"),
|
||||
EntryDirection: r.FormValue("entry_direction"),
|
||||
EntryOrder: r.FormValue("entry_order"),
|
||||
EntriesPerPage: int(entriesPerPage),
|
||||
KeyboardShortcuts: r.FormValue("keyboard_shortcuts") == "1",
|
||||
ShowReadingTime: r.FormValue("show_reading_time") == "1",
|
||||
CustomCSS: r.FormValue("custom_css"),
|
||||
EntrySwipe: r.FormValue("entry_swipe") == "1",
|
||||
DisplayMode: r.FormValue("display_mode"),
|
||||
DefaultReadingSpeed: int(defaultReadingSpeed),
|
||||
CJKReadingSpeed: int(cjkReadingSpeed),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,15 +6,17 @@ import (
|
|||
|
||||
func TestValid(t *testing.T) {
|
||||
settings := &SettingsForm{
|
||||
Username: "user",
|
||||
Password: "hunter2",
|
||||
Confirmation: "hunter2",
|
||||
Theme: "default",
|
||||
Language: "en_US",
|
||||
Timezone: "UTC",
|
||||
EntryDirection: "asc",
|
||||
EntriesPerPage: 50,
|
||||
DisplayMode: "standalone",
|
||||
Username: "user",
|
||||
Password: "hunter2",
|
||||
Confirmation: "hunter2",
|
||||
Theme: "default",
|
||||
Language: "en_US",
|
||||
Timezone: "UTC",
|
||||
EntryDirection: "asc",
|
||||
EntriesPerPage: 50,
|
||||
DisplayMode: "standalone",
|
||||
DefaultReadingSpeed: 35,
|
||||
CJKReadingSpeed: 25,
|
||||
}
|
||||
|
||||
err := settings.Validate()
|
||||
|
@ -25,15 +27,17 @@ func TestValid(t *testing.T) {
|
|||
|
||||
func TestConfirmationEmpty(t *testing.T) {
|
||||
settings := &SettingsForm{
|
||||
Username: "user",
|
||||
Password: "hunter2",
|
||||
Confirmation: "",
|
||||
Theme: "default",
|
||||
Language: "en_US",
|
||||
Timezone: "UTC",
|
||||
EntryDirection: "asc",
|
||||
EntriesPerPage: 50,
|
||||
DisplayMode: "standalone",
|
||||
Username: "user",
|
||||
Password: "hunter2",
|
||||
Confirmation: "",
|
||||
Theme: "default",
|
||||
Language: "en_US",
|
||||
Timezone: "UTC",
|
||||
EntryDirection: "asc",
|
||||
EntriesPerPage: 50,
|
||||
DisplayMode: "standalone",
|
||||
DefaultReadingSpeed: 35,
|
||||
CJKReadingSpeed: 25,
|
||||
}
|
||||
|
||||
err := settings.Validate()
|
||||
|
@ -48,15 +52,17 @@ func TestConfirmationEmpty(t *testing.T) {
|
|||
|
||||
func TestConfirmationIncorrect(t *testing.T) {
|
||||
settings := &SettingsForm{
|
||||
Username: "user",
|
||||
Password: "hunter2",
|
||||
Confirmation: "unter2",
|
||||
Theme: "default",
|
||||
Language: "en_US",
|
||||
Timezone: "UTC",
|
||||
EntryDirection: "asc",
|
||||
EntriesPerPage: 50,
|
||||
DisplayMode: "standalone",
|
||||
Username: "user",
|
||||
Password: "hunter2",
|
||||
Confirmation: "unter2",
|
||||
Theme: "default",
|
||||
Language: "en_US",
|
||||
Timezone: "UTC",
|
||||
EntryDirection: "asc",
|
||||
EntriesPerPage: 50,
|
||||
DisplayMode: "standalone",
|
||||
DefaultReadingSpeed: 35,
|
||||
CJKReadingSpeed: 25,
|
||||
}
|
||||
|
||||
err := settings.Validate()
|
||||
|
|
|
@ -27,18 +27,20 @@ func (h *handler) showSettingsPage(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
settingsForm := form.SettingsForm{
|
||||
Username: user.Username,
|
||||
Theme: user.Theme,
|
||||
Language: user.Language,
|
||||
Timezone: user.Timezone,
|
||||
EntryDirection: user.EntryDirection,
|
||||
EntryOrder: user.EntryOrder,
|
||||
EntriesPerPage: user.EntriesPerPage,
|
||||
KeyboardShortcuts: user.KeyboardShortcuts,
|
||||
ShowReadingTime: user.ShowReadingTime,
|
||||
CustomCSS: user.Stylesheet,
|
||||
EntrySwipe: user.EntrySwipe,
|
||||
DisplayMode: user.DisplayMode,
|
||||
Username: user.Username,
|
||||
Theme: user.Theme,
|
||||
Language: user.Language,
|
||||
Timezone: user.Timezone,
|
||||
EntryDirection: user.EntryDirection,
|
||||
EntryOrder: user.EntryOrder,
|
||||
EntriesPerPage: user.EntriesPerPage,
|
||||
KeyboardShortcuts: user.KeyboardShortcuts,
|
||||
ShowReadingTime: user.ShowReadingTime,
|
||||
CustomCSS: user.Stylesheet,
|
||||
EntrySwipe: user.EntrySwipe,
|
||||
DisplayMode: user.DisplayMode,
|
||||
DefaultReadingSpeed: user.DefaultReadingSpeed,
|
||||
CJKReadingSpeed: user.CJKReadingSpeed,
|
||||
}
|
||||
|
||||
timezones, err := h.store.Timezones()
|
||||
|
|
|
@ -53,14 +53,16 @@ func (h *handler) updateSettings(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
userModificationRequest := &model.UserModificationRequest{
|
||||
Username: model.OptionalString(settingsForm.Username),
|
||||
Password: model.OptionalString(settingsForm.Password),
|
||||
Theme: model.OptionalString(settingsForm.Theme),
|
||||
Language: model.OptionalString(settingsForm.Language),
|
||||
Timezone: model.OptionalString(settingsForm.Timezone),
|
||||
EntryDirection: model.OptionalString(settingsForm.EntryDirection),
|
||||
EntriesPerPage: model.OptionalInt(settingsForm.EntriesPerPage),
|
||||
DisplayMode: model.OptionalString(settingsForm.DisplayMode),
|
||||
Username: model.OptionalString(settingsForm.Username),
|
||||
Password: model.OptionalString(settingsForm.Password),
|
||||
Theme: model.OptionalString(settingsForm.Theme),
|
||||
Language: model.OptionalString(settingsForm.Language),
|
||||
Timezone: model.OptionalString(settingsForm.Timezone),
|
||||
EntryDirection: model.OptionalString(settingsForm.EntryDirection),
|
||||
EntriesPerPage: model.OptionalInt(settingsForm.EntriesPerPage),
|
||||
DisplayMode: model.OptionalString(settingsForm.DisplayMode),
|
||||
DefaultReadingSpeed: model.OptionalInt(settingsForm.DefaultReadingSpeed),
|
||||
CJKReadingSpeed: model.OptionalInt(settingsForm.CJKReadingSpeed),
|
||||
}
|
||||
|
||||
if validationErr := validator.ValidateUserModification(h.store, loggedUser.ID, userModificationRequest); validationErr != nil {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue