Bước tới nội dung

Thành viên:Plantaest/Zinnia/Prototype 1 & 2

Bách khoa toàn thư mở Wikipedia
Zinnia elegans

Zinnia là tên của một dự án phần mềm đang được phát triển bởi thành viên Plantaest và cộng đồng. Mục tiêu của Zinnia là một phiên bản tốt hơn cho Thay đổi gần đây và Twinkle.

Đăng ký nhận báo cáo[sửa | sửa mã nguồn]

Khoảng 1–4 tuần, nếu có các báo cáo quan trọng thì mọi người có thể đăng ký nhận tin (thông báo qua ping), bằng cách ký vào danh sách bên dưới. Các báo cáo sẽ đăng trên trang thảo luận của dự án. Mọi ý kiến góp ý trong quá trình phát triển phần mềm đều được ghi nhận một cách trân trọng.

  1. Dang (thảo luận) 20:17, ngày 21 tháng 3 năm 2023 (UTC)
  2. Lại là Cookie nè hay là Cúc Ki ta? {{{(>_<)}}} 11:35, ngày 22 tháng 3 năm 2023 (UTC)
  3. Tryvix1509 (thảo luận | đóng góp | trung ương | meta) 13:41, ngày 22 tháng 3 năm 2023 (UTC)
  4. Phjtieudoc (thảo luận) 11:24, ngày 5 tháng 1 năm 2024 (UTC)
  5. Miyako FujimiyaΣυζητώ 05:50, ngày 1 tháng 5 năm 2024 (UTC)

Lịch sử[sửa | sửa mã nguồn]

Bối cảnh[sửa | sửa mã nguồn]

Việc thực hiện các chức năng quản lý wiki đã và đang được triển khai thông qua một số công cụ kinh điển như RecentChanges (Thay đổi gần đây), RTRC, Navigation popups, Twinkle, Huggle, hay một số công cụ mới hơn như RedWarn/Ultraviolet, SWViewer, AntiVandal. Ngoài ra, còn có sự hỗ trợ từ rất nhiều các user script, những tập lệnh được cộng đồng phát triển theo nhu cầu cá nhân hoặc nhu cầu tập thể, có thể khá đơn giản và chỉ thực hiện một trách nhiệm duy nhất như BlankedThePage.

Nhìn chung, hệ thống những công cụ lớn được đề cập ở trên, cùng với các user script, đã có thể giúp quản lý wiki tương đối ổn định; các thao tác như duyệt sửa đổi, lùi sửa, thêm bản mẫu đều khá dễ dàng thực hiện. Tuy nhiên, nếu xét riêng từng trường hợp thì mỗi công cụ đều có những hạn chế riêng của nó:

  • RecentChanges là nơi đầu tiên mà các thành viên wiki tiếp xúc với một nhật trình quan trọng bậc nhất của hệ thống. Công cụ này tuy đã được cải tiến trong một thời gian dài (như việc thêm các bộ lọc sửa đổi), nhưng đến hiện tại thì giao diện vẫn giữ nguyên cấu trúc từ rất nhiều năm trước, khá rườm rà và dày đặc thông tin. Bản chất RecentChanges là một nhật trình (log), nên giao diện như vậy thực ra lại phù hợp để thể hiện thông tin một cách đầy đủ và phù hợp để truy xuất dữ liệu, nhưng nó sẽ không tiện dụng để thực hiện các tác vụ quản lý, hiệu suất xử lý công việc sẽ bị giảm khi tập trung quá lâu vào một màn hình có quá nhiều dữ liệu. Cộng đồng cũng có một số nỗ lực để cải thiện RecentChanges, như việc đề xuất thêm các nút "inline diff" và "inline patrol" để thuận tiện cho quá trình tuần tra.
  • RTRC có thể coi là một phiên bản RecentChanges đơn giản hơn, với các thông tin được sắp xếp gọn gàng, cùng với một panel để thực hiện các chức năng lọc nhật trình theo nhu cầu. Cơ bản RTRC thực hiện tốt những chức năng mà nó cung cấp, nhưng cũng có một số nhược điểm như diff panel có thể khá hẹp, khiến khó theo dõi những diff dài; bộ chọn timeframe không tiện dụng do phải nhập tay thông tin thời gian theo một pattern được quy định sẵn.
  • Navigation popups là một công cụ khá tiện dụng để xem trước các nội dung mà không cần mở một trang mới. Nhược điểm của nó có thể là giao diện không quá trau chuốt, và diff dạng inline được sử dụng trong công cụ này có thể khó nhìn hơn so với diff dạng split thường thấy khi duyệt wiki, nhất là những diff dài, nhưng đa phần diff thường ngắn nên có lẽ không có vấn đề gì quá lớn.
  • Twinkle là công cụ quản lý wiki kinh điển, nó được ví như dao Thụy Sĩ, vì có khá nhiều công cụ nhỏ tiện dụng. Về mặt chức năng thì Twinkle cơ bản đáp ứng tốt, nhất là đối với những wiki có quy trình xử lý công việc tương tự enwiki. Nhưng vấn đề lớn nhất của Twinkle là hai việc i18n (internationalization, quốc tế hóa) và l10n (localization, bản địa hóa), nói đơn giản là các label của Twinkle không được tách riêng khỏi mã nguồn để thuận tiện cho việc chuyển ngữ, cũng như những chức năng của nó đôi khi quá đặc thù cho enwiki, khiến khó "bản địa hóa" cho các wiki khác. Một nỗ lực để giải quyết hai vấn đề i18n và l10n cho Twinkle là dự án twinkle-core. Ngoài ra, giao diện của Twinkle được nhận xét là lỗi thời và hiện tại công cụ cũng không hỗ trợ sử dụng trên skin Minerva (môi trường di động), trừ khi sử dụng một patch như TwinkleMobile.
  • Huggle là một công cụ có thể coi như là sự kết hợp giữa RecentChanges và Twinkle. Nhìn chung, Huggle hoạt động đáng tin cậy, nhưng điểm yếu có thể là giao diện chưa quá tốt, và phải cài đặt để sử dụng (có thể là nhược điểm lớn nhất).
  • RedWarn/Ultraviolet là một công cụ quản lý wiki tương tự Twinkle được phát triển gần đây. Giao diện tuy đã được cải thiện so với Twinkle nhờ sử dụng Material UI, nhưng cách triển khai giao diện thực ra chưa quá tốt, dễ nhận thấy một số điểm bất hợp lý, như việc để các modal chồng lên nhau có thể coi là một anti-pattern, và một số chỗ chưa được trau chuốt như lề tiêu đề modal, hay thiếu icon "tick" của checkbox. Ngoài ra, phiên bản viết lại Ultraviolet cũng đang gặp khá nhiều lỗi vặt và thiếu tính năng so với phiên bản gốc RedWarn.
  • SWViewer là một công cụ được đánh giá cao, nhờ có một giao diện tốt hơn phần lớn các công cụ khác ở wiki. Nhìn chung không có gì đáng để chê ở công cụ này, ngoại trừ SWViewer sử dụng queue làm luồng thông tin (với những sửa đổi được chọn lọc từ EventStreams), thay vì là một feed chảy liên tục như RecentChanges, điều này có thể gây chút khó chịu nếu như muốn duyệt wiki theo cách cổ điển. Ngoài ra, mục đích ban đầu của SWViewer là dùng để quản lý các "wiki nhỏ", nên việc dùng nó cho mục đích tổng quát (quản lý một wiki cụ thể, nhất là wiki lớn) có thể không quá phù hợp. Bên cạnh đó, SWViewer sử dụng AngularJS làm giao diện front-end, một thư viện đã ngừng phát triển từ rất lâu, điều này có thể là trở ngại để các lập trình viên mới tham gia phát triển.
  • AntiVandal là một công cụ mới được phát triển gần đây, có thể coi là phiên bản đơn giản của Huggle. Tuy ít được biết đến, nhưng chức năng của nó khá vừa phải và dễ sử dụng; giao diện tuy không quá kiểu cách nhưng vừa đủ để thực hiện các tác vụ một cách tiện dụng. Mã nguồn của AntiVandal vẫn được viết theo phong cách kinh điển của một user script, điều này có thể gây khó khăn để mở rộng về sau.

