Bagaimana Smartcalls menjadi Voximplant Kit - fitur rebranding dan killer


Untuk waktu yang lama kami mempersiapkan pembaruan untuk Smartcalls, editor visual untuk panggilan keluar, dan sekarang hal itu terjadi. Hari ini, di bawah potongan, kita akan berbicara tentang perubahan UI / UX dan naik di bawah kap mode demo untuk menunjukkan bagaimana kita menjinakkan JointJS .

Apa yang sebenarnya telah berubah?


Dari yang paling jelas - nama dan URL baru, yang berarti Voximplant Kit tersedia di tautan voximplant.com/kit yang sesuai . Kami juga memodifikasi halaman pendaftaran , sekarang seperti ini:

gambar

Meskipun konsepnya tetap sama, antarmuka produk telah berubah secara signifikan, menjadi lebih ramah pengguna. Menu atas bermigrasi ke kiri, yang membuat navigasi blok lebih logis dan nyaman.

gambar

Selain itu, pengelompokan dan pengurutan skrip dan rekaman audio, pencarian berdasarkan angka, serta kartu kampanye dengan informasi singkat tentang mereka, termasuk indikator baru - durasi rata-rata panggilan yang berhasil dan jumlah total yang dihabiskan, sekarang tersedia.

gambar

Adapun integrasi: antarmuka yang ramah pengguna sampai ke pengaturan mail, dan pada tab Dialogflow, SIP, Global Variables, pencarian dan pengurutan file berdasarkan ID dan host muncul.

gambar

Secara umum, banyak yang baru dan keren! Baca lebih lanjut tentang perubahan di blog kami .

Tetapi yang paling penting adalah editor


Mode Demo (spoiler: ini adalah fitur pembunuh utama).


Eksekusi skrip real-time dengan menyoroti blok yang terlibat, dan setelah eksekusi - hasil panggilan (Flow dan Log), yang membuat skrip debugging lebih mudah dan lebih cepat.

gambar

Anda dapat menonton video dari mode demo di sini atau mengujinya sendiri setelah mendaftar dengan Voximplant Kit .

Dan bagaimana ini semua diterapkan, kami akan memberi tahu di bagian selanjutnya. Fitur baru editor:

  • undo / redo (1 pada gambar di bawah);
  • tombol pintas (2);
  • menu pop-up di mana Anda dapat menyelaraskan blok dan tautan di antara mereka dengan satu klik, mengubah skala, bekerja dengan miniMap, memperluas skrip ke layar penuh, dan juga membagikannya (salin atau simpan sebagai png) (3);
  • menu konteks klik kanan;
  • menyalin blok - tidak hanya dalam skrip yang sama, tetapi juga antara skrip yang berbeda dan bahkan akun yang berbeda (!);
  • mengunci / membuka kunci blok - blok yang dikunci dapat dipindahkan, tetapi TIDAK mungkin untuk mengedit untuk menghindari perubahan yang tidak diinginkan;
  • perubahan warna - secara visual Anda dapat memilih beberapa blok "terkait";
  • cari berdasarkan nama dan isi blok yang digunakan;
  • Blok β€œmenu interaktif” - kemampuan untuk menukar port (opsi jawaban) di tempat hanya dengan menyeret dan menjatuhkan.

gambar

Kami mengungkapkan kartu


Saatnya untuk mencari tahu bagaimana animasi blok diterapkan dalam kode.


Editor memanggil metode HTTP API kami - StartScenarios - untuk menjalankan skrip cloud. Awan Voximplant memulai skrip dan memberikannya ke editor media_access_url. Mulai saat ini, editor menarik media_access_url setiap detik, menerima informasi tentang bagaimana script "berjalan" melalui blok-blok sebagai respons - berdasarkan data ini, editor menyoroti blok yang diperlukan dan menjiwai koneksi di antara mereka.

Sejarah adalah objek JSON dengan bidang-bidang berikut:

  • cap waktu;
  • idSource - blok awal;
  • idTarget - blok terakhir;
  • port - port (mungkin ada beberapa output dari 1 blok).

gambar

Dengan bantuan variabel ubahsuaian dan layanan ini, front-end memahami blok mana yang dilaluinya selama pengujian. Bagaimana dia mengerti ini? Ketika konstruksi visual terjadi (blok baru ditambahkan), segera diberikan id, yang kemudian digunakan dalam sejarah sebagai idSource / idTarget.

Untuk mengimplementasikan fungsi ini, kami menggunakan pustaka JointJS, tetapi ada beberapa kode yang ditulis sendiri.

Mari kita mulai dengan metode selectBlock () utama, ia bekerja sebagai berikut: kita pergi melalui array sejarah pergerakan (idSource, idTarget) dan segera setelah kita menemukan titik awal dan akhir, cari koneksi di antara mereka:

const link = this.editor.getTestLink(sourceCell, portId);

