All Products
Search
Document Center

Cloud Phone:Tempel di Safari dengan Web SDK

Last Updated:Aug 28, 2026

Karena pembatasan keamanan, Safari memicu pop-up tempel native saat mengakses clipboard, yang dapat menurunkan pengalaman pengguna dalam menyinkronkan konten ke Cloud Phone. Topik ini menjelaskan cara menggunakan Web SDK untuk menempelkan teks dari clipboard lokal Anda ke Safari.

Ikhtisar solusi

  1. Tambahkan tombol clipboard kustom ke klien lokal Anda. Saat diklik, tombol ini akan membuka kotak input pop-up.

  2. Masukkan konten yang ingin dikirim ke Cloud Phone ke dalam kotak input pop-up tersebut.

  3. Klik tombol Paste Now pada kotak input pop-up untuk menyinkronkan konten ke clipboard dan bidang input Cloud Phone.

Prosedur

Parameter Cloud Phone

  • Atur readClipboardDataByUser ke true untuk mencegah SDK membaca clipboard secara otomatis.

  • Atur useCustomIme ke true untuk mengaktifkan local input method editor (IME). Ini diperlukan agar konten dapat disinkronkan ke bidang input Cloud Phone.

// Periksa apakah browser adalah Safari.
function isSafari() {
    return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
}
// Kontrol utama: Nonaktifkan pembacaan clipboard otomatis dan aktifkan IME lokal.
connConfig = {..., readClipboardDataByUser:isSafari(), useCustomIme:true}; 
var appInfo = {
  ...,
  connConfig: connConfig,
  ...
};
var sessionParam = {
  ...,
  appInfo: appInfo,
  ....
};
var wuyingSdk = Wuying.WebSDK;
session = wuyingSdk.createSession('appstream', sessionParam);
// Konfigurasi thumbnail: Aktifkan IME lokal.
this.thumbnail = new window.Wuying.ThumbnailSDK({
  ...,
  connectionConfig: {
    useCustomIme: true,
  },
},
{
  onConnected: (data) => {
    this.thumbnail.session.getLocalConfig().setClipboardEnabled(true);
  },
  onDisConnected: (data) => {},
  onThumbnailData: (url) => {},
}
);

Buat kotak input pop-up

Buat tombol clipboard yang membuka kotak input pop-up. Contoh implementasinya ditunjukkan dalam kode berikut.

function showInput() {
  showCustomDialog();
  // Tutup dialog saat overlay diklik.
  document.querySelector('.modal-overlay').addEventListener('click', function (e) {
      if (e.target === this) {
          closeModal();
      }
  });

  // Tutup dialog saat tombol Escape ditekan.
  document.addEventListener('keydown', function (e) {
      if (e.key === 'Escape') {
          closeModal();
      }
  });
}

function closeModal() {
  console.log('closeModal');
  const overlay = document.querySelector('.modal-overlay');
  if (overlay) {
      overlay.style.display = 'none';
      overlay.remove();
  }
}

function submitContent() {
  const content = document.querySelector('.input-field').value.trim();
  if (!content) {
      alert('Please enter content.');
      return;
  }
  // Sinkronkan konten ke Cloud Phone.
  sendMsgToCloudPhoneOperation(content);
  closeModal();
}

function showCustomDialog() {
  // Buat overlay modal.
  const overlay = document.createElement('div');
  overlay.className = 'modal-overlay';
  // Pastikan modal menangkap semua event dan ditampilkan di level tertinggi
  overlay.style.pointerEvents = 'all';
  overlay.style.zIndex = '9999';
  
  // Cegah event menyebar ke lapisan di bawahnya
  const stopPropagation = function(e) {
      e.stopPropagation();
  };
  
  overlay.addEventListener('contextmenu', stopPropagation, true);
  
  // Tambahkan listener event untuk mengintersepsi semua event keyboard
  overlay.addEventListener('keydown', stopPropagation, true);
  overlay.addEventListener('keyup', stopPropagation, true);
  overlay.addEventListener('keypress', stopPropagation, true);
  
  overlay.innerHTML = `
      <div class="modal">
          <div class="modal-header">
              <h2 class="modal-title">Clipboard</h2>
              <button class="close-btn" onclick="closeModal()">×</button>
          </div>
          
          <div class="input-container">
              <textarea 
                  class="input-field" 
                  placeholder="Enter content"
                  maxlength="500"
              ></textarea>
          </div>
          
          <button class="submit-btn" onclick="submitContent()">
              Paste Now
          </button>
      </div>
  `;

  document.body.appendChild(overlay);
  
  // Fokuskan textarea saat modal terbuka agar event keyboard tertangkap
  setTimeout(() => {
      const textarea = overlay.querySelector('.input-field');
      if (textarea) {
          textarea.focus();
      }
  }, 100);
}

Kirim teks ke Cloud Phone

Picu tugas sinkronisasi

function submitContent() {
  const content = document.querySelector('.input-field').value.trim();
  if (!content) {
      alert('Please enter content.');
      return;
  }
  // Sinkronkan konten ke Cloud Phone.
  sendMsgToCloudPhoneOperation(content);
  closeModal();
}

Sinkronkan konten ke Cloud Phone

function sendMsgToCloudPhoneOperation(msg) {
  // Untuk sesi kontrol utama
  if (session) {
    session.setClipboardModule('sendClipboardDataToRemote', msg) 
  }
  // Untuk sesi thumbnail
  for (const [key, value] of thumbnailSDKMap) {
      console.log('thumbnail sendMsgToCloudPhoneOperation ', key, msg);
      value.thumbnail.session.getClipboardModule().sendClipboardDataToRemote(msg);
  }
}

Catatan penggunaan

Dialog kustom harus menangkap semua event keyboard agar elemen UI lain tidak mengintersepsinya. Hal ini memastikan bahwa penekanan tombol terdaftar dengan benar di dalam dialog.

overlay.addEventListener('contextmenu', stopPropagation, true);

// Tambahkan listener event untuk mengintersepsi semua event keyboard
overlay.addEventListener('keydown', stopPropagation, true);
overlay.addEventListener('keyup', stopPropagation, true);
overlay.addEventListener('keypress', stopPropagation, true);