Tóm lại, mỗi một công cụ đều có những ưu nhược điểm riêng, việc sử dụng kết hợp nhiều công cụ khác nhau (nhất là sử dụng thêm các user script) có thể giúp giảm thiểu các nhược điểm, cũng như đảm bảo trải nghiệm và cảm xúc thoải mái khi làm việc trên wiki.

Tháng 7 năm 2022[sửa | sửa mã nguồn]

Ý định về việc thực hiện một chương trình tương tự RecentChanges và Twinkle đã được tôi quan tâm từ khá lâu, vì nhận thấy những nhược điểm lớn của hai công cụ kinh điển này. Tuy nhiên, từ trước năm 2022, tôi ít khi làm việc với JavaScript và hầu như không quan tâm nhiều về front-end, vì vậy kiến thức lúc đó là không đủ để triển khai ý tưởng. Tiện ích TwinkleMobile được viết vào cuối năm 2021, có thể nhận thấy là cách viết mã JavaScript lúc đó khá bừa bộn.

Từ đầu năm 2022, tôi bắt đầu học tập "tương đối" nghiêm túc JavaScript và một số công nghệ liên quan như TypeScript, React. Đến cuối tháng 7 năm 2022, tôi đã bày tỏ ý định làm một công cụ thay thế cho RecentChanges và Twinkle trên trang thảo luận của thành viên NguoiDungKhongDinhDanh, và đã nhận được một số góp ý khá hợp lý.

Tháng 9–10 năm 2022: Prototype đầu tiên[sửa | sửa mã nguồn]

Cuối tháng 9, đầu tháng 10 năm 2022, tôi mới có thời gian để bắt tay vào việc dựng prototype đầu tiên của dự án. Nếu không nhớ nhầm thì việc này diễn ra trong khoảng 2–3 tuần.

Thời điểm thực hiện prototype đầu tiên này là một khoảng thời gian khá quý báu, khi tôi nhận ra những ý định thiết kế ban đầu khi được trình bày thực tế đã không mang lại lợi ích như dự tính, đó là lý do chính mà prototype này đã bị hủy bỏ, một phần nữa là do lúc đó khá bận công việc cá nhân. Lý giải chi tiết như sau:

  • Vấn đề thứ nhất: Ý định ban đầu là chương trình sẽ được tổ chức tương tự một chương trình khác đang được phát triển là Teyora, với việc đặt trọng tâm vào một yếu tố quan trọng là workspace (không gian làm việc). Không rõ ý định của Teyora trong việc triển khai workspace là như thế nào, nhưng khả năng họ định nghĩa workspace là nơi thu nhận những luồng tin (feed) từ một hoặc nhiều wiki. Dù workspace là một ý tưởng khá hay, nhưng việc đặt trọng tâm vào nó (là màn hình được hiển thị ngay sau màn hình splash) có lẽ không nên, vì đây là một khái niệm khá lạ lẫm đối với cộng đồng wiki, do nhu cầu sử dụng của mọi người thường chỉ tập trung một wiki chính, rất hiếm thành viên có nhu cầu tuần tra liên wiki. Chức năng này vẫn nên có, nó rất phù hợp để kết hợp nhiều feed của nhiều wiki, nhưng không nên đặt trọng tâm vào nó.
  • Vấn đề thứ hai: Đối với giao diện làm việc chính (main screen), ý định ban đầu là sẽ chia làm 2 cột, với cột trái là nơi chứa thông tin đầy đủ của một sửa đổi, và cột phải là nơi chứa thông tin diff của sửa đổi đó (có thể có các nút lùi sửa, đánh dấu tuần tra). Thiết kế này vướng phải nhược điểm là lặp lại sai lầm của RecentChanges, khi quá dày đặc thông tin khiến khó tập trung để xử lý công việc. Ngoài ra, phần diff do không gian khá nhỏ nên có thể phải dùng inline diff, điều này khiến khó đọc hơn dạng split diff truyền thống.

Tháng 3 năm 2023: Prototype thứ hai[sửa | sửa mã nguồn]

Giữa tháng 3 năm 2023, sau khi đã giải quyết xong xuôi nhiều công việc cá nhân, tôi bắt tay vào việc thực hiện prototype thứ hai, từ một số ý tưởng manh nha sau nhiều tháng liền suy nghĩ, cũng như tái tham khảo một số chương trình tương tự như Huggle, SWViewer, AntiVandal.

Tôi bắt đầu lại từ việc xác định ý nghĩa của dự án. Mục tiêu của dự án là xây dựng một phiên bản thay thế có thể tốt hơn cho 2 công cụ RecentChanges và Twinkle, như vậy, khả năng một điểm cạnh tranh quan trọng của nó chính là giao diện người dùng. Đó phải là một giao diện có tính hài hòa và kế thừa, nếu quá tập trung vào những khái niệm lạ lẫm như workspace thì có thể khiến người sử dụng không quen thuộc so với những trải nghiệm từ trước.

Xét về RecentChanges, tôi nhận định ý nghĩa của nó là dùng để duyệt một danh sách các thay đổi, và kiểm tra sự khác biệt (diff). Như vậy, yếu tố cốt lõi xuyên suốt trong dự án chính là diff. Đó là thứ phải được thể hiện một cách rõ ràng và tường minh, và cần tập trung nhiều nhất. Vì diff giúp người dùng trực tiếp xác định một sửa đổi là thiện ý hay phá hoại, dù cho một số thông tin khác như con số chênh lệch kích thước văn bản giữa hai phiên bản, thông tin quyền người dùng, hay điểm ORES cũng có thể mang lại hiệu ứng tương tự, nhưng chúng chỉ nên là thông tin bổ sung trong quá trình đánh giá sửa đổi.

Prototype thứ hai[sửa | sửa mã nguồn]

Prototype này tập trung biểu diễn những thành phần quan trọng nhất của hệ thống, để từ đó có một sự hình dung tương đối về phần mềm trong tương lai, cũng như có cơ sở để thiết kế hệ thống và lập kế hoạch triển khai.

Thiết kế tổng thể[sửa | sửa mã nguồn]

Từ thực tế khảo sát, các công cụ có biểu diễn "Thay đổi gần đây" đều có 2 dạng chính: (1) gói các thành phần trong một hộp (compact), và (2) dãn theo nội dung (fit-content). Giao diện (1) xuất hiện ở những công cụ như RTRC, Huggle, SWViewer, AntiVandal. Giao diện (2) xuất hiện ở RecentChanges, Raun. Giao diện compact có nhược điểm so với giao diện fit-content là nó giới hạn không gian cuộn của feed "Thay đổi gần đây", thường là sẽ nằm trong một panel góc trái; nhưng ưu điểm là có thể dành được không gian rộng hơn để thể hiện diff. Giao diện chính của Zinnia kế thừa hai giao diện trên, vừa đảm bảo không gian cuộn của feed "Thay đổi gần đây" rộng nhất có thể (do không đóng gói), nhưng cũng dành được không gian lớn cho diff (đính kèm panel chứa diff theo thao tác cuộn).

Giao diện chính của chương trình gồm có 3 panel chính: FeedPanel, TabPanel, và ControlPanel. Ngoài ra, còn có một panel phụ ở đầu là HeaderPanel để thể hiện thông tin dự án. FeedPanel gồm các FeedItemCard xếp theo chiều dọc, không gian cuộn của FeedPanel là toàn màn hình.

HeaderPanel[sửa | sửa mã nguồn]

HeaderPanel là panel phụ chứa thông tin về phần mềm, bao gồm logo, slogan, một số liên kết đến các trang ngoài. Nó xuất hiện ngay khi mở chương trình, sau màn hình splash. HeaderPanel được ẩn đi khi người dùng cuộn xuống.

Không gian làm việc chính[sửa | sửa mã nguồn]

Màn hình làm việc là sự kết hợp của 3 panel chính theo chiều từ trái qua phải: FeedPanel, TabPanel, ControlPanel. Trong đó, FeedPanel là panel chứa feed, thể hiện dưới dạng các card gọi là FeedItemCard. TabPanel là panel thể hiện nội dung của một tab và các thành phần chức năng có liên quan, trong ví dụ hiện tại thì nó là DiffTabPanel, dùng để thể hiện một diff. ControlPanel là nơi chứa các nút điều khiển chính của chương trình.

