ایپس (پلگ انز) لکھنا
ایپس Antimatter کو اندر سے خصوصیات فراہم کرتی ہیں: Go میں سرور کا حصہ جو سرور میں ہک ہوتا ہے، اور React میں ویب ایپ کا حصہ جو مینو، پینلز، پیغام کے اقسام اور صفحات شامل کرتا ہے۔ یہ صفحہ دکھاتا ہے کہ ایک ایپ کیسے ترتیب دی جاتی ہے، جہاں شامل شدہ Polls ایپ کو مثال کے طور پر استعمال کیا گیا ہے، اور Antimatter کے Fusion انٹرفیس میں کیا تبدیلیاں آتی ہیں۔
ایپ کیسے کام کرتی ہے
- سرور کا حصہ ایک Go پروگرام ہے۔ سرور اسے ایک الگ پروسیس کے طور پر شروع کرتا ہے اور اس کے ساتھ RPC کے ذریعے بات چیت کرتا ہے: یہ ایپ کے ہکس کو کال کرتا ہے (ایک پیغام پوسٹ ہونے والا ہے، ایک کمانڈ چلائی گئی ہے…)، اور ایپ سرور کے پلگ ان API کو کال کرتی ہے (پوسٹ بنائیں، صارف پڑھیں، ڈیٹا محفوظ کریں…)۔ یہ
/plugins/<app id>/کے تحت HTTP روٹس بھی فراہم کر سکتی ہے۔ - ویب ایپ کا حصہ ایک JavaScript بंडل ہے جو ویب ایپ کے ساتھ براؤزر میں لوڈ ہوتا ہے۔ یہ رجسٹری کے ساتھ React اجزاء اور کال بیکس رجسٹر کرتا ہے: مینو میں بٹن، پینل، یا پیغام کے کسی قسم کو ڈرا کرنے کا طریقہ۔
- دونوں حصے اختیاری ہیں۔ ایک ایپ
.tar.gzبंडل کے طور پر انسٹال ہوتی ہے، اور سسٹم ایڈمنز اسے فعال، غیر فعال اور ترتیب دیتے ہیں۔
Antimatter Mattermost کے لیے لکھی گئی ایپس کو چلاتا ہے، اور اس کے برعکس بھی، بشرطیکہ ایپ صرف ان ہکس کا استعمال کرے جو دونوں میں موجود ہیں۔ دیکھیں صرف Antimatter کے ہکس۔
بंडل کی ترتیب
کوئی الگ اسٹارٹر ٹیمپلیٹ موجود نہیں ہے: ایک چھوٹی شامل شدہ ایپ جیسے antimatter-plugin-polls یا antimatter-plugin-todo سے شروع کریں، اور اس کا ID اور کوڈ تبدیل کریں۔ Polls کی ترتیب اس طرح ہے:
antimatter-plugin-polls/
├── plugin.json the manifest
├── Makefile build, test, bundle, deploy
├── build/ the manifest and pluginctl helper tools (Go), setup.mk
├── assets/icon.svg files shipped with the bundle
├── go.mod
├── server/
│ ├── main.go plugin.ClientMain(&Plugin{})
│ ├── plugin.go the Plugin type, OnActivate, ServeHTTP
│ ├── manifest.go generated from plugin.json
│ ├── api.go, command.go, hooks.go, store.go …
│ └── dist/ compiled binaries, one per platform
└── webapp/
├── package.json, webpack.config.js, tsconfig.json
├── i18n/ en.json and one file per language
├── src/index.tsx registers the app with the web app
├── src/manifest.ts generated from plugin.json
├── src/translations.ts
└── dist/main.js the bundle
اختیاری: ایک public/ فولڈر، جو /plugins/<app id>/public/ پر جیسا ہے فراہم کیا جاتا ہے۔
plugin.json
{
"id": "com.example.weather",
"name": "Weather",
"description": "Forecasts in the chat.",
"homepage_url": "https://github.com/example/weather",
"support_url": "https://github.com/example/weather/issues",
"icon_path": "assets/icon.svg",
"version": "1.0.0",
"min_server_version": "12.0.0",
"server": {
"executables": {
"linux-amd64": "server/dist/plugin-linux-amd64",
"linux-arm64": "server/dist/plugin-linux-arm64",
"darwin-amd64": "server/dist/plugin-darwin-amd64",
"darwin-arm64": "server/dist/plugin-darwin-arm64",
"windows-amd64": "server/dist/plugin-windows-amd64.exe"
}
},
"webapp": {"bundle_path": "webapp/dist/main.js"},
"settings_schema": {"settings": []}
}
id: منفرد اور مستقل؛ ایک ریورس ڈومین نام عام طور پر استعمال ہوتا ہے۔ یہ روٹس، محفوظ شدہ ترتیبات اور WebSocket ایونٹس کے نام مقرر کرتا ہے۔version: سیمنٹک ورژن۔ شامل شدہ ایپس اسےplugin.jsonسے باہر چھوڑ دیتی ہیں؛ ان کا بلڈ ٹول اسے تازہ ترینv*git ٹیگ سے لیتا ہے۔min_server_version: Antimatter12.0.0رپورٹ کرتا ہے۔settings_schema: سسٹم کنسول میں ایپ کی ترتیبات کی صفحہ (دیکھیں ترتیبات)۔
make apply مانی فیسٹ کو server/manifest.go اور webapp/src/manifest.ts میں کاپی کرتا ہے؛ make manifest-check اس کی تصدیق کرتا ہے۔
سرور کا حصہ
سرور کا حصہ Mattermost ایپس کے جیسا ہی Go ماڈیول، github.com/mattermost/mattermost/server/public، Go ماڈیول پروکسی سے امپورٹ کرتا ہے۔ اس کا main صرف ایپ کو شروع کرتا ہے:
package main
import "github.com/mattermost/mattermost/server/public/plugin"
func main() {
plugin.ClientMain(&Plugin{})
}
Plugin ٹائپ plugin.MattermostPlugin کو ایمبیڈ کرتا ہے، جس سے اسے p.API ملتا ہے، اور وہ ہکس (hooks) کو نافذ کرتا ہے جو اسے درکار ہیں:
type Plugin struct {
plugin.MattermostPlugin
router *mux.Router
}
func (p *Plugin) OnActivate() error {
p.router = p.newRouter()
return p.API.RegisterCommand(&model.Command{
Trigger: "weather",
AutoComplete: true,
AutoCompleteDesc: "Show the forecast",
AutoCompleteHint: "[city]",
})
}
func (p *Plugin) ExecuteCommand(c *plugin.Context, args *model.CommandArgs) (*model.CommandResponse, *model.AppError) {
city := strings.TrimSpace(strings.TrimPrefix(args.Command, "/weather"))
return &model.CommandResponse{
ResponseType: model.CommandResponseTypeEphemeral,
Text: "Forecast for " + city + ": sunny",
}, nil
}
func (p *Plugin) ServeHTTP(c *plugin.Context, w http.ResponseWriter, r *http.Request) {
p.router.ServeHTTP(w, r)
}
عام ہکس
| ہک | کب چلتا ہے |
|---|---|
OnActivate, OnDeactivate | جب ایپ کو فعال یا غیر فعال کیا جائے، اور جب سرور شروع ہو یا بند ہو۔ OnActivate میں کمانڈز اور بوٹس رجسٹر کریں۔ |
OnConfigurationChange | جب اس کی ترتیبات تبدیل ہوں؛ انہیں p.API.LoadPluginConfiguration(&cfg) کے ذریعے لوڈ کریں۔ |
ServeHTTP | /plugins/<app id>/… کی درخواستیں۔ جب درخواست سائنڈ ان صارف سے آتی ہے تو سرور Mattermost-User-Id ہیڈر سیٹ کرتا ہے؛ اس کے بغیر درخواستوں کو مسترد کریں، مگر یہ سوائے اس کے کہ وہ عوامی ہونے کا مقصد رکھتی ہوں۔ |
ExecuteCommand | ایپ نے رجسٹر کی ہوئی کمانڈ چلا دی گئی۔ |
MessageWillBePosted, MessageWillBeUpdated | پیغام محفوظ ہونے سے پہلے: تبدیل شدہ پوسٹ واپس کریں، یا اسے مسترد کرنے کی وجہ دیں۔ |
MessageHasBeenPosted, MessageHasBeenUpdated, MessageHasBeenDeleted | بعد ازاں، جانبی اثرات کے لیے۔ |
ReactionHasBeenAdded, ReactionHasBeenRemoved | ردعمل۔ |
UserHasJoinedChannel, UserHasLeftChannel, UserHasJoinedTeam, UserHasLeftTeam, ChannelHasBeenCreated | رکنیت اور چینلز میں تبدیلیاں۔ ٹیم ایک کمیونٹی ہے۔ |
FileWillBeUploaded | فائل محفوظ ہونے سے پہلے: اسے تبدیل کریں یا مسترد کریں۔ |
OnPluginClusterEvent | کلسٹر کے دوسرے سرور پر موجود اسی ایپ سے پیغام۔ |
مکمل فہرست، بالکل درست سائنچرز کے ساتھ، server/public/plugin/hooks.go میں ہے؛ API server/public/plugin/api.go میں ہے۔ pluginapi پیکیج (server/public/pluginapi) API کو دوستانہ ہیلپرز میں لفٹ کرتا ہے۔
مفید API کالز
CreatePost،UpdatePost،SendEphemeralPost: ایپ کے بوٹ کے طور پر یا کسی صارف کے طور پر پوسٹ کریں۔EnsureBotUser(&model.Bot{Username, DisplayName}): ایپ کا بوٹ ایک بار بنائیں اور اس کا ID حاصل کریں۔PublishWebSocketEvent("poll_updated", payload, &model.WebsocketBroadcast{ChannelId: id}): ویب ایپ کو ایونٹ بھیجیں۔ یہcustom_<app id>_poll_updatedکے طور پر پہنچتا ہے۔OpenInteractiveDialog: ڈائیلاگ کھولیں۔LogInfo،LogErrorاور اسی طرح کے: سرور لاگ میں لکھیں، ایپ کے ID کے ساتھ ٹیگ شدہ۔GetUser،GetChannel،HasPermissionToChannel: کسی صارف کے لیے عمل کرنے سے پہلے چیک کریں کہ کس کو کیا کرنے کی اجازت ہے۔
ایپ کلسٹر کے ہر سرور پر چلتی ہے۔ اسٹیٹ کو کیو وی اسٹور یا ڈیٹا بیس میں رکھیں، صرف میموری میں نہیں۔
AI سروس
Antimatter کا سرور ایپس کے لیے AI ماڈلز کو کال کرتا ہے، اس کے لیے ایڈمن نے جو ماڈل کنکشنز سیٹ اپ کیے ہیں (ایڈمن گائیڈ میں AI دیکھیں)۔ کوئی ایپ پرووائیڈر کی کلڈ نہیں رکھتی: یہ صرف اس شخص کا نام بتاتی ہے جس کے لیے وہ کام کر رہی ہے اور کہاں، اور سرور چیک کرتا ہے کہ کیا وہ شخص وہاں اس کنکشن کا استعمال کر سکتا ہے، اس کی حدود اور بجٹ لاگو کرتا ہے، ٹوکنز کو اس شخص اور ایپ کے حساب سے گنتی کرتا ہے، اور کال کی آڈٹ ریکارڈ کرتا ہے بغیر اس کے مواد کے۔
| طریقہ | یہ کیا کرتا ہے |
|---|---|
AIChat(actingUserID, channelID, teamID, *ai.ChatRequest) | ایک چیٹ کمپلیشن: پیغامات، ٹولز، اور ساختی آؤٹ پٹ (JSONSchema)۔ |
AIChatStream(…) | وہی، اسٹریمنگ کے ساتھ: چینل بند ہونے تک اسٹریم کے Events پڑھیں، یا کال روکنے کے لیے اسے Close کریں۔ |
AIEmbed(…, *ai.EmbedRequest) | متن کے ایمبیڈنگز۔ |
AITranscribe(…, *ai.TranscribeRequest) | بول چال کو متن میں تبدیل کرنا۔ |
AIDecide(…, *ai.DecideRequest) | ایک متن کے بارے میں فیصلہ ماڈل کو ٹائپڈ سوالات (ہاں یا نہیں، ایک انتخاب، ایک اسکور)۔ |
AIConnectionsForUser(userID, channelID, teamID) | وہ کنکشنز جو ایک شخص وہاں استعمال کر سکتا ہے، ان کے ماڈلز اور صلاحیتوں کے ساتھ، کبھی ان کی کلڈز کے ساتھ نہیں۔ |
ہر درخواست کا ConnectionID کنکشن منتخب کرتا ہے، اور Model اس کا ایک ماڈل (اگر خالی ہو تو کنکشن کا ڈیفالٹ)۔ Operation استعمال اور آڈٹ ریکارڈز کے لیے ایک مختصر لیبل ہے، کبھی مواد نہیں۔ ان کا کم از کم سرور ورژن 11.11 ہے۔
actingUserID کو صرف اس ماخذ سے لیں جو سرور نے تصدیق کر لیا ہو: آپ کے ServeHTTP کی درخواست کا Mattermost-User-Id ہیڈر، یا ہک کے کنٹیکسٹ کا صارف (پوسٹ کے مصنف، یا وہ صارف جس نے کمانڈ چلائی)۔ کبھی اسے پیغام، ویب ہک پی لوڈ، URL یا کسی دوسری ایپ کی درخواست سے نہ لیں: ورنہ آپ کی ایپ کسی اور کے رسائی کے وسائل خرچ کر دے گی۔یہ طریقے اور ai پیکیج (server/public/ai) صرف Antimatter کے ماڈل کی کاپی میں موجود ہیں، Mattermost کے پبلش شدہ ورژن میں نہیں۔ ان کا استعمال کرنے کے لیے، Antimatter کے server/public کے خلاف بلڈ کریں، اپنے go.mod میں ایک replace لائن کے ساتھ، مثال کے طور پر replace github.com/mattermost/mattermost/server/public => ../antimatter/server/public۔ ایسی ایپ صرف Antimatter پر چلے گی۔
ڈیٹا کا ذخیرہ
ہر ایپ کے لیے سرور کے ڈیٹا بیس میں اپنا الگ کیو وی اسٹور ہوتا ہے:
KVSet(key, value),KVGet(key),KVDelete(key): ویلیوز بائٹس ہوتی ہیں، عموماً JSON۔ کیز زیادہ سے زیادہ 150 حروف کے ہو سکتے ہیں۔KVSetWithExpiry(key, value, seconds): ویلیو اس وقت کے بعد غائب ہو جاتی ہے۔KVCompareAndSet(key, old, new)اورKVSetWithOptionsکے ساتھAtomic: جب کئی درخواستیں یا سرورز ایک ہی کی پر لکھتے ہوں تو محفوظ اپڈیٹس۔ پولز اس طریقے سے ہر ووٹ محفوظ کرتا ہے اور تصادم پر دوبارہ کوشش کرتا ہے۔KVList(page, perPage): کیز، صفحہ بہ صفحہ۔
ویب ایپ کا حصہ
بندل window.registerPlugin کے ذریعے ایک کلاس رجسٹر کرتا ہے۔ اس کا initialize رجسٹری اور Redux اسٹور وصول کرتا ہے:
import manifest from './manifest';
class Plugin {
initialize(registry, store) {
registry.registerTranslations((locale) => translationsFor(locale));
registry.registerPostTypeComponent('custom_poll', PollPost);
registry.registerWebSocketEventHandler(`custom_${manifest.id}_poll_updated`, (msg) => {
store.dispatch(pollUpdated(JSON.parse(msg.data.poll)));
});
registry.registerReconnectHandler(() => store.dispatch(reloadPolls()));
}
}
window.registerPlugin(manifest.id, new Plugin());
- مشترک لائبریریاں۔ ویب ایپ React، ReactDOM، Redux، React Redux اور React Intl فراہم کرتی ہے: انہیں webpack
externals(React,ReactDOM,Redux,ReactRedux,ReactIntl) کے طور پر درج کریں، اپنے کاپیوں کو بندل کرنے کے بجائے۔ Polls کےwebpack.config.jsکو دیکھیں۔ - اپنے سرور حصے کو کال کرنا۔
${window.basename}/plugins/<app id>/…کوClient4.getOptions()(جوmattermost-redux/clientسے آتا ہے) کے آپشنز کے ساتھ Fetch کریں: یہ وہ ہیڈرز ہیں جو سرور کو براؤزر سے آنے والی درخواست کو قبول کرنے کے لیے درکار ہوتی ہیں۔ - آپ کا اپنا اسٹیٹ۔
registerReducerایک ریڈیوسر شامل کرتا ہے، جوstate['plugins-<app id>']کے تحت محفوظ ہوتا ہے۔ - ٹائپس۔ Antimatter کے اضافی رجسٹری طریقے Mattermost کے شائع شدہ ٹائپس میں شامل نہیں ہیں: Polls
webapp/src/types/host.tsمیں وہ رجسٹری اعلان کرتا ہے جسے استعمال کرتا ہے۔
رجسٹری کے طریقے اور ان کے پیرامیٹرز کوڈ میں دستاویزات کے طور پر موجود ہیں، webapp/fusion/src/plugins/registry.ts (Fusion) اور webapp/channels/src/plugins/registry.ts (classic) میں۔
Fusion انٹرفیس کی معاونت
Antimatter کے دو ویب انٹرفیس ہیں: Fusion، جو ڈیفالٹ ہے، اور کلاسیکی۔ دونوں ایک جیسے ایپ بندلز لوڈ کرتے ہیں اور ایک جیسی رجسٹری رکھتے ہیں، لیکن Fusion کئی چیزیں خود بناتا ہے اور پلگ ان اجزاء کو اپنی طرز پر رکھتا ہے۔ اپنی ایپ کو دونوں میں ٹیسٹ کریں۔
انٹرفیس کی شناخت
کسی بھی ایپ کے لوڈ ہونے سے پہلے، دونوں انٹرفیس window.antimatterWebUI کو 'fusion' یا 'classic' پر سیٹ کرتے ہیں، اور اسی ویلیو کو صفحے کے روٹ عنصر پر data-am-web-ui کے طور پر۔ Mattermost پر، نہ تو یہ سیٹ ہوتا ہے۔
export function isFusionUI(): boolean {
return window.antimatterWebUI === 'fusion' || document.documentElement.dataset.amWebUi === 'fusion';
}
باندل شدہ ایپس اس کے استعمال سے مختلف انداز میں ڈرائے کرتی ہیں۔ پولز اپنی پول کارڈز اور تخلیق کے ڈائیلاگ کو Fusion کے انداز میں ڈرائے کرتی ہے، اور Fusion میں /poll کے لیے اپنا الگ ڈائیلاگ کھولتی ہے۔ کالز اور وائس چینلز وہ سائیڈ بار اور ٹوسٹ کمپوننٹس چھوڑ دیتے ہیں جن کی جگہ Fusion اپنی کال انٹرفیس رکھتی ہے۔ ایجنٹس ایپ اپنے AI اقدامات کو پیغام کے مینیو میں، مزید اقدامات کے نیچے ایک گروپ کے طور پر رکھتی ہے، ہاور ٹول بار کے بجائے۔ Fusion کی اپنی CSS classes (جو am- سے شروع ہوتی ہیں) اور اس کا ڈائیلاگ لیئر (am-layer عنصر) وہ چیزیں ہیں جن کا ان ایپس کو انٹرفیس کو میچ کرنے کے لیے استعمال ہوتا ہے؛ یہ دستاویزی شدہ، مستحکم API نہیں ہیں۔
جہاں فیوژن پلگ ان کمپوننٹس دکھاتا ہے
| رجسٹری طریقہ | فیوژن میں کہاں ظاہر ہوتا ہے |
|---|---|
registerAppBarComponent, registerChannelHeaderButtonAction | ایپ ریل، یعنی دائیں کنارے پر آئیکنز کی کالم، جو آپ کے ایواٹار اور Antimatter کے بارے میں بٹن کے درمیان ہے۔ چینل ہیڈر کے بٹن بھی اسی جگہ آتے ہیں، چینل ہیڈر میں نہیں۔ جب سسٹم ایڈمن ایپس بار غیر فعال کریں (ExperimentalSettings.DisableAppBar، پہلے سے غیر فعال) کو آن کر دیتا ہے تو یہ چھپ جاتا ہے۔ |
registerRightHandSidebarComponent | دائیں جانب پینل۔ لوگ اس کی کنارے کو ڈریگ کرکے اس کا سائز تبدیل کر سکتے ہیں، اور اسے نئے ونڈو میں کھول سکتے ہیں۔ اگر ایپ ایک پروڈکٹ بھی ہو، تو پینل مکمل صفحے کے طور پر کھولیں کا آپشن پیش کرتا ہے۔ دیکھیں نئے ونڈو میں پینل۔ |
registerChannelHeaderIcon | چینل ہیڈر میں آئیکنز، کال بٹنز کے بعد؛ فونز پر ہیڈر کے مزید میو میں۔ |
registerCallButtonAction | چینل ہیڈر کا کال بٹن؛ کئی پرووائڈرز کال کرنے کے دیگر طریقے میو کو شیئر کرتے ہیں۔ |
registerPostDropdownMenuAction | پیغام کے پیغام کے اقدامات (⋯) مینیو، اس کے مزید اقدامات سب مینیو میں؛ نیز سلسلے کے پینل کے سلسلے کے اقدامات مینیو میں، مزید اقدامات کے تحت۔ Fusion ہر اقدام سے پہلے ایپ کی آئیکن کو سرمئی رنگ میں ڈرائے کرتی ہے: باندل شدہ ایپس کے لیے اپنی آئیکن، ورنہ ایپ کی وہ آئیکن جو ایپ ریل میں دکھاتی ہے، ورنہ ایک نیوٹرل آئیکن۔ اگر کسی عنصر میں اقدام کے متن کے آغاز پر کوئی متن نہ ہو (ایک ایسی آئیکن جو ایپ خود ڈرائے کرتی ہے)، تو وہ چھپا دیا جاتا ہے۔ |
registerPostDropdownSubMenuAction | ایک ہی مزید اقدامات سب مینیو میں، انفرادی اقدامات کے بعد، ایک ہیڈنگ والا گروپ۔ کوئی ایپ پیغام کے مینیو میں اپنی الگ اندراج نہیں پاتی۔ |
registerPostActionComponent | میسج ہاور ٹول بار، ⋯ بٹن سے پہلے۔ |
registerPostTypeComponent, registerPostMessageAttachmentComponent, registerPostHeaderComponent, registerPostWillRenderEmbedComponent | میسج خود: اس کا باڈی، اس کے متن کے نیچے، اس کے وقت کے بعد، اور لنک پری ویوز کی جگہ۔ |
registerChannelHeaderMenuAction | چینل کا چینل کے اختیارات میو (سائیڈ بار میں چینل پر ⋯، یا رائٹ کلک)، پلگ آئیکن والے آئٹمز کے طور پر۔ |
registerMainMenuAction | کمیونٹی میو (چینل لسٹ کے اوپر کمیونٹی کا نام)، مزید اقدامات کے تحت، ایپ کے لحاظ سے گروپ شدہ۔ |
registerSidebarBrowseOrAddChannelMenuAction | کمیونٹی میو، چینل بنائیں اور زمرہ بنائیں کے بعد۔ |
registerFileUploadMethod | کمپوزر کا + میو (پیغام میں شامل کریں)، فائل اپ لوڈ کریں کے بعد۔ |
registerPostEditorActionComponent | کمپوزر کا فارمیٹنگ بار، جب فارمیٹنگ دکھائی جائے۔ |
registerAIActionMenuItemComponent | کمپوزر کا AI مینیو۔ |
registerFileDropdownMenuAction, registerFilePreviewComponent | فائل کا آپشنز مینیو، اور فائل پری ویو۔ |
registerUserSettings | پروفائل اور ترتیبات، پلگ انز ہیڈنگ کے تحت ہر ایپ کے لیے ایک ٹیب۔ |
registerChannelSettingsTab | چینل کی ترتیبات ڈائیلاگ، ایپس ہیڈنگ کے تحت۔ |
registerPopoverUserAttributesComponent, registerPopoverUserActionsComponent | پروفائل کارڈ، جو آپ کو نام یا ایواٹار پر کلک کرنے پر دکھائی دیتا ہے۔ |
registerLeftSidebarHeaderComponent, registerSidebarChannelLinkLabelComponent, registerChannelIconOverride, registerBottomTeamSidebarComponent | کمیونٹی کے چینلز کی فہرست کا اوپری حصہ، چینل کے نام کے ساتھ، چینل کی آئیکن کے ساتھ، اور بائیں جانب کمیونٹی ریل کا نچلا حصہ۔ |
registerChannelIntro, registerChannelIntroButtonAction, registerChannelToastComponent, registerNewMessagesSeparatorActionComponent, registerChannelComposerBannerComponent, registerComposerPlaceholder | کسی چینل کی تاریخ کا آغاز، پیغامات کی فہرست کا اوپری حصہ، غیر پڑھا لائن، کمپوزر کے اوپر، اور کمپوزر کا پلیس ہولڈر۔ |
registerChannelTypeOption | چینل بنائیں ڈائیلاگ کے چینل کے اقسام۔ |
registerSearchComponents | چینل ہیڈر کا تلاش خانہ: ایپ اسکوپس اس وقت ظاہر ہوتے ہیں جب یہ خالی ہو۔ |
registerUserGuideDropdownMenuAction | Antimatter کے بارے میں (ایپ ریل کا نچلا حصہ)، مدد کے تحت۔ |
registerProduct | پروڈکٹ کے URL پر مکمل صفحات، جو Antimatter کے بارے میں میں مصنوعات کے تحت درج ہیں۔ پروڈکٹ صفحات کلاسیکی پیج فریم کو برقرار رکھتے ہیں، جس کا پروڈکٹ مینیو صرف اس وقت دکھتا ہے جب کوئی ایپ پروڈکٹ رجسٹر کرتی ہو یا اس میں اندراج شامل کرتی ہو۔ باندل شدہ Kanban اور Playbooks ایپس اب پروڈکٹس رجسٹر نہیں کرتیں: ان کے صفحات ان کے سائیڈ پینلز میں کھلتے ہیں۔ |
registerRootComponent, registerGlobalComponent, ہکس جیسے registerMessageWillBePostedHook, registerSlashCommandWillBePostedHook, registerMessageWillFormatHook, registerFilesWillUploadHook, registerDesktopNotificationHook, registerWebSocketEventHandler, registerReducer, registerTranslations | کلاسیک انٹرفیس کی طرح کام کریں۔ |
registerAdminConsolePlugin, registerAdminConsoleCustomSetting | سسٹم کنسول، جو دونوں انٹرفیسز میں کلاسیک ہے۔ |
Fusion جو چیزیں ظاہر یا چلا نہیں کرتا
registerPostDropdownMenuComponent(پیغام کے مینیو میں ایک کمپوننٹ)،registerPostCardTypeComponent(پیغام کا کارڈ دائیں جانب پینل میں) اورregisterProductSwitcherMenuItemFusion کے مرکزی ویوز میں ظاہر نہیں ہوتے۔ پہلے کے بجائےregisterPostDropdownMenuActionاستعمال کریں۔registerMessageWillBeUpdatedHookFusion میں پیغام کے ترمیم کے وقت نہیں چلتا۔ ترمیمات کو سرور پرMessageWillBeUpdatedہک کے ذریعے چیک کریں۔registerActionAfterChannelCreationصرف کلاسیک چینل تخلیق ڈائیلاگ سے چلتا ہے، جسے Fusion اپنے چینل بنائیں ڈائیلاگ میں مزید اختیارات… سے کھولتا ہے۔- ایپ بار کمپوننٹس ان کے
supportedProductIdsسے قطع نظر ظاہر ہوتے ہیں۔ registerNeedsTeamRouteاورregisterCustomRouteسے آنے والے روٹس کلاسیک پیج فریم برقرار رکھتے ہیں، جیسے پروڈکٹس۔
ہکس جو صرف Antimatter میں ہیں
یہ رجسٹری طریقے Mattermost پر موجود نہیں ہیں۔ کال کرنے سے پہلے چیک کریں کہ طریقہ موجود ہے، تاکہ ایپ وہاں بھی کام کرے:
if (typeof registry.registerComposerMenuItem === 'function') {
registry.registerComposerMenuItem({
text: 'Create a poll',
icon: <i className='icon icon-chart-bar'/>,
fusionIcon: 'poll',
action: ({channelId, rootId}) => openPollCreation(channelId, rootId),
});
} else {
registry.registerChannelHeaderButtonAction(icon, (channel) => openPollCreation(channel.id), 'Create a poll', 'Create a poll');
}
| طریقہ | یہ کیا شامل کرتا ہے |
|---|---|
registerComposerMenuItem({text, icon, fusionIcon, action, shouldRender}) | پیغام باکس کے + مینیو میں ایک آئٹم، دونوں انٹرفیسز میں۔ action کو {channelId, rootId} ملتا ہے۔ |
registerEmojiPickerTab({id, label, icon, fusionIcon, order, component, shouldRender, replacesGifPicker}) | پیغام باکس کے ایموجی پکر کا ایک ٹیب، جیسے GIFs یا اسٹیکرز۔ Fusion میں، 10 سے کم order والے ٹیبز ایموجی ٹیب سے پہلے آتے ہیں۔ کمپوننٹ کو channelId، rootId، filter، onFilterChange، onSelectDone، insertText، isFusion اور، Fusion میں، pickerKit (نیچے دیکھیں) ملتا ہے۔ |
registerChannelViewPanel({matcher, component}) | چینل ہیڈر اور پیغامات کے درمیان ایک پینل، جن چینلز کے لیے matcher(state, channel) منتخب کرتا ہے۔ یہ پیغامات اور کمپوزر کو چھپا سکتا ہے (setMessagesVisible)، جیسا کہ وائس چینلز کرتے ہیں۔ |
registerSidebarChannelFooterComponent(component) | سائیڈ بار میں چینل کے نیچے ایک قطار، جیسے اس کی کال میں موجود افراد۔ یہ channel وصول کرتا ہے۔ |
registerIntegrationsOption({title, description, fusionIcon, action, shouldRender}) | صرف Fusion: انضمامات صفحات پر ایک اندراج، کسٹم ایموجی کے ساتھ۔ GIF ایپ وہاں اپنے کسٹم GIF اور اسٹیکرز شامل کرتی ہے۔ |
ایموجی پکر میں ویوز شامل کریں اور ان کا انتظام کریں
Fusion میں، ایموجی پیکر کے ٹیب کو pickerKit پراپ ملتا ہے: یہ وہ کمپوننٹس ہیں جو ایموجی ٹیب اپنے add اور manage ویوز کے لیے استعمال کرتا ہے، تاکہ ٹیب کے ویوز ایک جیسے نظر آئیں اور پیکر کے اندر ہی رہیں۔ GIFs اور Memes ایپس اسے GIFs، اسٹیکرز اور میم ٹیمپلیٹس کو add اور manage کرنے کے لیے استعمال کرتی ہیں۔ اس میں version (1)، ہکس usePickerView اور useOnEscape، اور کمپوننٹس PickerViewButtons (سرچ باکس کے ساتھ + اور manage بٹنز)، PickerViewFrame (اپنی بیک اریو کے ساتھ ایک ویو)، PickerNotice، PickerField، PickerSearch، PickerDropZone اور PickerManageList شامل ہیں۔ Escape دبا کر کسی ویو سے ٹیب کے گرڈ پر واپس جاتے ہیں۔ چیک کریں کہ یہ پراپ موجود ہے: دیگر ہوسٹس اسے چھوڑ دیتے ہیں، اور اس صورت میں ٹیب اپنے ڈائیلاگز خود رکھتا ہے۔ ٹائپس webapp/fusion/src/types/store/plugins.ts (EmojiPickerTabProps) میں اور کمپوننٹس webapp/fusion/src/fusion/popovers/picker_views.tsx میں موجود ہیں۔
نئے ونڈو میں پینل
Fusion، registerRightHandSidebarComponent کے کمپوننٹ کو دو مزید پراپس دیتا ہے، تاکہ نئے ونڈو میں کھولیں پینل کو ایسی جگہ کھولے جہاں وہ پہلے تھا، نہ کہ ایپ کے ہوم پر:
setPanelState(state): اسے پینل کی جگہ بدلنے پر کال کریں، اپنے ایپ کے ذریعے تعریف کردہ ایک مختصر سٹرنگ کے ساتھ، جیسے'note/<id>'یا'board/<id>/card/<id>'، یا اپنے ہوم پرnull۔ یہ ونڈو کے ایڈریس میں جاتا ہے، اس لیے اس میں کبھی کوئی راز نہ ڈالیں۔ 512 حروف سے طویل سٹیٹ، یا کنٹرول کاریکٹرز والا سٹیٹ، خارج کر دیا جاتا ہے۔initialPanelState: نئے ونڈو میں، وہ سٹیٹ جو پینل کے پاس تھی، یاundefined۔ اسے غیر معتبر ان پٹ کے طور پر سمجھیں: سائنڈ ان صارف کے طور پر آئٹم کو دوبارہ fetch کریں، اور اگر وہ اسے کھول نہیں سکتا ہے تو ایپ کا ہوم یا not-found ویو دکھائیں۔
جب پینل بند ہو جائے یا کسی دوسری ایپ کا پینل اس کی جگہ لے لے تو سٹیٹ بھول جاتی ہے۔ کسی پینل کے ونڈو کو خود کھولنے کے لیے، popoutRhsPlugin (جو window.WebappUtils.popouts میں بھی موجود ہے) سٹیٹ کو اختیاری پانچویں آرگومنٹ کے طور پر لیتا ہے۔ Notes، Whiteboard، Todo، Kanban اور Playbooks اس کا استعمال کرتے ہیں۔
fusionIcon Fusion کے آئیکن سیٹ میں سے ایک آئیکن کا نام ہے (مثلاً poll، sticker، calendar یا image؛ دیکھیں webapp/fusion/src/fusion/components/icon)۔ Fusion اسے icon کی جگہ دکھاتا ہے، تاکہ یہ آئیٹم دوسروں کے مطابق ہو۔
ترتیبات
plugin.json میں settings_schema سسٹم کنسول › پلگ انز میں ایپ کا صفحہ بیان کرتا ہے:
"settings_schema": {
"header": "Forecasts come from the weather service below.",
"settings": [
{"key": "ServiceURL", "display_name": "Service URL", "type": "text", "default": "https://api.example.com"},
{"key": "Units", "display_name": "Units", "type": "dropdown", "default": "metric",
"options": [{"display_name": "Celsius", "value": "metric"}, {"display_name": "Fahrenheit", "value": "imperial"}]},
{"key": "EnableAlerts", "display_name": "Severe weather alerts", "type": "bool", "default": false,
"help_text": "Post alerts in the channels that follow a city."}
]
}
ترتیبات کی اقسام: bool، text، longtext، number، dropdown، radio، generated (ایک رینڈم سیکرٹ)، username، اور custom (جو ایک کمپوننٹ سے بنایا جاتا ہے جو ویب ایپ حصہ registerAdminConsoleCustomSetting کے ساتھ رجسٹر کرتا ہے)۔ ترتیبات کو sections میں گروپ کیا جا سکتا ہے۔
سرور کا حصہ انہیں ایک سٹرکٹ میں پڑھتا ہے جس کے فیلڈز کیز کے مطابق ہوتے ہیں:
type configuration struct {
ServiceURL string
Units string
EnableAlerts bool
}
func (p *Plugin) OnConfigurationChange() error {
var cfg configuration
if err := p.API.LoadPluginConfiguration(&cfg); err != nil {
return err
}
p.setConfiguration(&cfg)
return nil
}
ایڈمنز انہیں کنفیگریشن میں بھی سیٹ کر سکتے ہیں، PluginSettings.Plugins.<app id> کے تحت، چھوٹے حروف میں کیز کے ساتھ (دیکھیں ایڈمن گائیڈ)۔
ترجمے
Antimatter کو 37 زبانوں میں ترجمہ کیا گیا ہے، اور شامل ایپس بھی۔ ویب ایپ کا حصہ اسے اس طرح کرتا ہے:
- ہر سٹرنگ کو React Intl کے ساتھ لکھیں، ایک ID اور اس کے انگریزی متن کے ساتھ:
<FormattedMessage id='polls.create' defaultMessage='Create a poll'/>یاdefineMessages۔ IDs کو اپنی ایپ کے نام سے پیش کریں۔ - انگریزی سٹرنگز کو
webapp/i18n/en.jsonمیں نکالیں (شامل ایپسformatjs extractاستعمال کرتی ہیں)۔ - اس کے ساتھ ہر زبان کے لیے ایک فائل شامل کریں، ایک ہی IDs کے ساتھ:
fr.json،de.json،pt-BR.json،zh-CN.json… - انہیں ویب ایپ کو دیں، جو صارف کی زبان پوچھتی ہے:
import fr from '../i18n/fr.json'; import ptBR from '../i18n/pt-BR.json'; const catalogs = {fr, 'pt-BR': ptBR}; export function translationsFor(locale) { return catalogs[locale] || catalogs[locale.split('-')[0]] || {}; } registry.registerTranslations(translationsFor);
اگر کوئی سٹرنگ موجود نہ ہو تو اس کی انگریزی defaultMessage استعمال ہوتی ہے۔ ان سٹرنگز کے لیے جو سرور حصہ بھیجتا ہے (کمانڈ کے جوابات، بوٹ پیغامات)، pluginapi/i18n پیکج بنڈل میں شامل ترجمہ فائلز (مثلاً assets/i18n) لوڈ کرتا ہے اور ہر صارف کی زبان میں لوکلائزر فراہم کرتا ہے۔
بنائیں، انسٹال کریں اور ڈیبگ کریں
آپ کو Go اور Node.js (ایپ کے .nvmrc میں دی گئی ورژن) درکار ہیں۔ ایپ کے فولڈر میں:
| کمانڈ | یہ کیا کرتا ہے |
|---|---|
make dist | ہر پلیٹ فارم کے لیے سرور حصہ اور ویب ایپ حصہ بناتا ہے، اور بنڈل کو dist/<app id>-<version>.tar.gz میں لکھتا ہے۔ |
make test | Go اور JavaScript ٹیسٹ چلاتا ہے۔ |
make check-style | کوڈ کو لِنٹ کرتا ہے (golangci-lint, ESLint) اور TypeScript کی قسموں کی جانچ کرتا ہے۔ |
make deploy | بناتا ہے، پھر سرور پر بنڈل کو انسٹال اور فعال کرتا ہے۔ |
make watch, make deploy-from-watch | پہلا ہر بار آپ کے سیو کرنے پر ویب ایپ حصہ دوبارہ بناتا ہے؛ دوسرا جو کچھ بنایا اسے بنڈل کر کے سرور پر انسٹال کرتا ہے۔ |
make enable, make disable, make reset | سرور پر ایپ کو فعال، غیر فعال یا دوبارہ شروع کریں۔ |
make logs, make logs-watch | سرور لاگ میں ایپ کی لائنز دکھائیں۔ |
make attach | چل رہے سرور حصے کے ساتھ Delve ڈیبگر کو منسلک کرتا ہے (پہلے AM_DEBUG=1 کے ساتھ بنائیں)۔ |
make deploy اور دیگر سرور کمانڈز جب ایک مقامی موڈ سوکیٹ پاتے ہیں (/var/tmp/antimatter_local.socket، یا AM_LOCALSOCKETPATH) تو اسے استعمال کرتے ہیں: انہیں مقامی موڈ آن ہو کر سرور کی مشین پر چلائیں۔ ورنہ وہ MM_SERVICESETTINGS_SITEURL سے دیے گئے سرور پر AM_ADMIN_TOKEN، یا AM_ADMIN_USERNAME اور AM_ADMIN_PASSWORD کے ساتھ سائن ان کرتے ہیں۔ بلڈ ٹولز ابھی سائٹ URL کے لیے AM_ نام نہیں پڑھتے۔
بنڈل کو دستی طور پر انسٹال کریں
- سسٹم ایڈمن
AM_PLUGINSETTINGS_ENABLEUPLOADS=trueکے ساتھ اپ لوڈز کی اجازت دیتا ہے (ڈیفالٹ طور پر بند؛ سسٹم کنسول میں کوئی سوئچ نہیں ہے)۔ - پھر سسٹم کنسول › پلگ انز › پلگ ان مینجمنٹ › پلگ ان اپ لوڈ کریں، یا
amctl plugin add weather.tar.gzکے بعدamctl plugin enable com.example.weather۔ - اگر سروسرور پر پلگ ان سائنچر کو لازمی قرار دیں آن ہے، تو یہ صرف ان باندلز کو قبول کرتا ہے جو اس کے اعتماد کے ساتھ سائن شدہ ہوں؛ دیکھیں دیگر ایپس کی تنصیب۔
AM_SERVICESETTINGS_ENABLEDEVELOPER=true سیٹ کریں: اس صورت میں غلطیاں اپنے تفصیلی معلومات کے ساتھ آتی ہیں۔ بنڈل شدہ ایپس کے Makefiles صرف تب آپ کے پلیٹ فارم کے لیے سرور حصہ بناتے ہیں جب آپ کے شیل میں MM_SERVICESETTINGS_ENABLEDEVELOPER سیٹ ہو۔