Agency Docs
QBESXStandalone

Agency-Watch تطبيقات مخصصة

الآن مع AgencyOS27: تحديث مجاني لكل من يملك الساعة بالفعل.

v27.0.0مجاني7 صفحات

⌚ بناء تطبيقك الخاص لـ Agency-Watch

الساعة مفتوحة. يمكن لصاحب الخادم إضافة تطبيق يبدو ويتصرف كتطبيق مدمج، بالمكوّنات نفسها والألوان نفسها والترجمات نفسها.

الشرط: نسخة Pro. لا توجد التطبيقات المخصّصة إلا إذا كان Agency-Phone يعمل على الخادم ويملكه اللاعب. بدون Pro تُسجَّل لكنها لا تُسلَّم أبدًا: لا تعرف الواجهة عنها شيئًا، ولا تظهر في متجر التطبيقات، ويرفض الخادم كل إجراء ترسله. يُتحقق من ذلك في ثلاثة مواضع منفصلة ولا يمكن تعطيله.

الملفمطلوبماذا يفعل
apps/<id>/app.luaنعميسجّل التطبيق: الاسم والأيقونة واللون والفئة.
apps/<id>/app.jsنعمالشاشة: ما ترسمه وكيف تتفاعل.
apps/<id>/app.cssلاتنسيقك الخاص. يُحمَّل فقط عند style = true.
apps/<id>/server.luaلامنطق الخادم الذي يمكن لتطبيقك استدعاؤه.

يحمل المجلد اسم معرّف التطبيق تمامًا. بهذا تجد الساعة app.js وapp.css دون كتابة المسار مرتين، والمسارات المكتوبة مرتين تتباعد عاجلًا أو آجلًا.

كل ما تحت apps/ مُدرج في escrow_ignore: يبقى مقروءًا وقابلًا للتعديل على قرصك، ولا يستبدله تحديث الساعة أبدًا.

1 تسجيل التطبيق

apps/hello/app.lua

AgencyWatchApp({
    id       = 'hello',          -- lowercase, digits and _, must match the folder
    name     = 'Hello',
    icon     = 'raster',         -- one of the built-in icons, see below
    color    = '#5ac8fa',        -- #rrggbb
    category = 'tools',          -- tools | games | driving | style | connected
    style    = true,             -- also load app.css
    texts    = { en = 'Hello', de = 'Hallo' },   -- optional, name per language
})

يُرفض في وحدة تحكم الخادم، بوضوح ومع السبب، كل تطبيق بمعرّف غير صحيح أو بلا اسم أو بفئة غير معروفة أو بلون ليس بصيغة #rrggbb. لا يوجد تسجيل نصفي: فمثل هذا الخطأ لن يظهر إلا حين ينقر لاعب على التطبيق.

شغّل refresh وrestart Agency-Watch بعد إضافة الملفات. عند التشغيل تُبلغ الساعة بما سُجّل.

2 رسم الشاشة

apps/hello/app.js

AgencyWatch.app('hello', {

    render: function (w) {            // required, returns HTML
        var d = w.data();
        return w.card('Hello, ' + w.esc(d.name)) +
               w.section('Steps') +
               w.row({ icon: 'schritte', static: true,
                       top: String(d.steps || 0) }) +
               w.button('Roll a die', ' data-roll');
    },

    bind: function (w) {              // optional, runs right after
        w.click('[data-roll]', function () {
            w.toServer('roll', { sides: 6 }).then(function (a) {
                if (a.ok) w.notify('Hello', 'You rolled ' + a.data.value);
            });
        });
    },
});

يعمل render في كل مرة تُبنى فيها الشاشة، لذلك لا يحتفظ بأي حالة بين الاستدعاءات. ما يجب أن يبقى بعد إعادة الرسم يوضع في متغير خارج كائن التطبيق.

تعمل الدالتان داخل شبكة أمان. إذا ألقت شيفرتك خطأ، يعرض تطبيقك سطر خطأ وتواصل الساعة العمل؛ ويذهب الخطأ الفعلي إلى وحدة تحكم F8.

3 صندوق الأدوات

يحتوي w على كل ما يحتاجه تطبيق على ساعة، ولا شيء أكثر. الواجهة التي تفعل كل شيء لا يمكن تغييرها أبدًا، لذلك هذه صغيرة عمدًا.

