跳至主要内容

Chapter 2.

Addon Basics -- frontend

1.1 frontend 資料夾介紹

在HydroOJ套件中 如果需要注射前端頁面 就需要建立frontend資料夾

my-addon/
├── frontend/
├── \[a-zA-Z0-9_\]+.page.tsx

其檔名格式為\[a-zA-Z0-9_\]+.page.tsx (其中\[a-zA-Z0-9_\]為正規表達式 代表英文字母大小寫、數字、底線的任意組合) 只要符合此格式的檔案 都會被HydroOJ識別為前端頁面檔案 並運行

1.2 page.tsx 檔案介紹

I. 頁面檔案結構

import { addPage, NamedPage, AutoloadPage } from '@hydrooj/ui-default';
addPage(new AutoloadPage('SomeNameIGuess', () => {
console.log('This will appear on every page load!');
}));
addPage(new NamedPage(['homepage'], async () => {
console.log('This will appear on `homepage` page load!');
}));
  • addPage:用來注射頁面的函式
  • AutoloadPage:用來注射到所有頁面的頁面類別
  • NamedPage:用來注射到指定頁面的頁面類別 如何查詢頁面名稱 在瀏覽器打開你想注射的頁面後 開啟開發者工具DevTools(F12) 在元素Elements標籤中 查看最外圍<html>標籤的data-page屬性 即可看到頁面名稱

II. 注射 HTML/body

我們可以使用document物件來操作DOM 進行HTML/body的注射

import { addPage, NamedPage } from '@hydrooj/ui-default';
addPage(new NamedPage(['homepage'], async () => {
const newDiv = document.createElement('div');
newDiv.innerHTML = '<h1>Hello, HydroOJ!</h1>';
document.body.prepend(newDiv); // 將新元素注射到body的最前面
}));

也可以使用其他DOM操作方法來進行注射 如appendChildinsertBefore等 這裡就是js的基本DOM操作方法了 可以參考相關的js教學來學習更多 之後程設班官網應該也會有相關的教學文章

1.3 HTTP 請求 (Request API)

如果你需要向伺服器請求資源或API資料 可以使用request函式來進行HTTP請求

I. 基本用法

import { request } from '@hydrooj/ui-default';

// GET 請求
request.get('/api/endpoint').then(response => {
console.log(response.data);
});

// POST 請求
request.post('/api/endpoint', { key: 'value' }).then(response => {
console.log(response.data);
});

// PUT 請求
request.put('/api/endpoint', { key: 'value' });

// DELETE 請求
request.delete('/api/endpoint');

II. 進階選項

// 帶有自定義標頭
request.get('/api/data', {
headers: { 'X-Custom-Header': 'value' }
});

// 處理錯誤
request.get('/api/data')
.then(res => console.log('成功:', res.data))
.catch(err => console.log('錯誤:', err.message));

// 使用 async/await
async function fetchData() {
try {
const response = await request.get('/api/data');
console.log(response.data);
} catch (error) {
console.error('請求失敗:', error);
}
}

1.4 對話框 (Dialog API)

HydroOJ 提供多種對話框元件來彰顯使用者訊息或請求使用者操作

I. Alert / Confirm / Prompt

import { alert, confirm, prompt } from '@hydrooj/ui-default';

// 簡單提示
alert('這是一個提示訊息');

// 確認對話框(返回 boolean)
confirm('確定要刪除嗎?').then(yes => {
if (yes) {
console.log('使用者按下確認');
}
});

// 輸入對話框(返回輸入值或 null)
prompt('請輸入內容:').then(value => {
if (value !== null) {
console.log('使用者輸入了:', value);
}
});

II. 高級對話框

import { Dialog, ActionDialog, InfoDialog } from '@hydrooj/ui-default';

// 訊息対話框
new InfoDialog({
title: '訊息',
message: '這是一個訊息對話框'
}).show();

// 帶有動作按鈕的對話框
new ActionDialog({
$body: document.createElement('div'),
onAction: (val) => {
console.log('使用者選擇了:', val);
}
}).show();

1.5 通知系統 (Notification API)

在頁面上方顯示簡短的通知訊息

import { Notification } from '@hydrooj/ui-default';

// 成功通知
Notification.success('操作成功!');

// 錯誤通知
Notification.error('操作失敗!');

// 警告通知
Notification.warning('請注意!');

// 資訊通知
Notification.info('這是一個資訊通知');

1.6 多國語系 (i18n)

在前端代碼中使用多國語系字符串

import { i18n } from '@hydrooj/ui-default';

// 獲取翻譯文本
const message = i18n('homepage');
console.log(message); // 對應當前語言的翻譯

// 帶有參數的翻譯(如果支援)
const greeting = i18n('greeting', { name: 'Alice' });

1.7 頁面系統進階用法

I. 頁面生命週期

import { NamedPage } from '@hydrooj/ui-default';

const page = new NamedPage(
'problem_detail',
async (pageName) => {
console.log('頁面載入前執行');
},
async (pageName) => {
console.log('頁面載入後執行');
}
);

II. 多頁面匹配

import { NamedPage } from '@hydrooj/ui-default';

// 在多個頁面上運行相同的代碼
addPage(new NamedPage(['homepage', 'problem_list', 'contest_list'], () => {
console.log('在主頁或列表頁上運行');
}));

III. 懶加載模塊

import { NamedPage } from '@hydrooj/ui-default';

// 指定模塊名稱以進行懶加載
const page = new NamedPage(
'heavy_page',
'my_heavy_module', // 模塊名稱
async (pageName) => {
console.log('懶加載的模塊執行');
}
);
其他可用資源

以下是 @hydrooj/ui-default 中一些其他常用的函式

套件名稱作用說明
request用來進行HTTP請求(GET/POST/PUT/DELETE)
i18n(key)用來進行多國語系翻譯
Dialog / ActionDialog / InfoDialog對話框元件
Notification.success() / error() / warning() / info()通知訊息
delay(ms)延遲指定毫秒數
pjax(url)PJAX 導航(無整頁刷新)
tpl / rawHtmlHTML 模板處理
getTheme()獲取當前主題

詳細的 API 參考請查看附錄:前端 API 完整參考

參考資料

草貓
第十四屆進階教學 aka.架網站的那個