extensions.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. !function () {
  2. const ENGLISH_DISPLAY_NAMES = new Intl.DisplayNames(["en"], { type: "language" });
  3. function simpleLanguageName(language) {
  4. return language === "all" ? "All" : ENGLISH_DISPLAY_NAMES.of(language);
  5. }
  6. function languageName(language) {
  7. if (language === "all") {
  8. return "All";
  9. }
  10. if (language === "en") {
  11. return "English"
  12. }
  13. const localDisplayNames = new Intl.DisplayNames([language], { type: "language" });
  14. return `${ENGLISH_DISPLAY_NAMES.of(language)} - ${localDisplayNames.of(language)}`;
  15. }
  16. const LoadingStatus = {
  17. Loading: "loading",
  18. Loaded: "loaded",
  19. Error: "error",
  20. }
  21. const NsfwOption = {
  22. All: "all",
  23. Safe: "safe",
  24. Nsfw: "nsfw",
  25. }
  26. document.addEventListener("alpine:init", () => {
  27. Alpine.store("repoUrl", "https://raw.githubusercontent.com/keiyoushi/extensions/repo");
  28. Alpine.data("extensionList", () => ({
  29. LoadingStatus,
  30. NsfwOption,
  31. simpleLanguageName,
  32. languageName,
  33. extensions: [],
  34. languages: [],
  35. loading: LoadingStatus.Loading,
  36. filtered: [],
  37. query: "",
  38. selectedLanguages: [],
  39. nsfw: NsfwOption.All,
  40. async init() {
  41. try {
  42. const index = await fetch(`${Alpine.store("repoUrl")}/index.min.json`).then((e) => e.json());
  43. this.extensions = index.sort((a, b) => {
  44. if ("all" === a.lang && "all" !== b.lang) {
  45. return -1;
  46. }
  47. if ("all" !== a.lang && "all" === b.lang) {
  48. return 1;
  49. }
  50. if ("en" === a.lang && "en" !== b.lang) {
  51. return -1
  52. }
  53. if ("en" === b.lang && "en" !== a.lang) {
  54. return 1;
  55. }
  56. const langA = simpleLanguageName(a.lang);
  57. const langB = simpleLanguageName(b.lang);
  58. return langA.localeCompare(langB) || a.name.localeCompare(b.name);
  59. });
  60. this.languages = [...new Set(this.extensions.map((e) => e.lang))];
  61. this.loading = LoadingStatus.Loaded;
  62. } catch (e) {
  63. console.error(e);
  64. this.loading = LoadingStatus.Error;
  65. }
  66. if (this.filtered.length === 0) {
  67. this.updateFilteredList();
  68. }
  69. this.$nextTick(() => {
  70. window.location.hash && window.location.replace(window.location.hash);
  71. });
  72. },
  73. updateFilteredList() {
  74. this.filtered = this.extensions
  75. .filter(
  76. (e) => !this.query
  77. || e.name.toLowerCase().includes(this.query.toLowerCase())
  78. || e.pkg.toLowerCase().includes(this.query.toLowerCase()),
  79. )
  80. .filter(
  81. (e) => this.nsfw === NsfwOption.All
  82. || (this.nsfw === NsfwOption.Nsfw ? e.nsfw : !e.nsfw),
  83. )
  84. .filter(
  85. (e) =>
  86. !this.selectedLanguages.length || this.selectedLanguages.includes(e.lang)
  87. );
  88. },
  89. }))
  90. });
  91. }()