الاستدعاءما تحصل عليه
w.data()لقطة مسطّحة: time, hour, minute, date, weekday, name, job, health, armour, pulse, steps, distance, calories, speed, heading, weather, pro.
w.row({icon, top, bottom, end, attrs, static})صف قائمة بنمط الساعة الخاص.
w.section(text)عنوان قسم.
w.card(html)سطح.
w.button(text, attrs)زر. attrs نص خصائص خام، مثل ' data-roll'.
w.toggle(on)مفتاح تشغيل وإيقاف.
w.center(html)في المنتصف، لقيمة كبيرة واحدة.
w.icon(name)إحدى الأيقونات المدمجة.
w.esc(text)يهرّب النص. استخدمه في كل ما ليس من عندك.
w.text(key, fallback)ترجمة من الساعة.
w.click(selector, fn)يربط مستمعًا. داخل bind فقط.
w.notify(title, text, icon, colour)إشعار على الساعة.
w.refresh()إعادة رسم دون حركة الظهور.
w.close()رجوع، مثل السهم في الترويسة.
w.toServer(action, data)سؤال الخادم. يُرجع promise.
w.id, w.versionمعرّف تطبيقك وإصدار AgencyOS.

اللقطة نسخة وليست مرجعًا. تحمل الساعة أيضًا جهات الاتصال والرسائل وبيانات البطاقات؛ ولا شيء من ذلك موجود فيها.

4 جهة الخادم

apps/hello/server.lua

AgencyWatchAction('hello', 'roll', function(src, data)
    local sides = tonumber(data and data.sides) or 6
    if sides < 2 then sides = 2 end
    if sides > 100 then sides = 100 end
    return { value = math.random(1, math.floor(sides)) }
end)

يكتمل w.toServer دائمًا، بـ { ok: true, data: … } أو { ok: false, reason: '…' }، حتى لو لم يرد الخادم أبدًا. لا يمكن لتطبيقك أن يعلق في الانتظار، والسبب موجود دائمًا في المستوى الأعلى أيًّا كانت الجهة التي رفضت.

reasonالمعنى
no_proلا توجد نسخة Pro. بدونها لا توجد تطبيقات مخصّصة.
unknownلا يوجد تطبيق أو إجراء مسجّل بهذا الاسم.
too_fastحد المعدل: عشرة طلبات كحد أقصى كل خمس ثوانٍ لكل لاعب.
errorألقى معالجك خطأ. التفاصيل في وحدة تحكم الخادم.
timeoutلا رد خلال اثنتي عشرة ثانية.
dataلم يكن الطلب جدولًا.

ما يصل في data يأتي من العميل وهو أمنية وليس حقيقة. تحقّق من كل قيمة قبل استخدامها. كل ما له قيمة (المال، العناصر، النتائج) مكانه الخادم ولا مكان غيره.

5 التنسيق

ألوان الساعة متاحة كمتغيرات CSS وتتبع ما اختاره مرتديها في Studio. الألوان الثابتة تعطيك تطبيقًا يبقى أزرق على ساعة خضراء.

var(--text)   var(--text-2)   var(--leise)
var(--akzent) var(--gruen)    var(--rot)    var(--gelb)
var(--karte)  var(--karte-hoch)   var(--linie)
var(--grund)

أضف بادئة إلى فئاتك الخاصة. الشاشة مشتركة مع كل التطبيقات الأخرى، والفئة المسماة .large ستجد من يشاركها.

6 الأيقونات المدمجة

مرّر أيًّا منها إلى icon في app.lua أو إلى w.icon():

akku auto blitz brief einkauf farben flugzeug gewitter glocke haken helligkeit herz hoch hupe karte karte-pin kein-signal kino kompass kreuz krone lampe laufen lautlos links loeschen minus mobil mond nebel neuladen pause personen pin plus qr raster rechts regen regler runter sanduhr schild schloss schloss-auf schnee schritte signal sonne sp-fall sp-flug sp-ring sp-turm sprechen stoppuhr telefon telefon-aus tempo ton uhr verboten wiedergabe wlan wolke zahnrad

تبقى أسماء الأيقونات كما هي عمدًا. إنها معرّفات وليست تسميات: لا يقرؤها اللاعب أبدًا، وإعادة تسمية معرّف تعطّل كل تطبيق يستخدمه بالفعل.

📦 مثال يعمل يأتي مع الساعة

apps/example/ داخل المورد تطبيق كامل قابل للتشغيل: مكوّنات واستدعاء للخادم وإشعار وCSS خاص. انسخ المجلد وأعد تسميته، وستحصل على نقطة انطلاق تعمل بالفعل.

توجد نسخة مختصرة من هذه الصفحة بجانبه في apps/README.md.

ما زلت عالقًا بعد هذه الصفحة؟ فريق الدعم يتولّى الأمر من هنا.