add: ability to enable pages instead of infinite scrolling
This commit is contained in:
parent
fa72d6a59d
commit
ffdf320c14
15 changed files with 47 additions and 15 deletions
|
@ -44,9 +44,10 @@
|
||||||
("ui_ident" "io_data_load")
|
("ui_ident" "io_data_load")
|
||||||
(div ("ui_ident" "io_data_marker"))))
|
(div ("ui_ident" "io_data_marker"))))
|
||||||
|
|
||||||
|
(text "{% set paged = user and user.settings.paged_timelines %}")
|
||||||
(script
|
(script
|
||||||
(text "setTimeout(() => {
|
(text "setTimeout(() => {
|
||||||
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?user_id={{ profile.id }}&tag={{ tag }}&page=\", Number.parseInt(\"{{ page }}\") - 1]);
|
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?user_id={{ profile.id }}&tag={{ tag }}&page=\", Number.parseInt(\"{{ page }}\") - 1, \"{{ paged }}\" === \"true\"]);
|
||||||
});"))
|
});"))
|
||||||
|
|
||||||
(text "{% endblock %}")
|
(text "{% endblock %}")
|
||||||
|
|
|
@ -1403,6 +1403,11 @@
|
||||||
\"Hides dislikes on all posts. Users will also no longer be able to dislike your posts.\",
|
\"Hides dislikes on all posts. Users will also no longer be able to dislike your posts.\",
|
||||||
\"text\",
|
\"text\",
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
[\"paged_timelines\", \"Make timelines paged instead of infinitely scrolled\"],
|
||||||
|
\"{{ profile.settings.paged_timelines }}\",
|
||||||
|
\"checkbox\",
|
||||||
|
],
|
||||||
[[], \"Fun\", \"title\"],
|
[[], \"Fun\", \"title\"],
|
||||||
[
|
[
|
||||||
[\"disable_gpa_fun\", \"Disable GPA\"],
|
[\"disable_gpa_fun\", \"Disable GPA\"],
|
||||||
|
|
|
@ -83,9 +83,10 @@
|
||||||
("ui_ident" "io_data_load")
|
("ui_ident" "io_data_load")
|
||||||
(div ("ui_ident" "io_data_marker")))
|
(div ("ui_ident" "io_data_marker")))
|
||||||
|
|
||||||
|
(text "{% set paged = user and user.settings.paged_timelines %}")
|
||||||
(script
|
(script
|
||||||
(text "setTimeout(() => {
|
(text "setTimeout(() => {
|
||||||
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?stack_id={{ stack.id }}&page=\", Number.parseInt(\"{{ page }}\") - 1]);
|
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?stack_id={{ stack.id }}&page=\", Number.parseInt(\"{{ page }}\") - 1, \"{{ paged }}\" === \"true\"]);
|
||||||
});"))
|
});"))
|
||||||
(text "{%- endif %}"))))
|
(text "{%- endif %}"))))
|
||||||
|
|
||||||
|
|
|
@ -33,9 +33,10 @@
|
||||||
("ui_ident" "io_data_load")
|
("ui_ident" "io_data_load")
|
||||||
(div ("ui_ident" "io_data_marker"))))
|
(div ("ui_ident" "io_data_marker"))))
|
||||||
|
|
||||||
|
(text "{% set paged = user and user.settings.paged_timelines %}")
|
||||||
(script
|
(script
|
||||||
(text "setTimeout(() => {
|
(text "setTimeout(() => {
|
||||||
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?tl=AllPosts&page=\", Number.parseInt(\"{{ page }}\") - 1]);
|
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?tl=AllPosts&page=\", Number.parseInt(\"{{ page }}\") - 1, \"{{ paged }}\" === \"true\"]);
|
||||||
});"))
|
});"))
|
||||||
|
|
||||||
(text "{% endblock %}")
|
(text "{% endblock %}")
|
||||||
|
|
|
@ -11,9 +11,10 @@
|
||||||
("ui_ident" "io_data_load")
|
("ui_ident" "io_data_load")
|
||||||
(div ("ui_ident" "io_data_marker"))))
|
(div ("ui_ident" "io_data_marker"))))
|
||||||
|
|
||||||
|
(text "{% set paged = user and user.settings.paged_timelines %}")
|
||||||
(script
|
(script
|
||||||
(text "setTimeout(() => {
|
(text "setTimeout(() => {
|
||||||
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?tl=FollowingPosts&page=\", Number.parseInt(\"{{ page }}\") - 1]);
|
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?tl=FollowingPosts&page=\", Number.parseInt(\"{{ page }}\") - 1, \"{{ paged }}\" === \"true\"]);
|
||||||
});"))
|
});"))
|
||||||
|
|
||||||
(text "{% endblock %}")
|
(text "{% endblock %}")
|
||||||
|
|
|
@ -31,9 +31,10 @@
|
||||||
(div ("ui_ident" "io_data_marker")))
|
(div ("ui_ident" "io_data_marker")))
|
||||||
(text "{%- endif %}"))
|
(text "{%- endif %}"))
|
||||||
|
|
||||||
|
(text "{% set paged = user and user.settings.paged_timelines %}")
|
||||||
(script
|
(script
|
||||||
(text "setTimeout(() => {
|
(text "setTimeout(() => {
|
||||||
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?tl=MyCommunities&page=\", Number.parseInt(\"{{ page }}\") - 1]);
|
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?tl=MyCommunities&page=\", Number.parseInt(\"{{ page }}\") - 1, \"{{ paged }}\" === \"true\"]);
|
||||||
});"))
|
});"))
|
||||||
|
|
||||||
(text "{% endblock %}")
|
(text "{% endblock %}")
|
||||||
|
|
|
@ -11,9 +11,10 @@
|
||||||
("ui_ident" "io_data_load")
|
("ui_ident" "io_data_load")
|
||||||
(div ("ui_ident" "io_data_marker"))))
|
(div ("ui_ident" "io_data_marker"))))
|
||||||
|
|
||||||
|
(text "{% set paged = user and user.settings.paged_timelines %}")
|
||||||
(script
|
(script
|
||||||
(text "setTimeout(() => {
|
(text "setTimeout(() => {
|
||||||
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?tl=PopularPosts&page=\", Number.parseInt(\"{{ page }}\") - 1]);
|
trigger(\"ui::io_data_load\", [\"/_swiss_army_timeline?tl=PopularPosts&page=\", Number.parseInt(\"{{ page }}\") - 1, \"{{ paged }}\" === \"true\"]);
|
||||||
});"))
|
});"))
|
||||||
|
|
||||||
(text "{% endblock %}")
|
(text "{% endblock %}")
|
||||||
|
|
|
@ -30,3 +30,7 @@
|
||||||
(str (text "chats:label.go_back")))
|
(str (text "chats:label.go_back")))
|
||||||
(text "{%- endif %}"))
|
(text "{%- endif %}"))
|
||||||
(text "{%- endif %}")
|
(text "{%- endif %}")
|
||||||
|
|
||||||
|
(text "{% if paginated -%}")
|
||||||
|
(text "{{ components::pagination(page=page, items=list|length) }}")
|
||||||
|
(text "{%- endif %}")
|
||||||
|
|
|
@ -1141,7 +1141,7 @@ ${option.input_element_type === "textarea" ? `${option.value}</textarea>` : ""}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
self.define("io_data_load", (_, tmpl, page) => {
|
self.define("io_data_load", (_, tmpl, page, paginated_mode = false) => {
|
||||||
self.IO_DATA_MARKER = document.querySelector(
|
self.IO_DATA_MARKER = document.querySelector(
|
||||||
"[ui_ident=io_data_marker]",
|
"[ui_ident=io_data_marker]",
|
||||||
);
|
);
|
||||||
|
@ -1164,7 +1164,16 @@ ${option.input_element_type === "textarea" ? `${option.value}</textarea>` : ""}
|
||||||
self.IO_DATA_PAGE = page;
|
self.IO_DATA_PAGE = page;
|
||||||
self.IO_DATA_SEEN_IDS = [];
|
self.IO_DATA_SEEN_IDS = [];
|
||||||
|
|
||||||
self.IO_DATA_OBSERVER.observe(self.IO_DATA_MARKER);
|
if (!paginated_mode) {
|
||||||
|
self.IO_DATA_OBSERVER.observe(self.IO_DATA_MARKER);
|
||||||
|
} else {
|
||||||
|
// immediately load first page
|
||||||
|
self.IO_DATA_TMPL = self.IO_DATA_TMPL.replace("&page=", "");
|
||||||
|
self.IO_DATA_TMPL += `&paginated=true&page=`;
|
||||||
|
self.io_load_data();
|
||||||
|
}
|
||||||
|
|
||||||
|
self.IO_PAGINATED = paginated_mode;
|
||||||
});
|
});
|
||||||
|
|
||||||
self.define("io_load_data", async () => {
|
self.define("io_load_data", async () => {
|
||||||
|
|
|
@ -213,7 +213,7 @@ pub async fn upload_avatar_request(
|
||||||
if mime == "image/gif" {
|
if mime == "image/gif" {
|
||||||
// gif image, don't encode
|
// gif image, don't encode
|
||||||
if img.0.len() > MAXIMUM_GIF_FILE_SIZE {
|
if img.0.len() > MAXIMUM_GIF_FILE_SIZE {
|
||||||
return Json(Error::DataTooLong("gif".to_string()).into());
|
return Json(Error::FileTooLarge.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::fs::write(&path, img.0).unwrap();
|
std::fs::write(&path, img.0).unwrap();
|
||||||
|
@ -226,7 +226,7 @@ pub async fn upload_avatar_request(
|
||||||
|
|
||||||
// check file size
|
// check file size
|
||||||
if img.0.len() > MAXIMUM_FILE_SIZE {
|
if img.0.len() > MAXIMUM_FILE_SIZE {
|
||||||
return Json(Error::DataTooLong("image".to_string()).into());
|
return Json(Error::FileTooLarge.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// upload image
|
// upload image
|
||||||
|
@ -314,7 +314,7 @@ pub async fn upload_banner_request(
|
||||||
if mime == "image/gif" {
|
if mime == "image/gif" {
|
||||||
// gif image, don't encode
|
// gif image, don't encode
|
||||||
if img.0.len() > MAXIMUM_GIF_FILE_SIZE {
|
if img.0.len() > MAXIMUM_GIF_FILE_SIZE {
|
||||||
return Json(Error::DataTooLong("gif".to_string()).into());
|
return Json(Error::FileTooLarge.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::fs::write(&path, img.0).unwrap();
|
std::fs::write(&path, img.0).unwrap();
|
||||||
|
@ -327,7 +327,7 @@ pub async fn upload_banner_request(
|
||||||
|
|
||||||
// check file size
|
// check file size
|
||||||
if img.0.len() > MAXIMUM_FILE_SIZE {
|
if img.0.len() > MAXIMUM_FILE_SIZE {
|
||||||
return Json(Error::DataTooLong("image".to_string()).into());
|
return Json(Error::FileTooLarge.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// upload image
|
// upload image
|
||||||
|
|
|
@ -136,7 +136,7 @@ pub async fn upload_avatar_request(
|
||||||
|
|
||||||
// check file size
|
// check file size
|
||||||
if img.0.len() > MAXIMUM_FILE_SIZE {
|
if img.0.len() > MAXIMUM_FILE_SIZE {
|
||||||
return Json(Error::DataTooLong("image".to_string()).into());
|
return Json(Error::FileTooLarge.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// upload image
|
// upload image
|
||||||
|
@ -191,7 +191,7 @@ pub async fn upload_banner_request(
|
||||||
|
|
||||||
// check file size
|
// check file size
|
||||||
if img.0.len() > MAXIMUM_FILE_SIZE {
|
if img.0.len() > MAXIMUM_FILE_SIZE {
|
||||||
return Json(Error::DataTooLong("image".to_string()).into());
|
return Json(Error::FileTooLarge.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// upload image
|
// upload image
|
||||||
|
|
|
@ -133,7 +133,7 @@ pub async fn create_request(
|
||||||
// check sizes
|
// check sizes
|
||||||
for img in &images {
|
for img in &images {
|
||||||
if img.len() > MAXIMUM_FILE_SIZE {
|
if img.len() > MAXIMUM_FILE_SIZE {
|
||||||
return Json(Error::DataTooLong("image".to_string()).into());
|
return Json(Error::FileTooLarge.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -576,6 +576,8 @@ pub struct TimelineQuery {
|
||||||
pub user_id: usize,
|
pub user_id: usize,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub tag: String,
|
pub tag: String,
|
||||||
|
#[serde(default)]
|
||||||
|
pub paginated: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `/_swiss_army_timeline`
|
/// `/_swiss_army_timeline`
|
||||||
|
@ -697,6 +699,7 @@ pub async fn swiss_army_timeline_request(
|
||||||
|
|
||||||
context.insert("list", &list);
|
context.insert("list", &list);
|
||||||
context.insert("page", &req.page);
|
context.insert("page", &req.page);
|
||||||
|
context.insert("paginated", &req.paginated);
|
||||||
Ok(Html(
|
Ok(Html(
|
||||||
data.1
|
data.1
|
||||||
.render("timelines/swiss_army.html", &context)
|
.render("timelines/swiss_army.html", &context)
|
||||||
|
|
|
@ -231,6 +231,9 @@ pub struct UserSettings {
|
||||||
/// A list of strings the user has muted.
|
/// A list of strings the user has muted.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub muted: Vec<String>,
|
pub muted: Vec<String>,
|
||||||
|
/// If timelines are paged instead of infinitely scrolled.
|
||||||
|
#[serde(default)]
|
||||||
|
pub paged_timelines: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mime_avif() -> String {
|
fn mime_avif() -> String {
|
||||||
|
|
|
@ -41,6 +41,7 @@ pub enum Error {
|
||||||
AlreadyAuthenticated,
|
AlreadyAuthenticated,
|
||||||
DataTooLong(String),
|
DataTooLong(String),
|
||||||
DataTooShort(String),
|
DataTooShort(String),
|
||||||
|
FileTooLarge,
|
||||||
UsernameInUse,
|
UsernameInUse,
|
||||||
TitleInUse,
|
TitleInUse,
|
||||||
QuestionsDisabled,
|
QuestionsDisabled,
|
||||||
|
@ -62,6 +63,7 @@ impl Display for Error {
|
||||||
Self::AlreadyAuthenticated => "Already authenticated".to_string(),
|
Self::AlreadyAuthenticated => "Already authenticated".to_string(),
|
||||||
Self::DataTooLong(name) => format!("Given {name} is too long!"),
|
Self::DataTooLong(name) => format!("Given {name} is too long!"),
|
||||||
Self::DataTooShort(name) => format!("Given {name} is too short!"),
|
Self::DataTooShort(name) => format!("Given {name} is too short!"),
|
||||||
|
Self::FileTooLarge => "Given file is too large".to_string(),
|
||||||
Self::UsernameInUse => "Username in use".to_string(),
|
Self::UsernameInUse => "Username in use".to_string(),
|
||||||
Self::TitleInUse => "Title in use".to_string(),
|
Self::TitleInUse => "Title in use".to_string(),
|
||||||
Self::QuestionsDisabled => "You are not allowed to ask questions there".to_string(),
|
Self::QuestionsDisabled => "You are not allowed to ask questions there".to_string(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue