ساخت APK رایگان

API پل جاوااسکریپت

اجرا، میان‌برها و دکمه برگشت

نحوه باز شدن اپلیکیشن، میان‌برهای فشار طولانی روی آیکون، درخواست نقد درون‌برنامه‌ای، و گفتن به پوسته که صفحه فشار برگشت را می‌خواهد.

AppMint.requestReview کمک‌کننده#

AppMint.requestReview(options)

نمونه

از Google Play می‌خواهد برگه امتیازدهی خودش را درون اپلیکیشن نشان دهد (Play In-App Review) و به شما می‌گوید چه شد.

مقدار بازگشتی: یک Promise که همیشه با {result, openedStore, message?} حل می‌شود. result می‌تواند 'shown' باشد (Play صفحه‌اش را نشان داد - هرگز نمی‌گوید کاربر امتیاز داده یا نه)، 'not_from_play' (این نصب از Google Play نیامده است: APK نصب‌شده دستی یا نصب آزمایشی که Play در آن هرگز صفحه را نشان نمی‌دهد)، 'quota' (Play تصمیم گرفت الان آن را نشان ندهد: سهمیه‌اش برای این کاربر تمام شده یا او قبلاً نظر داده است) یا 'error' (امکان پرسیدن از Play نبود: Play Store نیست یا آفلاین است). با {openStore: true} وقتی صفحه نمایش داده نشد، صفحه‌ی برنامه در Play باز می‌شود و openedStore برابر true است. پیش‌نیاز: چیزی برای روشن کردن لازم نیست.

هر کد:

// A "Rate us" button: the sheet when Play shows it, the Play listing otherwise.
document.getElementById('rate-btn').onclick = async function () {
  if (!(window.AppMint && AppMint.requestReview)) { location.href = 'https://play.google.com/store/apps/details?id=com.example.app'; return; }
  var r = await AppMint.requestReview({ openStore: true });
  if (r.result === 'shown' || r.openedStore) showToast('Thank you!');
};

بعد از یک لحظه موفقیت به‌جای یک دکمه بپرسید، بدون اینکه هرگز اپلیکیشن را ترک کنید:

async function onOrderDelivered(count) {
  if (count !== 3 || !(window.AppMint && AppMint.requestReview)) return;
  var r = await AppMint.requestReview();      // no openStore: nothing opens if Play says no
  if (r.result === 'not_from_play') console.log('Test install: Play only shows the sheet for Play installs');
}

وقتی سازنده Ask users to rate the app (مرحله Display) را روشن کرده، اپلیکیشن خودش در یک لحظه آرام می‌پرسد و به صفحه می‌گوید چه شد:

window.addEventListener('appmint:review', function (e) {
  // e.detail = { result, openedStore: false, source: 'auto' }
  analytics.track('rate_prompt', { result: e.detail.result });
});

نکته‌ها: Google Play برگه را محدود می‌کند و خودش تصمیم می‌گیرد ظاهر شود یا نه؛ هرگز برای نقد پاداش ندهید یا برگه را روی دکمه قول ندهید. آن را با نصب از مسیر internal testing در Play آزمایش کنید - APK نصب‌شده دستی همیشه پاسخ می‌دهد not_from_play.

بدون کد: پیوند appmint://review. یک دکمه یا پیوند با این نشانی همان برگه را می‌خواهد (و وقتی Play آن را نشان نمی‌دهد صفحه Play را باز می‌کند، چون کاربر خواسته امتیاز دهد). در یک پیام درون‌برنامه‌ای آن را روی یک دکمه در مرکز ارسال بگذارید (قالب Rate us این کار را می‌کند)؛ در یک صفحه آن را به‌عنوان پیوند ساده استفاده کنید:

<a href="appmint://review" class="rate-link">Rate us on Google Play</a>

از اسکریپت، مثلاً بعد از سومین سفارش تمام‌شده:

function maybeAskForRating(ordersDone) {
  if (ordersDone === 3) location.href = 'appmint://review';   // the app runs it; nothing is loaded
}

قبل از باز شدن برگه بشنوید کاربر در یک پیام درون‌برنامه‌ای «به ما امتیاز دهید» چه چیزی انتخاب کرد:

window.addEventListener('appmint:inapp', function (e) {
  var d = e.detail;
  if (d.type === 'answered' && d.question === 'stars' && d.value <= 3) showFeedbackForm();
  if (d.type === 'clicked' && d.link === 'appmint://review') console.log('Opening the Play review sheet');
});

AppMint.setBackHandler کمک‌کننده#

AppMint.setBackHandler(handler)

نمونه

وقتی کاربر دکمه برگشت گوشی را فشار می‌دهد (یا از ژست برگشت استفاده می‌کند) اولین حرف را به صفحه شما می‌دهد. برای اپلیکیشن‌هایی لازم است که صفحه را با نمایش و پنهان کردن عناصر عوض می‌کنند، جایی که تاریخچه اندروید خالی است و برگشت از اپلیکیشن خارج می‌شود.

مقدار برگشتی: هیچ. handler شما باید true (مدیریت شد، همین‌جا بمان) یا false (بگذار اپلیکیشن برگردد / خارج شود) برگرداند. نیازمندی: هیچ. در شروع سند نصب می‌شود، پس می‌توانید در اولین اسکریپت خود ثبتش کنید.

if (window.AppMint && AppMint.setBackHandler) {
  AppMint.setBackHandler(function () {
    if (isMenuOpen)               { closeMenu();  return true; }   // consumed
    if (currentScreen !== 'home') { goTo('home'); return true; }
    return false;   // nothing to undo: normal Back (history back, exit dialog, exit)
  });
}

// Remove it again, for example when the screen that needed it closes:
// AppMint.setBackHandler(null);

رویداد appmint:back - قابل‌لغو. e.preventDefault() را فراخوانی کنید تا فشار را مصرف کنید. قبل از کنترل‌کننده اجرا می‌شود و هر تعداد شنونده می‌تواند از آن استفاده کند:

window.addEventListener('appmint:back', function (e) {
  var sheet = document.querySelector('.bottom-sheet.open');
  if (sheet) {
    sheet.classList.remove('open');
    e.preventDefault();   // consumed: the handler and the shell do nothing more
  }
});

از گم شدن یک یادداشت نیمه‌نوشته جلوگیری کنید: برگشت نوار «تغییرات دور ریخته شود؟» خودتان را نشان می‌دهد به‌جای خروج (یک confirm() مسدودکننده پنجره پاسخ ۳۵۰ میلی‌ثانیه‌ای را از دست می‌دهد و پوسته به‌هرحال برمی‌گردد):

if (window.AppMint && AppMint.setBackHandler) {
  var noteDirty = false;
  document.getElementById('note').addEventListener('input', function () { noteDirty = true; });

  AppMint.setBackHandler(function () {
    if (!noteDirty) return false;        // nothing to lose: normal Back
    showDiscardBar();                    // your in-page "Discard changes? / Keep editing" bar
    return true;                         // stay here while the user decides
  });

  document.getElementById('discard-btn').onclick = function () {
    noteDirty = false;                   // the next Back press passes straight through
    hideDiscardBar();
    closeEditor();
  };
}

نکته‌ها: پاسخ باید همزمان باشد: برگرداندن Promise یعنی «مدیریت نشد». سریع پاسخ دهید - اگر صفحه ظرف حدود ۳۵۰ میلی‌ثانیه پاسخ ندهد پوسته خودش برمی‌گردد. ترتیب در هر فشار: منوی کناری باز (کشوی خود اپلیکیشن) اول بسته می‌شود و از صفحه پرسیده نمی‌شود؛ سپس شنونده‌های appmint:back ← کنترل‌کننده شما ← بستن‌دهنده داخلی پوسته (یک <dialog> باز، دیالوگ ARIA یا مودال تمام‌صفحه را می‌بندد) ← برگشت تاریخچه / تأیید خروج / خروج. اپلیکیشن‌هایی که برای هر صفحه از history.pushState استفاده می‌کنند (React Router و مشابه) به این نیاز ندارند. اپلیکیشن‌های ساخته‌شده با هوش مصنوعی می‌توانند از onBackGesture در @/lib/appmintNative.