Jika ada koneksi di antara mereka, maka kami menghidupkan bola yang berjalan di sepanjang jalur komunikasi:
if (link) this.setLinkAnimation(link);

Metode selectBlock () dipanggil setelah setiap pembaruan this.testHistory. Karena beberapa blok yang dilewati dapat tiba di this.testHistory sekaligus, kami memanggil selectBlock sekali setiap 700 ms (ini adalah perkiraan waktu yang dihabiskan untuk menghidupkan gerakan dari blok ke blok):

setTimeout(this.selectBlock, 700);

Semua kode untuk metode ini adalah sebagai berikut. Perhatikan metode selectTestBlock dan getTestLink, baris 7 dan 10 - sekarang kita akan membicarakannya secara terpisah:

selectBlock ( ) : void {
if ( this . historyIndex < this . testHistory . length ) {
const i = ini . sejarahIndex ;
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 ) ;
}
}
lihat mentah selectBlock.js di- host dengan ❀ oleh GitHub


Buat koneksi


Metode getTestLink () membantu untuk mendapatkan koneksi antara blok - ini didasarkan pada getConnectedLinks (), metode JointJS bawaan yang mengambil input blok dan mengembalikan array tautan. Dalam implementasi kami, kami mencari di array yang dihasilkan untuk tautan dengan port, di mana properti sumber memiliki nilai portId:

link = this.graph.getConnectedLinks(cell, {outbound : true}).find(item => {
     return item.get('source').port === portId;

Lalu, jika ada tautan, maka sorot:

return link ? (link.toFront() && link) : null;

Kode Metode:

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;
}
 

Animasi bola yang berjalan diimplementasikan sepenuhnya melalui JointJS ( lihat demo ).

Kami pindah ke blok saat ini


Kami memanggil metode selectTestBlock () bila perlu untuk memilih blok terakhir dan memindahkan kanvas ke sana. Di sini kita mendapatkan koordinat tengah blok:

const center = cell.getBBox().center();

Kemudian panggil setTestCell () untuk mewarnai blok:

editor.tester.setTestCell(cell);

Akhirnya, kami memperbesar ke pusatnya menggunakan fungsi zoomToCell () yang ditulis sendiri (ini yang paling menarik, tetapi tentangnya di bagian akhir):

editor.paperController.zoomToCell(center, 1, false);

Kode Metode:

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;
}

Metode pewarnaan: temukan elemen SVG dari blok kami dan tambahkan kelas CSS .is-diuji untuk membuat warna blok:

setTestCell(cell: Cell): void {
 const view = cell.findView(this.paper);
 if (view) view.el.classList.add('is-tested');
}

Zoom halus


Akhirnya, zoomToCell ()! JointJS memiliki metode bawaan untuk memindahkan kanvas di sepanjang sumbu X dan Y, pada awalnya mereka ingin mengambilnya. Namun, metode ini menggunakan transformasi sebagai atribut dari tag SVG, itu tidak mendukung animasi yang lancar di browser Firefox + dan hanya menggunakan CPU.

Kami membuat peretasan kecil - kami menulis fungsi kami zoomToCell (), yang pada dasarnya melakukan hal yang sama, tetapi melakukan transformasi sebagai inline CSS, ini memungkinkan rendering menggunakan GPU (karena WebGL terhubung ke proses). Dengan demikian, masalah kompatibilitas lintas-browser terpecahkan.

Fungsi kami tidak hanya memindahkan kanvas dalam XY, tetapi juga memungkinkan kami untuk secara bersamaan skala (zoom) melalui penggunaan matriks transformasi.

Properti akan berubah dari .animate-viewport kelas memberitahu browser bahwa elemen akan diubah dan optimasi harus diterapkan, termasuk penggunaan GPU, dan properti transisi mengatur kelancaran memindahkan kanvas ke blok:

.animate-viewport {
 will-change: transform;
 transition: transform 0.5s ease-in-out;

Semua kode metode kami di bawah ini:

public zoomToCell(center: g.Point, zoom: number, offset: boolean = true): void {
   this.updateGridSize();
   const currentMatrix = this.paper.layers.getAttribute('transform');
   //   svg-,        center
   //   ,     style
   const { a, b, c, d, e, f } = this.zoomMatrix(zoom, center, offset);
   //  FireFox    ,       
   this.paper.layers.style.transform = currentMatrix;
   //    FF  ,     ,    
   setTimeout(() => {
     //  CSS- .animate-viewport,    - transition;
     //    style      - transition
     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;
     //        style;
     //      joint
     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);
 }

Ternyata, kadang-kadang bahkan yang paling canggih pun harus diselesaikan dengan file :) Kami harap Anda menikmati menggali bagian dalam paus (tidak peduli seberapa menyeramkan kedengarannya). Semoga Anda berhasil dalam pengembangan dengan Voximplant Kit dan banyak lagi!

All Articles