FeedPanel[sửa | sửa mã nguồn]

FeedPanel là nơi chứa feed, thể hiện dưới dạng một stack gồm các FeedItemCard.

FeedItemCard gồm các thông tin của một feed item, là một đối tượng chung được thể hiện cụ thể tùy bối cảnh. Nếu là feed Recent Changes và Watchlist thì feed item là "change"; feed New Pages là "page"; và feed New Files là "file". Trong ví dụ, feed item là một change, cụ thể là "edit change" (sửa đổi), nên sẽ có những thông tin điển hình như thời điểm sửa đổi, điểm ORES, con số chênh lệch kích thước văn bản, trang được sửa, thành viên sửa, và wiki. Có thể bổ sung thêm một số chỉ báo (indicator) để thể hiện thêm một số thông tin, nhưng cần cân nhắc để giữ FeedItemCard cân đối.

Đối với FeedItemCard của edit change, khi hover sẽ xuất hiện một hovercard chứa 3 nút: [Diff], [New tab], [See later]. [Diff] là nút khi hover thì hiển thị một hovercard để xem trước diff của sửa đổi (DiffPreviewHovercard). [New tab] khi bấm vào thì edit change được mở trong một tab mới. [See later] khi bấm vào thì edit change được thêm vào bộ sưu tập See later (Xem sau).

TabPanel và DiffTabPanel[sửa | sửa mã nguồn]

TabPanel là nơi chứa nội dung của tab và một số chức năng có liên quan. DiffTabPanel là trường hợp TabPanel thể hiện một diff (đến từ đối tượng change của feed).

DiffTabPanel có 3 phần theo chiều từ trên xuống:

  • Phần đầu là nơi thể hiện thông tin cơ bản của một diff, bao gồm trang được sửa, thành viên sửa (thành viên tạo sửa đổi nằm bên phải, còn thành viên của phiên bản được so nằm bên trái), tóm lược sửa đổi, các tag của sửa đổi. Tóm lược và tag có thể được ẩn bằng một nút góc phải trên cùng của DiffTabPanel.
  • Phần giữa là nơi thể hiện diff, nó nằm trong một vùng cuộn (scroll area), với thanh cuộn được ẩn hiện tự động.
  • Phần đáy được chia làm 3 phần:
    • Hai carousel hai bên thể hiện danh sách sửa đổi của 2 người dùng của 2 phía của diff.
    • Phần giữa là dãy nút của các tool điển hình để xử lý sửa đổi: [Mark as patrolled], [Rollback (AGF)], [Rollback], [Rollback (vandalism)], [More tools]. Nút [More tools] mở một popover là ToolsPanel, nơi chứa các tool mà người dùng hay sử dụng. Khi bấm vào một tool, nếu là dạng tool được sandbox hóa (bản chất là một user script), thì sẽ mở một modal với viền đặc thù để chứa giao diện tool đó (SandboxedToolModal).

ControlPanel[sửa | sửa mã nguồn]

ControlPanel là nơi chứa các thành phần điều khiển chính của chương trình, bố trí trong một panel hẹp theo chiều từ trên xuống. Gồm có các thành phần sau:

FeedsMenu[sửa | sửa mã nguồn]

FeedsMenu là một action icon. Khi hover thì hiện một hovercard là FeedsHovercard, cho phép chuyển qua lại giữa các feed của workspace. Khi bấm vào thì hiện một modal là FeedsModal, chức năng tương tự FeedsHovercard, thuận tiện cho giao diện di động (do hovercard bị tắt).

[Previous] và [Next][sửa | sửa mã nguồn]

[Previous] và [Next] là hai nút để điều hướng feed, cho phép di chuyển lên hoặc xuống feed item kế trước hoặc kế tiếp.

FiltersMenu[sửa | sửa mã nguồn]

FiltersMenu là một action icon. Khi hover thì hiện FiltersHovercard, cho phép chuyển qua lại giữa các filter của feed. Khi bấm vào thì hiện FiltersModal, để cài đặt chi tiết các filter của feed.

PageHistoryCarousel[sửa | sửa mã nguồn]

PageHistoryCarousel là một carousel thể hiện lịch sử của trang gắn với tab đang mở. Nó xuất hiện tùy vào từng loại tab, ví dụ nếu là một tab Welcome (Chào mừng) thì nó không hiển thị trên ControlPanel.

TabsMenu[sửa | sửa mã nguồn]

TabsMenu là một action icon. Khi hover thì hiện TabsHovercard, cho phép chuyển qua lại giữa các tab. Khi bấm vào thì hiện TabsModal, cho phép chuyển tab, xóa tab.

WorkspacesMenu[sửa | sửa mã nguồn]

WorkspacesMenu là một action icon. Khi hover thì hiện WorkspacesHovercard, cho phép chuyển qua lại giữa các workspace. Khi bấm vào thì hiện WorkspacesModal, cho phép chuyển qua lại workspace, mở một số modal khác để xem chi tiết, sửa, xóa workspace bằng một menu ẩn.

SettingsMenu[sửa | sửa mã nguồn]

SettingsMenu là một action icon. Khi hover thì hiện QuickSettingsHovercard, để thực hiện nhanh một số thiết lập, như bật tắt chế độ tối của giao diện. Khi bấm vào thì hiện SettingsModal, để thực hiện các thiết lập cho chương trình.

MiscMenu[sửa | sửa mã nguồn]

MiscMenu là một action icon, khi hover thì hiện MiscHovercard, chứa các nút dẫn đến các chức năng khác của hệ thống. Theo ví dụ hiện tại thì có 3 nút: [See later], [Logs], [About]. Khi bấm vào mỗi nút trên thì hiện ra một modal chứa thông tin liên quan đến chức năng tương ứng.

GlassPanel[sửa | sửa mã nguồn]

GlassPanel là một yếu tố thiết kế, được thể hiện dưới dạng mặt gương mờ (sử dụng backdrop-filter của CSS), dùng trong một số hovercard, modal. Ý nghĩa là để nhấn mạnh vào các chức năng chính của chương trình.

Kiến trúc tổng thể[sửa | sửa mã nguồn]

Từ thiết kế của prototype thứ hai, chương trình có thể có kiến trúc dự kiến như sau:

  • Thứ nhất, dù là một ứng dụng hoàn chỉnh, nhưng bản chất chương trình vẫn là một user script, nó sẽ được cài đặt thông qua common.js của trang thành viên. Người dùng cần truy cập trang Special:BlankPage/Zinnia để sử dụng. Khả năng cao sẽ ép buộc người dùng cài đặt trên global.js của Meta, điều này giúp chương trình có thể hoạt động trên nhiều wiki.
  • Thứ hai, mỗi một phiên sử dụng, người dùng tiến hành các thao tác trên một workspace (không gian làm việc). Workspace là một bản mô tả mà người dùng cho biết mình sẽ làm việc với những wiki nào, có thể một hoặc nhiều wiki. Tuy nhiên, để không lặp lại sai lầm là đặt trọng tâm vào workspace như prototype đầu tiên, hệ thống sẽ chia khái niệm workspace thành hai loại: default (mặc định) và custom (tùy chỉnh). Workspace mặc định (default workspace) là một loại workspace đặc biệt, nó có sẵn khi người dùng mở chương trình, và nó chỉ liên kết đến duy nhất wiki mà người dùng đang mở chương trình chạy trên wiki đó. Ví dụ, người dùng mở chương trình trên enwiki thì workspace mặc định liên kết đến enwiki, tương tự với trường hợp mở trên viwiki. Như vậy, workspace mặc định thay đổi tùy theo môi trường wiki, và người dùng không được phép sửa hay xóa workspace này. Còn workspace tùy chỉnh (custom workspace) là loại workspace mà người dùng được phép tạo, sửa, xóa. Thông tin về workspace được sử dụng lần cuối sẽ được lưu trữ, giúp người dùng khi mở lại chương trình thì có thể mở đúng workspace lần trước mình đóng.
  • Thứ ba, mỗi một workspace luôn có sẵn 4 feed, bao gồm: Recent Changes (Thay đổi gần đây), New Pages (Trang mới), New Files (Tập tin mới), và Watchlist (Danh sách theo dõi). Feed là những nguồn cấp tin của một wiki, nó có thể có nhiều dạng, nhưng chương trình chỉ tập trung vào 4 loại feed đã nêu. Mỗi một feed theo quan điểm workspace là một hỗn hợp các feed cùng loại của những wiki được quy định trong workspace. Ví dụ, nếu một workspace được cấu hình liên kết đến hai wiki là enwiki và viwiki, thì feed Recent Changes của workspace này là hỗn hợp hai feed Recent Changes của 2 wiki đã nêu. Người dùng không được phép thêm, sửa, xóa bất kỳ feed nào trong workspace, mà chỉ được phép chuyển qua lại giữa các feed mà workspace cung cấp, điều này giúp đơn giản hóa hệ thống. Nội dung mỗi feed bao gồm:
    • Recent Changes là tập hợp các thay đổi (change) gần đây, có thể là sửa đổi (edit change) – dạng change được quan tâm nhiều nhất.
    • New Pages là tập hợp các trang (page) gần đây.
    • New Files là tập hợp các tập tin (file) gần đây.
    • Watchlist là tập hợp các thay đổi (change) gần đây của các trang được theo dõi.
  • Thứ tư, mỗi một feed có thể có một hoặc nhiều filter (bộ lọc). Filter là những thiết đặt giúp điều phối lượng thông tin của feed đúng theo nhu cầu mà người dùng mong muốn. Có hai loại filter là defaultcustom. Default filter là filter luôn có sẵn khi người dùng mở một feed, dù không được xóa, nhưng người dùng có thể sửa thông tin của nó để điều phối lại feed theo nhu cầu. Custom filter là những filter do người dùng tự tạo, sửa và xóa. Trong quá trình sử dụng một feed, người dùng có thể chỉ cần tùy chỉnh default filter là đủ nhu cầu, nhưng đôi khi nếu muốn lưu nhiều filter để dùng về sau thì custom filter lại hữu dụng. Lưu ý: Trong default workspace, filter (bao gồm hai dạng default và custom) có thêm một tính chất quan trọng, là nó được liên kết với wiki của default workspace. Nghĩa là nếu thay đổi môi trường wiki, thì filter cũng bị thay đổi theo. Nói cách khác, ở default workspace enwiki, nếu người dùng đã tùy chỉnh hệ thống filter, thì khi qua default workspace viwiki thì filter sẽ bị reset lại nếu trước đó chưa có tùy chỉnh gì. Việc này không xảy ra đối với custom workspace.
  • Thứ năm, mỗi một workspace có thể có một hoặc nhiều tab. Tab là panel chính của chương trình, nơi trình bày toàn diện thông tin về một chủ đề cụ thể, và là không gian chính để người dùng làm việc. Tab không thể tạo bằng tay, mà chỉ sinh ra trong quá trình sử dụng chương trình. Người dùng có thể chuyển qua lại giữa các tab bằng một hovercard hoặc modal. Dự kiến sẽ có những loại tab chính sau:
    • Welcome: Tab hiển thị khi mới lần đầu sử dụng chương trình, chỉ có 1, không thể xóa.
    • Diff: Tab hiển thị diff của một sửa đổi, có 1 hoặc nhiều, có thể xóa.
      • Main Diff: Trường hợp đặc biệt của diff tab, nó liên kết trực tiếp đến feed Recent Changes và feed Watchlist của workspace, chỉ có 1, không thể xóa.
    • Page History: Tab hiển thị lịch sử của một trang, có thể có 1 hoặc nhiều, có thể xóa.
    • User Contributions: Tab hiển thị đóng góp của một người dùng, có thể có 1 hoặc nhiều, có thể xóa.
    • Read: Tab hiển thị nội dung của trang, có 1 hoặc nhiều, có thể xóa.
      • Main Read: Trường hợp đặc biệt của read tab, nó liên kết trực tiếp đến feed New Pages của workspace, chỉ có 1, không thể xóa.
    • Edit: Tab sửa nội dung trang, có thể có 1 hoặc nhiều, có thể xóa.
    • Draft: Tab viết nháp, chỉ có 1, có thể xóa (có thể xem như một chương trình con).
    • File: Tab hiển thị thông tin của tập tin, có 1 hoặc nhiều, có thể xóa.
      • Main File: Trường hợp đặc biệt của file tab, nó liên kết trực tiếp đến feed New Files của workspace, chỉ có 1, không thể xóa.
  • Thứ sáu, những đối tượng change, page, file của 4 feed có thể được lưu lại trong một bộ sưu tập gọi là see later (xem sau). Chúng có thể được xóa khỏi see later, hoặc được đẩy từ see later sang một tab mới để làm việc.

Những module[sửa | sửa mã nguồn]

Kiến trúc luận lý dự kiến

Core[sửa | sửa mã nguồn]

Zinnia Core là module chính của chương trình. Nó là hiện thực của những khái niệm chính trong kiến trúc tổng thể, bao gồm: workspace, feed, filter, tab, see later, v.v. Sự thực hiện đó chính là việc biểu diễn các khái niệm kiến trúc thành những đối tượng đồ họa của giao diện người dùng, cũng như triển khai các chức năng cho giao diện đó. Ví dụ, feed được biểu diễn dưới dạng một stack [panel] gồm nhiều feed item [card], và có chức năng hiển thị chính xác nội dung feed theo dữ liệu được cung cấp từ API.

Core cũng là đầu mối giúp người dùng tương tác với các module khác của hệ thống. Ví dụ, trong các tab, Core cung cấp các tool của module Toolbox theo bối cảnh nội dung của tab, điển hình như khi truy cập diff tab, thì Core cung cấp tool "Mark as patrolled", là một nút bấm đơn giản để người dùng có thể dùng cho việc đánh dấu một sửa đổi là "đã tuần tra".

MW[sửa | sửa mã nguồn]

Mô hình hóa Zinnia MW

Zinnia MW là module nền tảng của chương trình, nó không có giao diện, và có ý nghĩa là một thư viện để kết nối đến hệ thống API của MediaWiki. Zinnia sẽ không sử dụng trực tiếp đối tượng mw của thư viện MediaWikiJS Core của ResourceLoader, nguyên nhân chính là vấn đề side effect. Nếu sau này Zinnia được cho chạy trên một môi trường ngoài front-end của MediaWiki, thì nó vẫn phải đảm bảo hoạt động được bình thường, như vậy hệ thống chỉ có thể tương tác với API của MediaWiki qua một interface như Zinnia MW. Tuy nhiên, cũng cần nhận thấy là đối tượng mw khá tiện lợi để thực hiện các lệnh gọi API.

Hiện tại chưa có thiết kế rõ ràng cho Zinnia MW, nhưng có thể nó là một abstract class: ZinniaMW, được kế thừa bởi 2 class là InternalClientZinniaMWExternalClientZinniaMW. Internal Client là môi trường front-end của MediaWiki, nơi có sẵn đối tượng mw; còn External Client là môi trường ngoài front-end của MediaWiki, nơi không có sẵn đối tượng mw. Như vậy, các phương thức của class InternalClientZinniaMW sẽ được triển khai theo hướng tận dụng lại các khả năng của đối tượng mw.

ZinniaMW dự kiến là một interface tương tự class mwn của thư viện mwn, với các triển khai của từng phương thức sẽ được phân nhánh cho hai class con InternalClientZinniaMWExternalClientZinniaMW. Thông qua đó, abstract class/interface ZinniaMW cũng kế thừa lại tài liệu của class mwn, điều này giúp không cần tốn công sức cho việc tài liệu hóa.

Toolbox[sửa | sửa mã nguồn]

Zinnia Toolbox là module quản lý hệ thống tool của chương trình. Tool ở đây là một khái niệm dùng để chỉ những phần chức năng mở rộng được tích hợp vào hệ thống một cách quy ước (theo ý muốn của hệ thống) hoặc tự do (theo ý muốn của người dùng).

