لفترة طويلة كنا نستعد لتحديث Smartcalls ، محرر بصري للمكالمات الصادرة ، والآن حدث ذلك. اليوم ، تحت التخفيض ، سنتحدث عن تغييرات UI / UX ونتسلق تحت غطاء الوضع التجريبي لإظهار كيف قمنا بترويض JointJS .ما الذي تغير بالفعل؟
من الأكثر وضوحًا - اسم وعنوان URL جديد ، مما يعني أن مجموعة Voximplant Kit متاحة على الرابط المناسب voximplant.com/kit . قمنا أيضًا بتعديل صفحة التسجيل ، وهي الآن كما يلي:على الرغم من أن المفهوم ظل كما هو ، إلا أن واجهة المنتج تغيرت بشكل كبير ، لتصبح أكثر سهولة في الاستخدام. انتقلت القائمة العلوية إلى اليسار ، مما جعل التنقل بين الكتل أكثر منطقية وملاءمة.بالإضافة إلى ذلك ، يتوفر الآن تجميع وفرز النصوص والتسجيلات الصوتية ، والبحث بالأرقام ، بالإضافة إلى بطاقات الحملة التي تحتوي على معلومات موجزة عنها ، بما في ذلك المؤشرات الجديدة - متوسط مدة المكالمة الناجحة وإجمالي المبلغ المنفق.بالنسبة للتكامل: وصلت الواجهة سهلة الاستخدام إلى إعدادات البريد ، وعلى علامات التبويب Dialogflow و SIP و Global Variables ، ظهر بحث وفرز الملفات حسب المعرّف والمضيف.بشكل عام ، الكثير من الجديد والرائع! اقرأ المزيد حول التغييرات في مدونتنا .لكن أهم شيء هو المحرر
الوضع التجريبي (المفسد: هذه هي ميزة القاتل الرئيسية).تنفيذ برنامج نصي في الوقت الفعلي مع تمييز الكتل المشاركة ، وبعد التنفيذ - نتيجة مكالمة (Flow and Log) ، مما يجعل تصحيح البرامج النصية أسهل وأسرع.يمكنك مشاهدة فيديو الوضع التجريبي هنا أو اختباره بنفسك بعد التسجيل في Voximplant Kit .وكيف يتم تنفيذ كل هذا ، سنخبرنا في القسم التالي. الميزات الجديدة للمحرر:- تراجع / إعادة (1 في الصورة أدناه) ؛
- مفاتيح التشغيل السريع (2) ؛
- قائمة منبثقة حيث يمكنك محاذاة الكتل والروابط بينها بنقرة واحدة ، وتغيير المقياس ، والعمل مع miniMap ، وتوسيع البرنامج النصي إلى ملء الشاشة ، ومشاركته أيضًا (نسخ أو حفظ كملف png) (3) ؛
- انقر بزر الماوس الأيمن على قائمة السياق ؛
- نسخ الكتل - ليس فقط داخل نفس البرنامج النصي ، ولكن أيضًا بين النصوص المختلفة وحتى (!) الحسابات المختلفة ؛
- قفل / فتح كتلة - يمكن نقل كتلة مقفلة ، ولكن لا يمكن تحريرها لتجنب التغييرات غير المرغوب فيها ؛
- تغيير اللون - بصريًا يمكنك تحديد العديد من الكتل "ذات الصلة" ؛
- البحث عن طريق أسماء ومحتويات الكتل المستخدمة ؛
- كتلة "القائمة التفاعلية" - القدرة على تبديل المنافذ (خيارات الإجابة) في الأماكن ببساطة عن طريق السحب والإسقاط.
نكشف البطاقات
حان الوقت لمعرفة كيفية تنفيذ الرسوم المتحركة في الكود.يستدعي المحرر طريقة HTTP API الخاصة بنا - StartScenarios - لتشغيل البرنامج النصي السحابي. تبدأ سحابة Voximplant النص البرمجي وتعطيه لمحرر media_access_url. من هذه اللحظة ، يسحب المحرر media_access_url كل ثانية ، ويتلقى معلومات حول كيفية "انتقال" النص البرمجي عبر الكتل في الاستجابة - استنادًا إلى هذه البيانات ، يبرز المحرر الكتل الضرورية ويحيي الاتصالات بينها.History هو كائن JSON يحتوي على الحقول التالية:- الطابع الزمني
- idSource - الكتلة الأولية ؛
- idTarget - الكتلة النهائية ؛
- المنفذ - المنفذ (قد يكون هناك العديد من المخرجات من كتلة واحدة).
بمساعدة هذه المتغيرات المخصصة والخدمية ، تدرك الواجهة الأمامية الكتلة التي تمر بها أثناء الاختبار. كيف يفهم هذا؟ عندما يحدث البناء المرئي (تتم إضافة كتلة جديدة) ، يتم تعيين معرف على الفور ، والذي يتم استخدامه بعد ذلك في السجل كمعرف المصدر / معرف الهدف.لتنفيذ هذه الوظيفة ، استخدمنا مكتبة JointJS ، ولكن كان هناك بعض التعليمات البرمجية المكتوبة ذاتيًا.لنبدأ بالطريقة الرئيسية selectBlock () ، وهي تعمل على النحو التالي: ننتقل عبر مصفوفة محفوظات الحركة (idSource ، idTarget) وبمجرد أن نجد نقاط البداية والنهاية ، ابحث عن الاتصال بينهما:const link = this.editor.getTestLink(sourceCell, portId);
إذا كان هناك اتصال بينهما ، فإننا نحرك كرة تعمل على طول خط الاتصال:if (link) this.setLinkAnimation(link);
يتم استدعاء طريقة selectBlock () بعد كل تحديث لهذا التاريخ. نظرًا لأن العديد من الكتل التي تم تمريرها يمكن أن تصل إلى this.testHistory في وقت واحد ، فإننا نسمي بشكل متكرر selectBlock مرة واحدة كل 700 مللي ثانية (هذا هو الوقت التقريبي الذي يقضيه في تحريك الحركة من كتلة إلى أخرى):setTimeout(this.selectBlock, 700);
جميع التعليمات البرمجية لهذه الطريقة هي كما يلي. انتبه إلى طرق selectTestBlock و getTestLink ، السطران 7 و 10 - الآن سنتحدث عنها بشكل منفصل: | selectBlock ( ) : باطل { |
| if ( this . historyIndex < this . testHistory . length ) { |
| const i = this . historyIndex . |
| const targetCellId = this.testHistory[i].idTarget; |
| const sourceCellId = this.testHistory[i].idSource; |
| const portId = this.testHistory[i].port; |
| const targetCell = this.editor.selectTestBlock(targetCellId); |
| const sourceCell = this.editor.getCell(sourceCellId); |
| if (sourceCell && targetCell) { |
| const link = this.editor.getTestLink(sourceCell, portId); |
| if (link) this.setLinkAnimation(link); |
| } |
| this.historyIndex += 1; |
| setTimeout ( this . selectBlock ، 700 ) ؛ |
| }} |
| }} |
ارسم اتصالًا
تساعد طريقة getTestLink () في الحصول على الاتصال بين الكتل - وهي تعتمد على getConnectedLinks () ، وهي طريقة JointJS مضمنة تأخذ مدخل كتلة وتعرض صفيفًا من الروابط. في تطبيقنا ، نحن نبحث في الصفيف الناتج عن ارتباط بمنفذ ، حيث تحتوي الخاصية المصدر على قيمة portId:link = this.graph.getConnectedLinks(cell, {outbound : true}).find(item => {
return item.get('source').port === portId;
ثم ، إذا كان هناك رابط ، فقم بتمييزه:return link ? (link.toFront() && link) : null;
كود الطريقة:getTestLink(sourceCell: Cell, portId: string): Link {
let link = null;
if (sourceCell && sourceCell.id) {
let cell = null;
if (sourceCell.type === 'ScenarioStart' || sourceCell.type === 'IncomingStart') {
cell = this.getStartCell()
} else {
cell = this.graph.getCell(sourceCell.id);
}
link = this.graph.getConnectedLinks(cell, {outbound : true}).find(item => {
return item.get('source').port === portId;
});
}
return link ? (link.toFront() && link) : null;
}
يتم تنفيذ الرسوم المتحركة للكرة الجارية بالكامل عن طريق JointJS ( انظر العرض ).ننتقل إلى الكتلة الحالية
نسمي طريقة selectTestBlock () عندما يكون من الضروري تحديد الكتلة النهائية ونقل اللوحة القماشية إليها. هنا نحصل على إحداثيات مركز الكتلة:const center = cell.getBBox().center();
ثم استدعاء setTestCell () لتلوين الكتلة:editor.tester.setTestCell(cell);
أخيرًا ، قمنا بالتكبير إلى مركزه باستخدام وظيفة zoomToCell () المكتوبة ذاتيًا (وهي الأكثر إثارة للاهتمام ، ولكنها في النهاية):editor.paperController.zoomToCell(center, 1, false);
كود الطريقة:selectTestBlock(id: string): Cell {
const cell = (id === 'ScenarioStart') ? editor.tester.getStartCell() : editor.graph.getCell(id);
if (cell) {
const center = cell.getBBox().center();
editor.tester.setTestCell(cell);
editor.paperController.zoomToCell(center, 1, false);
}
return cell;
}
طريقة التلوين: اعثر على عنصر SVG من مجموعتنا وأضف فئة CSS التي تم اختبارها لجعل لون الكتلة:setTestCell(cell: Cell): void {
const view = cell.findView(this.paper);
if (view) view.el.classList.add('is-tested');
}
تكبير سلس
أخيرًا ، zoomToCell ()! يحتوي JointJS على طريقة مدمجة لتحريك اللوحة القماشية على محوري X و Y ، في البداية أرادوا أخذها. ومع ذلك ، تستخدم هذه الطريقة التحويل كسمة لعلامة SVG ؛ فهي لا تدعم الرسوم المتحركة السلسة في متصفح Firefox + وتستخدم وحدة المعالجة المركزية فقط.لقد قمنا باختراق صغير - لقد كتبنا وظيفتنا zoomToCell () ، والتي ، في جوهرها ، تفعل نفس الشيء ، ولكن يلقي التحويل على أنها CSS مضمنة ، وهذا يسمح لنا بالتصوير باستخدام GPU (لأن WebGL متصل بالعملية). وبالتالي ، يتم حل مشكلة التوافق عبر المتصفح.لا تعمل وظيفتنا على تحريك اللوحة القماشية في XY فحسب ، بل تسمح لنا أيضًا بالتكبير / التصغير في نفس الوقت من خلال استخدام مصفوفة التحويل.تخبر خاصية will-change للفئة. animate-viewport المتصفح أنه سيتم تغيير العنصر ويجب تطبيق التحسينات ، بما في ذلك استخدام GPU ، وتضبط خاصية الانتقال سلاسة نقل اللوحة إلى الكتلة:.animate-viewport {
will-change: transform;
transition: transform 0.5s ease-in-out;
كل رمز طريقتنا أدناه:public zoomToCell(center: g.Point, zoom: number, offset: boolean = true): void {
this.updateGridSize();
const currentMatrix = this.paper.layers.getAttribute('transform');
const { a, b, c, d, e, f } = this.zoomMatrix(zoom, center, offset);
this.paper.layers.style.transform = currentMatrix;
setTimeout(() => {
this.paper.layers.classList.add('animate-viewport');
this.paper.layers.style.transform = `matrix(${ a }, ${ b }, ${ c }, ${ d }, ${ e }, ${ f })`;
const duration = parseFloat(getComputedStyle(this.paper.layers)['transitionDuration']) * 1000;
setTimeout(() => {
this.paper.layers.classList.remove('animate-viewport');
this.paper.layers.style.transform = null;
this.paper.matrix(newMatrix);
this.paper.trigger('paper:zoom');
this.updateGridSize();
this.paper.trigger('paper:update');
}, duration);
}, 100);
}
كما اتضح ، في بعض الأحيان تحتاج حتى أكثرها تقدمًا إلى الانتهاء من ملف :) نأمل أن تكون قد استمتعت بالحفر داخل الحوت (بغض النظر عن مدى رعبه). نتمنى لكم تطوراً ناجحاً مع مجموعة Voximplant Kit والمزيد!