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
Tambahkan tombol clipboard kustom ke klien lokal Anda. Saat diklik, tombol ini akan membuka kotak input pop-up.
Masukkan konten yang ingin dikirim ke Cloud Phone ke dalam kotak input pop-up tersebut.
Klik tombol Paste Now pada kotak input pop-up untuk menyinkronkan konten ke clipboard dan bidang input Cloud Phone.
Prosedur
Parameter Cloud Phone
Atur
readClipboardDataByUserke true untuk mencegah SDK membaca clipboard secara otomatis.Atur
useCustomImeke 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);