Zinnia Toolbox Framework (ZTF) là một thư viện nền tảng hỗ trợ triển khai các tool cho hệ thống, cung cấp sẵn một số giải pháp để giải quyết các nghiệp vụ thường xuyên xuất hiện trong các tool, nó phụ thuộc vào module Zinnia MW. Ví dụ, ZTF có thể có hàm addTemplates(), giúp các tool có nhu cầu thêm bản mẫu vào một trang có thể sử dụng nó mà không cần phải viết lại những logic thông thường. Như vậy, các hàm của ZTF phải có tính generic cao để có thể sử dụng cho nhiều trường hợp.

Ý định ban đầu thì Toolbox sẽ bao gồm các tool tương tự Twinkle, như vậy sẽ có các tool điển hình như: Fluff, Speedy, Warn, Tag, ARV, Welcome, Image, PROD, XFD, Talkback, SharedIP, BatchDelete, BatchUndelete, Protect, BatchProtect, Block, DePROD, Unlink.

Để tránh lặp lại sai lầm trong 2 vấn đề i18n là l10n của Twinkle, các tool của Zinnia sẽ giải quyết 2 vấn đề này như sau:

  • Đối với i18n, vấn đề này khá dễ giải quyết, chỉ tách phần label ra riêng, không chứa trong mã nguồn (thể hiện label dưới dạng key). Như vậy, những tool nào của Zinnia mà có nhu cầu thực hiện i18n (không phải tool nào cũng cần i18n, nếu nó quá đơn giản) thì sẽ có một kho label riêng cho từng ngôn ngữ.
  • Đối với l10n, vấn đề này rất phức tạp do quy trình xử lý công việc ở mỗi wiki có thể rất khác nhau. Để xử lý, có thể chỉ có cách tạo ra một số hook gắn vào mã nguồn của tool, và cho phép mỗi wiki tạo một config riêng để lấp đầy nội dung các hook. Như vậy, tool sẽ hoạt động phù hợp với từng môi trường wiki cụ thể, với logic chính vẫn được giữ nguyên. Trong trường hợp nếu wiki không có config riêng thì tool sẽ chỉ chạy logic chính; hoặc thậm chí không cho phép tool chạy trên wiki đó, điều này có thể sẽ được thiết lập trước trong đặc tả của tool. Ý tưởng hook từng được đề cập trong một thảo luận trên Phabricator về việc cải thiện Twinkle.

Tool của Zinnia có thể có 2 loại: nativesandboxed. Native tool là những tool được thiết kế và xây dựng trên nền tảng của Zinnia, nó sở hữu một giao diện người dùng có tính liên hợp với giao diện chính của chương trình. Điều này tạo ra sự đồng bộ giao diện và đảm bảo trải nghiệm người dùng được thông suốt. Những tool được đề cập ở trên (lấy nguyên mẫu từ Twinkle) đều là các native tool.

Sandboxed tool là những tool có bản chất là một user script được đóng gói trong một sandbox. Sự tồn tại của sandboxed tool là do hệ thống user script khá hữu ích, nếu có thể tận dụng lại thì sẽ giải quyết được khá nhiều vấn đề mà không cần phải tốn công viết mới các native tool. Nhược điểm của sandboxed tool là nó không thể liên hợp về mặt giao diện, cũng như có thể gặp vấn đề về việc i18n và l10n. Về định hướng triển khai thì tham khảo đề mục của module Sandbox.

Sandbox[sửa | sửa mã nguồn]

Zinnia Sandbox là một module hỗ trợ đóng gói các user script hiện có của cộng đồng trong một môi trường tách biệt để có thể sử dụng và tương tác một cách an toàn trong hệ thống Zinnia. Hiện tại chưa có một thiết kế rõ ràng cho module này. Công cụ hỗ trợ xây dựng Sandbox có thể là thư viện websandbox của JetBrains.

Về mặt kỹ thuật, việc sandbox hóa một user script có thể là một công việc khá tốn kém, do phải xử lý kỹ các side effect. User script có thể cần truy cập các đối tượng global điển hình như $ (jQuery), mw (MediaWikiJS Core) hoặc DOM. Do đó, môi trường sandbox cần cung cấp đầy đủ các đối tượng này, cùng với một DOM vừa đủ để user script có thể chạy được. Việc sử dụng trực tiếp websandbox có thể sẽ tốn công do phải thực hiện sandbox hóa thủ công cho từng user script. Do đó, việc sandbox hóa nên được thực hiện tự động thông qua một wrapper, chính là module Sandbox, với một config vừa đủ. Vì vậy, yêu cầu đặt ra cho module Sandbox là nó có thể sandbox hóa tự động (có thể kèm config) một lượng tương đối user script phổ thông, nhất là những user script hữu ích được nhiều người sử dụng.

Module Sandbox tạo ra các sandboxed tool từ các user script, và những sandboxed tool này có thể tương tác ngược lại môi trường Zinnia thông qua một số API, điều này cần được thảo luận thêm.

Một hệ quả khá thú vị là những công cụ của Twinkle có thể chạy được trên Zinnia thông qua module Sandbox. Điều này khá hữu ích vì thời gian đầu chắc chắn không thể triển khai được hết các native tool lấy nguyên mẫu từ Twinkle, nên việc có sẵn các công cụ của Twinkle sẽ giúp người dùng tiếp tục các trải nghiệm thường ngày mà không bị gián đoạn khi sử dụng Zinnia.

Index[sửa | sửa mã nguồn]

Zinnia Index là một chỉ mục cho biết những user script nào đã được sandbox hóa thành công và có thể sử dụng được trong chương trình. Người dùng có thể thêm các sandboxed tool từ danh sách Zinnia Index, việc này khá giống như khi tải ứng dụng từ một chợ.