__pullRefreshEligible پل#

window.WebToApk.__pullRefreshEligible(eligible: Boolean)

[pullPageEligible] / [pullProbeJs] را ببینید. در هر touchstart فراخوانی می‌شود.

نمونه

پشت‌صحنه تازه‌سازی با کشیدن: probe لمس خود پوسته در هر لمس آن را فراخوانی می‌کند تا بگوید کشیدن رو به پایین آنجا باید صفحه را تازه کند یا نه. صفحه‌ها هرگز آن را فراخوانی نمی‌کنند - تازه‌سازی با کشیدن را با CSS استاندارد و رویدادهای لمس کنترل می‌کنند.

مقدار برگشتی: هیچ. نیازمندی: Enable Pull-to-Refresh هنگام ساخت در مرحله ۳ (Integrate)، زیر Display Options روشن باشد (بدون آن probe نصب نمی‌شود).

راه عمومی برای جلوگیری از رفرش شدن با کشیدن در بخشی از صفحه‌ی شما - ژست را در اختیار بگیرید:

<style>
  /* A map, drawing canvas or slider: this element owns vertical drags. */
  #map, #canvas { touch-action: none; }
  /* A horizontal carousel: pan-x also tells the shell "not a refresh". */
  .carousel { touch-action: pan-x; }
</style>

یا آن را از یک کنترل‌کننده لمس، به روش استاندارد، ادعا کنید:

document.getElementById('canvas').addEventListener('touchstart', function (e) {
  e.preventDefault();   // the page took this gesture: no pull-to-refresh
}, { passive: false });

با ادعای کشیدن‌های عمودی فقط با CSS، یک سطح حرکت و زوم را از تازه‌سازی صفحه نگه دارید:

<div id="board" style="touch-action: none; height: 60vh"></div>
<script>
  // Dragging on #board moves the board; a pull from the top of the rest of the page still refreshes.
  document.getElementById('board').addEventListener('pointermove', function (e) { moveBoard(e); });
</script>

نکته‌ها: کشیدن فقط وقتی تازه‌سازی می‌کند که نزدیک‌ترین جعبه قابل اسکرول زیر انگشت (یا خود صفحه) به بالا اسکرول شده باشد، فقط یک انگشت پایین باشد، و هیچ‌کدام از ادعاهای بالا اعمال نشود. لمس داخل iframe از مبدأ دیگر هرگز تازه‌سازی نمی‌کند. خودتان این متد را فراخوانی نکنید.

getAppIcon پل#

window.WebToApk.getAppIcon(): String

آیکون لانچر در حال استفاده: "default" یا یکی از نام‌های getAvailableIcons().

نمونه

آیکون لانچر در حال استفاده: 'default' یا یکی از نام‌های getAvailableIcons().

مقدار برگشتی: یک رشته. 'default' در ساخت بدون آیکون جایگزین.

if (window.WebToApk && WebToApk.getAppIcon) {
  const current = WebToApk.getAppIcon();          // 'default', 'Dark', …
  document.querySelectorAll('[data-icon]').forEach(el => {
    el.classList.toggle('selected', el.dataset.icon === current);
  });
}

از صفحه تنظیمات به آیکون بعدی بروید:

function nextIcon() {
  if (!(window.WebToApk && WebToApk.getAvailableIcons && WebToApk.setAppIcon)) return;
  const names = JSON.parse(WebToApk.getAvailableIcons());
  if (names.length < 2) return;                                  // no alternate icons in this build
  const next = names[(names.indexOf(WebToApk.getAppIcon()) + 1) % names.length];
  if (!WebToApk.setAppIcon(next)) alert('Could not change the icon.');
}

نام آیکون را در یک برچسب نشان دهید، یا بیرون از اپلیکیشن پنهانش کنید:

const label = document.getElementById('icon-label');
if (window.WebToApk && WebToApk.getAppIcon) {
  const name = WebToApk.getAppIcon();
  label.textContent = name === 'default' ? 'Classic icon' : name + ' icon';
} else {
  label.hidden = true;           // in a browser there is no launcher icon
}

getAvailableIcons پل#

window.WebToApk.getAvailableIcons(): String

آرایه JSON نام آیکون‌هایی که setAppIcon می‌پذیرد: اول "default"، سپس جایگزین‌های ساخت.

نمونه

نام آیکون‌هایی که setAppIcon می‌پذیرد، به‌صورت رشته آرایه JSON: اول 'default'، سپس آیکون‌های جایگزین ویزارد ساخت به ترتیب اضافه شدنشان.

مقدار برگشتی: '["default","Dark","Gold"]'، یا '["default"]' در ساخت بدون آیکون جایگزین.

یک انتخابگر آیکون بسازید:

function iconPicker(container) {
  if (!(window.WebToApk && WebToApk.getAvailableIcons)) return;
  const names = JSON.parse(WebToApk.getAvailableIcons());
  if (names.length < 2) { container.hidden = true; return; }   // nothing to choose
  const current = WebToApk.getAppIcon();
  container.innerHTML = '';
  names.forEach(name => {
    const b = document.createElement('button');
    b.textContent = name === 'default' ? 'Classic' : name;
    b.className = name === current ? 'selected' : '';
    b.onclick = () => { if (WebToApk.setAppIcon(name)) iconPicker(container); };
    container.appendChild(b);
  });
}
iconPicker(document.querySelector('#iconPicker'));

انتخابگر را در ساخت بدون آیکون جایگزین پنهان کنید:

const picker = document.getElementById('iconPicker');
let names = ['default'];
if (window.WebToApk && WebToApk.getAvailableIcons) names = JSON.parse(WebToApk.getAvailableIcons());
picker.hidden = names.length < 2;      // only 'default' means there is nothing to choose

آیکون را با تم عوض کنید:

function matchIconToTheme(dark) {
  if (!(window.WebToApk && WebToApk.getAvailableIcons && WebToApk.setAppIcon)) return;
  const names = JSON.parse(WebToApk.getAvailableIcons());
  const wanted = dark ? 'Dark' : 'default';
  if (names.includes(wanted) && WebToApk.getAppIcon() !== wanted) WebToApk.setAppIcon(wanted);
}
matchIconToTheme(matchMedia('(prefers-color-scheme: dark)').matches);

getLaunchUrl پل#

window.WebToApk.getLaunchUrl(): String

پیوند عمیقی که این اپلیکیشن را اجرا یا از سر گرفته، یا "" اگر عادی باز شده. هر وقت اپلیکیشن سوار شد آن را بخوانید و خودتان مسیریابی کنید: const u = window.WebToApk?.getLaunchUrl?.(); if (u) router.navigate(new URL(u).pathname); مقدار نگه داشته می‌شود، مصرف نمی‌شود، پس اپلیکیشنی که دیر سوار می‌شود هم آن را می‌بیند؛ پیوند بعدی که هنگام اجرا برسد جایگزینش می‌کند و 'appmint:deep-link'.

نمونه

پیوند عمیقی که اپلیکیشن را باز کرده (یا دوباره باز کرده)، به‌صورت رشته، یا "" وقتی اپلیکیشن عادی باز شده.

مقدار برگشتی: یک رشته، به‌صورت همزمان. نیازمندی: هیچ. مقدار نگه داشته می‌شود، مصرف نمی‌شود، پس خواندنش هر وقت اپلیکیشن سوار شد امن است.

یک پیوند می‌تواند در سه شکل برسد: https://yoursite.com/path، appmint-shortcut://<package>/<route> خود پوسته (میان‌برهای لانچر، ویجت صفحه اصلی)، یا طرح سفارشی شما myapp://segment/path. این کمکی هر سه را به یک مسیر تبدیل می‌کند:

function routeOf(link) {
  var m = /^([a-z][a-z0-9+.-]*):\/\/([^\/?#]*)([^#]*)/i.exec(link || '');
  if (!m) return '/';
  var scheme = m[1].toLowerCase(), host = m[2], rest = m[3] || '';
  if (scheme === 'http' || scheme === 'https' || scheme === 'appmint-shortcut') return rest || '/';
  return '/' + host + rest;               // myapp://product/42 -> /product/42
}

// 1. On start: the link that launched the app.
if (window.WebToApk && typeof window.WebToApk.getLaunchUrl === 'function') {
  var link = window.WebToApk.getLaunchUrl();
  if (link) goTo(routeOf(link));
}

// 2. While running: a new link replaces the old one and fires 'appmint:deep-link'.
window.addEventListener('appmint:deep-link', function (e) {
  goTo(routeOf(e.detail.url));            // detail: { url }
});

همین اعلان به یک hook سراسری هم داده می‌شود، اگر یکی را ترجیح می‌دهید:

window.onAppMintDeepLink = function (detail) { goTo(routeOf(detail.url)); };

یک کد معرفی را از پیوندی مثل https://yoursite.com/invite?code=AB12 یا myapp://invite?code=AB12 بخوانید، برای هر پیوند یک بار (از routeOf بالا استفاده می‌کند):

function applyInvite(link) {
  if (!link) return;
  var done = '';
  try { done = sessionStorage.getItem('handledLink') || ''; } catch (e) {}
  if (link === done) return;                      // the same url is announced again after a reload
  try { sessionStorage.setItem('handledLink', link); } catch (e) {}
  var code = null;
  try { code = new URL(link).searchParams.get('code'); } catch (e) { return; }
  if (code && routeOf(link).indexOf('/invite') === 0) showInviteBanner(code);
}

if (window.WebToApk && typeof window.WebToApk.getLaunchUrl === 'function') {
  applyInvite(window.WebToApk.getLaunchUrl());
  window.addEventListener('appmint:deep-link', function (e) { applyInvite(e.detail.url); });
}

نکته‌ها: appmint:deep-link بعد از هر بار بارگذاری صفحه نیز، تا زمانی که لینک نگه داشته شده، ارسال می‌شود؛ پس یک url یکسان ممکن است بیش از یک بار برسد. لینکی را که قبلاً پردازش کرده‌اید نادیده بگیرید.

اپلیکیشن‌های حالت وب‌سایت فرق دارند: خود پوسته یک پیوند https:// ورودی را بارگذاری می‌کند (هنگام شروع سرد و هنگام اجرا)، و پیوند طرح سفارشی myapp://product/42 اول روی نشانی سایت شما بازنویسی می‌شود (https://yoursite.com/product/42)، پس getLaunchUrl() شکل https:// را برمی‌گرداند و صفحه شما معمولاً چیزی برای مسیریابی ندارد. ضربه میان‌بر لانچر یا ویجت مسیرش را روی سایت شما باز می‌کند (/today مقدار https://yoursite.com/today را بارگذاری می‌کند)، و getLaunchUrl() همچنان شکل appmint-shortcut:// را برمی‌گرداند (setAppShortcuts را ببینید). در اپلیکیشن‌های HTML، ZIP و ساخته‌شده با هوش مصنوعی (که از داخل اپلیکیشن سرو می‌شوند) پوسته هرگز ناوبری نمی‌کند: صفحه شما پیوند را می‌گیرد و روی آن مسیریابی می‌کند. پیوند طرح سفارشی همان‌طور که رسیده می‌ماند، چون نشانی سایتی برای نگاشت نیست. اپلیکیشن‌های ساخته‌شده با هوش مصنوعی می‌توانند از launchUrl() در @/lib/appmintNative.

rateApp پل#

window.WebToApk.rateApp(): String

جریان امتیازدهی صفحه Play را باز می‌کند. `rateApp()` از قبل بود اما فقط مورد بومی کشو می‌توانست به آن برسد، پس اپلیکیشنی که UI خودش را رسم می‌کند - هر ساخت هوش مصنوعی، که کشو خاموش است - راهی برای درخواست امتیاز نداشت. این تنها اقدام فروشگاهی است که صفحه واقعاً نمی‌تواند خودش انجام دهد: `market://` یک intent است، نه URL قابل ناوبری. مثل مورد کشو و مورد اشتراک‌گذاری نوار ناوبری پایین، با کلید «Rate App Button» خود سازنده کنترل می‌شود: خاموش کردن Rate باید یعنی هیچ سطح امتیازدهی‌ای در هیچ‌جا نباشد، وگرنه کلید خراب به نظر می‌رسد.

نمونه

صفحه‌ی برنامه در Google Play را باز می‌کند تا کاربر بتواند به آن امتیاز بدهد.

مقدار برگشتی: 'opened' وقتی صفحه باز شد، 'off' وقتی سازنده «Rate App» را خاموش کرده (آن‌وقت چیزی نمی‌شود). نیازمندی: کلید Rate App Button در مرحله ۵ (Menu) هنگام ساخت (به‌طور پیش‌فرض روشن است؛ یک مورد «Rate App» هم به منوی کناری اضافه می‌کند). با خاموش بودن، فراخوانی کاری نمی‌کند و 'off' برمی‌گرداند. برای برگه امتیازدهی درون‌برنامه‌ای Google Play از AppMint.requestReview().

var rateBtn = document.getElementById('rate-btn');
if (window.WebToApk && typeof window.WebToApk.rateApp === 'function') {
  rateBtn.onclick = function () { window.WebToApk.rateApp(); };
} else {
  rateBtn.hidden = true;   // in a browser
}

امتیازدهی را یک بار پیشنهاد دهید، بعد از اینکه کاربر پنج تمرین را تمام کرد، از کارتی که روی آن ضربه می‌زند:

function maybeOfferRating(completedCount) {
  if (!window.WebToApk || typeof window.WebToApk.rateApp !== 'function') return;
  var asked = false;
  try { asked = localStorage.getItem('rateAsked') === '1'; } catch (e) {}
  if (asked || completedCount < 5) return;

  var card = document.getElementById('rate-card');   // "Enjoying the app? Rate it on Google Play"
  card.hidden = false;
  card.querySelector('.rate-yes').onclick = function () {
    window.WebToApk.rateApp();                         // opens the Play listing
    try { localStorage.setItem('rateAsked', '1'); } catch (e) {}
    card.hidden = true;
  };
  card.querySelector('.rate-later').onclick = function () { card.hidden = true; };
}

یک ردیف «به ما امتیاز دهید» در صفحه تنظیمات شما که وقتی کاربر از Google Play برمی‌گردد تشکر می‌کند (برگشت صفحه به پیش‌زمینه تنها نشانه برگشتن کاربر است):

document.getElementById('settings-rate').onclick = function () {
  if (!window.WebToApk || typeof window.WebToApk.rateApp !== 'function') return;
  window.WebToApk.rateApp();
  document.addEventListener('visibilitychange', function onBack() {
    if (document.visibilityState !== 'visible') return;
    document.removeEventListener('visibilitychange', onBack);
    showToast('Thanks for taking a look!');           // your own toast; the user may not have rated
  });
};

نکته‌ها: صفحه‌ی برنامه را در Play Store باز می‌کند (market://details?id=<package>) یا وقتی برنامه‌ی Play Store نیست، وب‌سایت Play را. این کارت نظرسنجی درون‌برنامه‌ای نیست. یک صفحه نمی‌تواند خودِ market:// را باز کند - این یک intent اندروید است، نه آدرس وب. فقط بعد از کاری که کاربر از آن راضی بوده و با یک ضربه، درخواست کنید.

requestReview پل#

window.WebToApk.requestReview(optionsJson: String, callbackId: String)

صفحه‌ی نظرسنجی Play را درخواست می‌کند؛ [optionsJson] `{openStore?}`. با AppMint.requestReview [callbackId] حل می‌شود.

نمونه

پشت‌صحنه AppMint.requestReview() - صفحه‌ها از آن کمکی Promise استفاده می‌کنند که از Google Play برگه نقد درون‌برنامه‌ای‌اش را می‌خواهد و با آنچه رخ داد حل می‌شود.

مقدار برگشتی: مستقیماً چیزی؛ نتیجه وعده AppMint.requestReview() را حل می‌کند. نیازمندی: چیزی برای روشن کردن نیست. برگه فقط برای اپلیکیشن نصب‌شده از Google Play ظاهر می‌شود.

API عمومی:

async function askForRating() {
  if (!(window.AppMint && AppMint.requestReview)) return;          // a browser: no store here
  var r = await AppMint.requestReview();
  console.log(r.result);   // 'shown' | 'not_from_play' | 'quota' | 'error'
}

بعد از یک لحظه خوب بپرسید، و وقتی برگه ظاهر نمی‌شود صفحه فروشگاه را بخواهید:

async function afterHappyMoment() {
  if (!(window.AppMint && AppMint.requestReview)) return;
  const r = await AppMint.requestReview({ openStore: true });   // {result, openedStore, message?}
  if (r.result === 'shown') thankUser();
  else if (r.openedStore) console.log('Opened the Play listing instead');
}

به درخواست خودکار گوش دهید و خطا را گزارش کنید:

window.addEventListener('appmint:review', (e) => {
  if (e.detail.source === 'auto') console.log('Rate prompt result:', e.detail.result);
});

AppMint.requestReview().then((r) => {
  if (r.result === 'error') console.warn(r.message);
  if (r.result === 'not_from_play') showMessage('Rating is available once the app is installed from Google Play.');
});

setAppIcon پل#

window.WebToApk.setAppIcon(name: String): Boolean

آیکون لانچر اپلیکیشن را به یکی از آیکون‌های جایگزین اضافه‌شده در ویزارد ساخت تغییر می‌دهد، با نامی که آنجا داده شده ("default" = آیکون عادی). برای نامی که این ساخت ندارد false برمی‌گرداند. لانچر در زمان خودش دوباره رسم می‌کند (در برخی گوشی‌ها چند ثانیه)، و برخی لانچرها وقتی تغییر می‌کند اپلیکیشن را می‌بندند یا آیکون صفحه اصلی را جابه‌جا می‌کنند - از صفحه تنظیمات تغییر دهید، نه وسط یک کار.

نمونه

آیکون لانچر اپلیکیشن را به یکی از آیکون‌های جایگزین اضافه‌شده در ویزارد ساخت (مرحله Basic، «Alternate app icons») تغییر می‌دهد، با نامی که آنجا داده‌اید. 'default' آیکون عادی شماست.

مقدار برگشتی: true وقتی تغییر انجام شد (یا از قبل همان آیکون است)، false برای نامی که این ساخت ندارد. نیازمندی: آیکون‌های جایگزین اضافه‌شده در ویزارد (تا ۴). برخی لانچرها چند ثانیه طول می‌کشد تا آیکون را دوباره رسم کنند، و چند تا وقتی تغییر می‌کند اپلیکیشن را می‌بندند یا میان‌بر صفحه اصلی را جابه‌جا می‌کنند: از صفحه تنظیمات تغییر دهید، نه وسط یک کار. میان‌برهای لانچر شما (setAppShortcuts) به‌طور خودکار زیر آیکون جدید دوباره منتشر می‌شوند.

function useIcon(name) {
  if (!(window.WebToApk && window.WebToApk.setAppIcon)) return false;
  const ok = WebToApk.setAppIcon(name);
  if (!ok) console.warn('no icon called', name);
  return ok;
}

document.querySelector('#darkIcon').addEventListener('click', () => useIcon('Dark'));
document.querySelector('#normalIcon').addEventListener('click', () => useIcon('default'));

انتخابگر را از آیکون‌هایی که این ساخت دارد بسازید:

if (window.WebToApk && WebToApk.getAvailableIcons) {
  const names = JSON.parse(WebToApk.getAvailableIcons());   // 'default' first, then your alternates
  const current = WebToApk.getAppIcon();
  names.forEach((n) => addRadio('icon', n, n === current, () => WebToApk.setAppIcon(n)));
}

پاسخ را برای نامی که ساخت ندارد بررسی کنید:

function pickIcon(name) {
  if (!(window.WebToApk && WebToApk.setAppIcon)) return showMessage('Icons can be changed in the app only');
  if (!WebToApk.setAppIcon(name)) {
    showMessage('Unknown icon "' + name + '". Choose one of: ' + JSON.parse(WebToApk.getAvailableIcons()).join(', '));
  } else {
    showMessage('Done. Your launcher may take a few seconds to redraw the icon.');
  }
}

نکته‌ها: اولین به‌روزرسانی که آیکون جایگزین اضافه می‌کند ورودی لانچر را به یک مؤلفه جدید می‌برد، پس ممکن است لازم باشد میان‌بر صفحه اصلی ساخته‌شده قبل از آن به‌روزرسانی دوباره گذاشته شود.

setAppShortcuts پل#

window.WebToApk.setAppShortcuts(itemsJson: String)

میان‌برهای لانچر (فشار طولانی روی آیکون اپلیکیشن). تا چهار مورد: `[{id, title, route}]`، که `route` مسیری در اپلیکیشن است ('/new-note'). یک ضربه اپلیکیشن را با آن مسیر به‌عنوان پیوند عمیق اجرا باز می‌کند (`appmint-shortcut://<package><route>`)، که صفحه از طریق `getLaunchUrl()` می‌خواند و دقیقاً مثل هر پیوند عمیق دیگر روی آن مسیریابی می‌کند. در اپلیکیشن حالت وب‌سایت خود پوسته مسیر را روی وب‌سایت باز می‌کند (`/new-note` ← `https://<site>/new-note`). برای حذف آن‌ها `[]` بدهید. اندروید ۷٫۱+؛ زیر آن بی‌اثر است.

نمونه

میان‌برهای لانچر را تنظیم می‌کند که وقتی کاربر آیکون اپلیکیشن را لمس کرده و نگه می‌دارد ظاهر می‌شوند.

مقدار برگشتی: هیچ. نیازمندی: هیچ. اندروید ۷٫۱+ (زیر آن بی‌اثر است).

itemsJson یک رشته JSON است: آرایه‌ای از حداکثر چهار شیء {id, title, route}. route مسیری داخل اپلیکیشن شماست. یک ضربه اپلیکیشن را با appmint-shortcut://<package><route> به‌عنوان پیوند اجرا باز می‌کند:

if (window.WebToApk && typeof window.WebToApk.setAppShortcuts === 'function') {
  window.WebToApk.setAppShortcuts(JSON.stringify([
    { id: 'new-note', title: 'New note', route: '/new-note' },
    { id: 'search',   title: 'Search',   route: '/search' }
  ]));
}

ضربه را مثل هر پیوند عمیق دیگر بخوانید، هنگام شروع و هنگام اجرا:

function shortcutRoute(link) {
  var m = /^appmint-shortcut:\/\/[^\/?#]*([^#]*)/i.exec(link || '');
  return m ? (m[1] || '/') : null;
}
if (window.WebToApk && window.WebToApk.getLaunchUrl) {
  var r = shortcutRoute(window.WebToApk.getLaunchUrl());
  if (r) goTo(r);
}
window.addEventListener('appmint:deep-link', function (e) {
  var r = shortcutRoute(e.detail.url);
  if (r) goTo(r);
});

همه میان‌برها را حذف کنید:

if (window.WebToApk && window.WebToApk.setAppShortcuts) window.WebToApk.setAppShortcuts('[]');

نکته‌ها: هر فراخوانی کل فهرست را جایگزین می‌کند. ورودی‌های بدون title نادیده گرفته می‌شوند؛ برچسب به 25 نویسه کوتاه می‌شود (برای برچسب بلند 50). مقدار پیش‌فرض id برابر appmint-<index> است. به مسیری که / ابتدایی ندارد، یکی اضافه می‌شود. آیکون همان آیکون برنامه است. فهرست نادرست نادیده گرفته می‌شود (ثبت می‌شود)، هرگز خطا نمی‌دهد. برنامه‌های ساخته‌شده با هوش مصنوعی می‌توانند از shortcuts در @/lib/appmintNative استفاده کنند. برنامه‌های حالت وب‌سایت: با یک ضربه مسیر در وب‌سایت شما باز می‌شود - /new-note آدرس https://<your site>/new-note را بارگذاری می‌کند - و getLaunchUrl() همچنان لینک appmint-shortcut:// را برمی‌گرداند، پس صفحه‌ای که خودش مسیریابی می‌کند به کار خود ادامه می‌دهد.