Chỉ mục này chỉ có ý nghĩa xác nhận sự tương thích. Người dùng có thể tự do tạo các sandboxed tool từ các user script có sẵn thông qua một giao diện, nhưng việc này có thể cần có kiến thức lập trình nếu như gặp trường hợp cần thiết lập config cho module Sandbox. Ngoài ra, việc thêm thủ công như vậy cũng không thể chia sẻ sandboxed tool cho những người dùng khác. Như vậy, việc có một chỉ mục như Zinnia Index là khá cần thiết.

Công nghệ sử dụng[sửa | sửa mã nguồn]

Zinnia là một ứng dụng front-end, khả năng cao là nó không cần back-end, do chỉ tương tác với API của MediaWiki, và chạy trên môi trường front-end cũng của MediaWiki. Các tập lệnh của chương trình sẽ được trữ trên một máy chủ Toolforge, nó không được trữ trên trang thành viên wiki (ngoại trừ một script nhỏ để kết nối với máy chủ Toolforge), nguyên nhân là do bundle size có thể rất lớn nếu dồn hết các module, tool vào một file duy nhất; giải pháp là chia ra các ES Module và dùng kỹ thuật lazy load của React.

Phía React[sửa | sửa mã nguồn]

React[sửa | sửa mã nguồn]

React là nền tảng chính để triển khai dự án. Nếu dự án này mà dùng Vanilla JavaScript hay jQuery thì chắc chắn không thể làm nổi.

TypeScript[sửa | sửa mã nguồn]

TypeScript là ngôn ngữ chính của dự án.

Mantine[sửa | sửa mã nguồn]

Mantine là thư viện chính để xây dựng giao diện cho dự án. Nhiều người hay nhiều hướng dẫn nói nên dùng Material UI (MUI) hay Ant Design (antd), nhưng thật sự các thư viện này khá thừa và đôi khi lại thiếu (thu phí linh tinh).

TanStack Query[sửa | sửa mã nguồn]

TanStack Query là thư viện giúp quản lý server state. Nó giúp đơn giản hóa quy trình tương tác với API, như vậy khả năng cao nó sẽ bọc các hàm của module Zinnia MW, vì các hàm này là các hàm async thô (trả về Promise của JavaScript hoặc Promise của jQuery, đều có tính thenable).

Jotai[sửa | sửa mã nguồn]

Jotai là thư viện giúp quản lý client state. Nguyên nhân cho việc lựa chọn thư viện này thật sự không rõ ràng, nhưng có thể là nó khá đơn giản và dễ hiểu, và tôi cũng không thích kiểu selector function của Redux hay Zustand. Nhóm pmndrs còn có thư viện Valtio để quản lý client state ngoài hai thư viện Jotai và Zustand, nhưng nó dùng proxy, tương tự Pinia của Vue. Proxy là thứ khá nguy hiểm nên tốt nhất không nên đụng.

Vite[sửa | sửa mã nguồn]

Vite là môi trường phát triển chính của dự án, nhìn chung có vẻ nó thực hiện hot reload nhanh hơn Webpack, và đồng thời build cũng tiện hơn nhờ tích hợp Rollup.

Khác[sửa | sửa mã nguồn]

  • i18next là framework để xử lý vấn đề i18n.
  • Zod là thư viện kiểm tra schema, khá hữu ích để xử lý các vấn đề liên quan đến form.
  • Framer Motion là thư viện để bổ sung các animation.
  • websandbox là thư viện để xây dựng module Sandbox.

Phía MediaWiki[sửa | sửa mã nguồn]

Nhìn chung sẽ tái sử dụng nhiều công nghệ được cung cấp bởi MediaWiki, như các module của ResourceLoader (bao gồm MediaWikiJS Core, OOjs, OOUI, jQuery), các editor (bao gồm WikiEditor, VisualEditor, 2017 wikitext editor, CodeEditor), các công cụ hữu ích khác như DiscussionTools. Chủ yếu vì lý do tương thích và đỡ mất công viết mới, dù việc tích hợp với phía React có thể gặp một số vấn đề.

Ngoài ra, cũng có sử dụng một số thư viện liên quan đến wiki do cộng đồng cung cấp, như mwn, types-mediawiki. Chủ yếu để có type, không bị TypeScript báo lỗi.

Các thảo luận khác[sửa | sửa mã nguồn]

Vấn đề chạy tool của Zinnia ngoài Special:BlankPage/Zinnia[sửa | sửa mã nguồn]

Các tool của Zinnia có thể được chạy ngoài môi trường sử dụng chính là Special:BlankPage/Zinnia. Ví dụ, nó có thể xuất hiện dưới dạng một dock ở một trang diff của wiki.

Vấn đề chạy Zinnia ngoài môi trường front-end của MediaWiki[sửa | sửa mã nguồn]

Zinnia có thể chạy trên một server riêng, cần sử dụng class ExternalClientZinniaMW của Zinnia MW, cũng như có thể phải có một số config đặc thù, điều này sẽ được thảo luận thêm.

Nhật ký triển khai[sửa | sửa mã nguồn]

Tháng 3 năm 2023[sửa | sửa mã nguồn]

  • Tuần 3, 4 (13-03 đến 26-03): Xây dựng prototype thứ hai và viết báo cáo đầu tiên.
  • Tuần 5 (27-03 đến 02-04): Thực hiện 2 issue:
    • Issue #1. Xây dựng monorepo zinnia
    • Issue #2. Triển khai chức năng workspace