अपने PWA के लिए ब्राउज़र की नई और आने वाली सुविधाएं एक्सप्लोर करें: दिखाए गए फ़ुगु विद लव

1. शुरू करने से पहले

प्रोग्रेसिव वेब ऐप्लिकेशन (PWA), वेब के ज़रिए डिलीवर किए जाने वाले एक तरह के ऐप्लिकेशन सॉफ़्टवेयर हैं. इन्हें YouTube, सीएसएस, और JavaScript जैसी सामान्य वेब टेक्नोलॉजी की मदद से बनाया गया है. इनका इस्तेमाल ऐसे सभी प्लैटफ़ॉर्म के लिए किया जा सकता है जो स्टैंडर्ड ब्राउज़र का इस्तेमाल करते हैं.

इस कोडलैब में आप #39; बेसलाइन PWA से शुरुआत करेंगे. इसके बाद, ब्राउज़र से जुड़ी ऐसी नई क्षमताएं एक्सप्लोर करेंगे जिनसे आपका PWA सुपरपावर 🦸 मिलेगा.

ब्राउज़र में कई नई सुविधाएं फ़्लाइट के अंदर हैं और अब भी उन्हें स्टैंडर्ड बनाया जा रहा है. इसलिए, कभी-कभी आपको ब्राउज़र फ़्लैग को इस्तेमाल करने के लिए सेट करना होगा.

ज़रूरी बातें

इस कोडलैब के लिए, आपको मॉडर्न JavaScript के बारे में पता होना चाहिए. खास तौर पर, यह वादा करना चाहिए कि यह एक साथ काम नहीं करती है और न ही इसके साथ काम करती है. ऐसा इसलिए, क्योंकि कोडलैब के सभी चरण, सभी प्लैटफ़ॉर्म पर काम नहीं करते. इसलिए, अगर आपके पास ज़्यादा डिवाइस हैं, तो टेस्ट करने में मदद मिलती है. उदाहरण के लिए, आपका Android फ़ोन या लैपटॉप जिस डिवाइस पर कोड में बदलाव किया जा रहा है उससे अलग किसी ऑपरेटिंग सिस्टम का इस्तेमाल करना. असली डिवाइस के विकल्प के तौर पर, Android सिम्युलेटर या सिम्युलेटर जैसी किसी दूसरी ऑनलाइन सेवा का इस्तेमाल करके देखा जा सकता है, जो आपके मौजूदा डिवाइस की जांच करने की सुविधा देती है. इसके अलावा, आप कोई भी चरण छोड़ सकते हैं, वे एक-दूसरे पर निर्भर नहीं होते हैं.

आप क्या बनाएंगे #39;

आप ग्रीटिंग कार्ड का वेब ऐप्लिकेशन बना सकते हैं. साथ ही, यह जान सकते हैं कि नई और आने वाली ब्राउज़र सुविधाएं आपके ऐप्लिकेशन को कैसे बेहतर बना सकती हैं, ताकि कुछ खास ब्राउज़र पर यह बेहतर अनुभव दे सके. हालांकि, यह सभी आधुनिक ब्राउज़र पर काम करता है.

आप #{0/}

कोडलैब का इस्तेमाल करके आप अच्छी तरह समझ सकेंगे कि नए ब्राउज़र फ़ीचर की मदद से आप अपने वेब ऐप्लिकेशन को बेहतर तरीके से कैसे बेहतर बना सकते हैं. इसमें आपको काम नहीं करने वाले ब्राउज़र के सबसेट पर डाउनलोड का बोझ नहीं लगेगा और सबसे ज़रूरी बात यह है कि उन्हें अपने ऐप्लिकेशन से हटाएं.

आपको इनकी ज़रूरत होगी

इस समय, पूरी तरह से काम करने वाले ब्राउज़र ये हैं:

हमारा सुझाव है कि आप खास डेव चैनल का इस्तेमाल करें.

2. प्रोजेक्ट फ़ुगु

प्रगतिशील वेब ऐप्लिकेशन (PWA) को आधुनिक एपीआई की मदद से बनाया जाता है और बेहतर बनाया जाता है. इससे आप वेब पर कहीं भी, किसी भी तरह के डिवाइस का इस्तेमाल करके बेहतर तरीके से काम कर सकते हैं. साथ ही, ऐप्लिकेशन भरोसेमंद और भरोसेमंद हो सकता है. साथ ही, इंस्टॉल भी किया जा सकता है.

इनमें से कुछ एपीआई बहुत असरदार हैं. अगर इन्हें गलत तरीके से हैंडल किया जाता है, तो गड़बड़ियां हो सकती हैं. फ़ुग्यू फ़िश की तरह 🐡: जब आप इसे सही तरीके से काटते हैं, तो यह बहुत ही स्वादिष्ट होता है. हालांकि, जब आप इसे सही तरीके से काटें, तो यह खराब हो सकता है. हालांकि, चिंता न करें. यह कोडलैब में कुछ भी नहीं हो सकता.

इसलिए, प्रोजेक्ट फ़ुग्यू का नाम 'वेब कैपेसिटी' प्रोजेक्ट का अंदरूनी कोड नाम है. इस प्रोजेक्ट में शामिल कंपनियां इन नए एपीआई को डेवलप कर रही हैं.

वेब क्षमताओं को आज ही—पहले से ही बड़े और छोटे एंटरप्राइज़ को बिल्कुल सही ब्राउज़र-आधारित समाधानों पर बनाने की अनुमति देनी थी, जो कि अक्सर प्लैटफ़ॉर्म-विशिष्ट रास्ते की तुलना में कम विकास लागतों के साथ तेज़ी से डिप्लॉयमेंट की अनुमति देते थे.

3. अपनी प्रोफ़ाइल बनाना शुरू करें

इनमें से कोई भी ब्राउज़र डाउनलोड करें. इसके बाद, Chrome और Edge, दोनों पर काम करने वाले about://flags पर जाकर, रन टाइम से जुड़े इन फ़्लैग 🚩 पर सेट करें:

  • #enable-experimental-web-platform-features

इसे चालू करने के बाद, अपना ब्राउज़र रीस्टार्ट करें.

आप ग्लिच प्लैटफ़ॉर्म का इस्तेमाल करेंगे, क्योंकि इससे आप अपने PWA को होस्ट कर सकते हैं. साथ ही, इसमें बेहतरीन एडिटर भी है. ग्लिच, GitHub पर इंपोर्ट और एक्सपोर्ट करने की सुविधा भी देता है, इसलिए कोई वेंडर लॉक-इन नहीं होता. ऐप्लिकेशन को आज़माने के लिए, fugu- Paint.glitch.me पर जाएं. यह एक बुनियादी ड्रॉइंग ऐप्लिकेशन ⋅ है, जिसे आप कोडलैब के दौरान बेहतर बनाएंगे.

बड़ा सा PWA फ़ुगु ग्रीटिंग्स और एक बड़ा कैनवस, जिस पर &ldko;Google&rdqua; शब्द लिखा है.

ऐप्लिकेशन के साथ खेलने के बाद, ऐप्लिकेशन को अपनी खुद की कॉपी बनाने के लिए रीमिक्स करें, जिसमें आप बदलाव कर सकते हैं. आपके रीमिक्स का यूआरएल कुछ इस तरह दिखेगा: glitch.com/edit/#!/bouncy-candytuft (&QUt;bouncy-candytuft" कुछ और आपके लिए होगा). इस रीमिक्स को सीधे दुनिया भर में ऐक्सेस किया जा सकता है. अपने मौजूदा खाते में साइन इन करें या अपने काम को सेव करने के लिए, ग्लिच पर नया खाता बनाएं. आप &कोटेशन;🕶 शो और कोटेशन बटन पर क्लिक करके अपना ऐप्लिकेशन देख सकते हैं. साथ ही, होस्ट किए गए ऐप्लिकेशन का यूआरएल कुछ इस तरह होगा bouncy-candytuft.glitch.me (टॉप लेवल डोमेन के तौर पर .com के बजाय .me ध्यान दें).

अब आप#39;अपने ऐप्लिकेशन में बदलाव करने और उसे बेहतर बनाने के लिए तैयार हैं. जब भी आप बदलाव करेंगे, तो ऐप्लिकेशन फिर से लोड होगा और आपके बदलाव सीधे दिखेंगे.

किसी ग्लिच आईडीई में एचटीएमएल दस्तावेज़ में बदलाव करने का तरीका दिखाया जा रहा है.

नीचे दिए गए टास्क को सही तरीके से पूरा करना चाहिए, लेकिन जैसा कि ऊपर बताया गया है, अगर आपके पास सही डिवाइस का ऐक्सेस नहीं है, तो आप किसी भी चरण को छोड़ सकते हैं. याद रखें, हर टास्क को मैप, नुकसान पहुंचाने वाली ताज़े पानी की मछली या 🐡 (एक तरह का कोटेशन) के तौर पर मार्क किया जाता है. यह फ़ुग्यू फ़िश का इस्तेमाल करता है, जिससे यह पता चलता है कि यह सुविधा प्रयोग के तौर पर काम कर रही है या नहीं.

DevTools में कंसोल देखें और देखें कि इस डिवाइस पर एपीआई काम करता है या नहीं. हम ग्लिच का भी इस्तेमाल करते हैं, ताकि आप अलग-अलग डिवाइस पर एक ही ऐप्लिकेशन की जांच आसानी से कर सकें. उदाहरण के लिए, अपने मोबाइल फ़ोन और डेस्कटॉप कंप्यूटर पर.

DevTools में कंसोल के साथ काम करने वाला एपीआई काम करता है.

4. ⇨ वेब शेयर एपीआई सहायता जोड़ें

सबसे शानदार ड्रॉइंग बनाना तब उबाऊ होता है, जब कोई एक व्यक्ति की तारीफ़ भी नहीं करता. एक ऐसी सुविधा जोड़ें जिसकी मदद से आपके उपयोगकर्ता, ग्रीटिंग कार्ड के रूप में अपनी ड्रॉइंग को दुनिया के साथ शेयर कर सकें.

वेब शेयर एपीआई में, फ़ाइलें शेयर करने की सुविधा होती है. जैसा कि आपको याद होगा, File एक खास तरह का Blob है. इसलिए, share.mjs नाम वाली फ़ाइल में, शेयर करने का बटन और सुविधा फ़ंक्शन toBlob() इंपोर्ट करें. यह कैनवस के कॉन्टेंट को BLOB में बदल देता है और शेयर करने की सुविधा को नीचे दिए गए कोड के मुताबिक जोड़ें.

अगर आपने इसे लागू तो किया है, लेकिन बटन नहीं दिख रहा है, तो यह ##39; है, क्योंकि आपका ब्राउज़र वेब शेयर एपीआई को लागू नहीं करता है.

import { shareButton, toBlob } from './script.mjs';

const share = async (title, text, blob) => {
  const data = {
    files: [
      new File([blob], 'fugu-greeting.png', {
        type: blob.type,
      }),
    ],
    title: title,
    text: text,
  };
  try {
    if (!navigator.canShare(data)) {
      throw new Error("Can't share data.", data);
    }
    await navigator.share(data);
  } catch (err) {
    console.error(err.name, err.message);
  }
};

shareButton.style.display = 'block';
shareButton.addEventListener('click', async () => {
  return share('Fugu Greetings', 'From Fugu With Love', await toBlob());
});

5. ⇨ वेब शेयर टारगेट एपीआई सहायता जोड़ें

अब आपके उपयोगकर्ता, ऐप्लिकेशन का इस्तेमाल करके बनाए गए ग्रीटिंग कार्ड को शेयर कर सकते हैं. हालांकि, आप उपयोगकर्ताओं को अपने ऐप्लिकेशन से इमेज शेयर करने की अनुमति भी दे सकते हैं. साथ ही, उन्हें ग्रीटिंग कार्ड में भी बदल सकते हैं. इसके लिए, आप वेब शेयर टारगेट एपीआई का इस्तेमाल कर सकते हैं.

वेब ऐप्लिकेशन मेनिफ़ेस्ट में, आपको ऐप्लिकेशन को बताना होगा कि आप किस तरह की फ़ाइलें स्वीकार कर सकते हैं और एक या कई फ़ाइलें शेयर करने पर ब्राउज़र को कौनसा यूआरएल कॉल करना चाहिए. फ़ाइल manifest.webmanifest के नीचे का हिस्सा, यह दिखाता है.

{
  "share_target": {
    "action": "./share-target/",
    "method": "POST",
    "enctype": "multipart/form-data",
    "params": {
      "files": [
        {
          "name": "image",
          "accept": ["image/jpeg", "image/png", "image/webp", "image/gif"]
        }
      ]
    }
  }
}

इसके बाद सर्विस वर्कर, मिलने वाली फ़ाइलों से निपटता है. यूआरएल ./share-target/##39 मौजूद नहीं है. ऐप्लिकेशन सिर्फ़ fetch हैंडलर में काम करता है और क्वेरी पैरामीटर ?share-target जोड़कर, अनुरोध को रूट यूआरएल पर रीडायरेक्ट करता है:

self.addEventListener('fetch', (fetchEvent) => {
  /* 🐡 Start Web Share Target */
  if (
    fetchEvent.request.url.endsWith('/share-target/') &&
    fetchEvent.request.method === 'POST'
  ) {
    return fetchEvent.respondWith(
      (async () => {
        const formData = await fetchEvent.request.formData();
        const image = formData.get('image');
        const keys = await caches.keys();
        const mediaCache = await caches.open(
          keys.filter((key) => key.startsWith('media'))[0],
        );
        await mediaCache.put('shared-image', new Response(image));
        return Response.redirect('./?share-target', 303);
      })(),
    );
  }
  /* 🐡 End Web Share Target */

  /* ... */
});

जब ऐप्लिकेशन लोड होता है, तो यह जांच करता है कि क्या यह क्वेरी पैरामीटर सेट किया गया है. अगर ऐसा है, तो यह शेयर की गई इमेज को कैनवस पर लाता है और इसे कैश मेमोरी से मिटा देता है. यह सब script.mjs में होता है:

const restoreImageFromShare = async () => {
  const mediaCache = await getMediaCache();
  const image = await mediaCache.match('shared-image');
  if (image) {
    const blob = await image.blob();
    await drawBlob(blob);
    await mediaCache.delete('shared-image');
  }
};

इसके बाद, ऐप्लिकेशन के शुरू होने पर इस फ़ंक्शन का इस्तेमाल किया जाता है.

if (location.search.includes('share-target')) {
  restoreImageFromShare();
} else {
  drawDefaultImage();
}

6. ⇨ इंपोर्ट की गई इमेज के लिए सहायता जोड़ें

सब कुछ नए सिरे से बनाना मुश्किल है. एक ऐसी सुविधा जोड़ें जिससे आपके उपयोगकर्ता अपने डिवाइस से, ऐप्लिकेशन में स्थानीय इमेज अपलोड कर सकें.

सबसे पहले, कैनवस' drawImage() फ़ंक्शन के बारे में पढ़ें. इसके बाद, <​input
type=file>
एलिमेंट के बारे में जानें.

इस जानकारी के साथ, आप import_image_legacy.mjs नाम की फ़ाइल में बदलाव कर सकते हैं और नीचे दिया गया स्निपेट जोड़ सकते हैं. फ़ाइल के सबसे ऊपर, आप इंपोर्ट बटन और सुविधा फ़ंक्शन drawBlob() इंपोर्ट करते हैं, जिससे आप कैनवस पर BLOB को बना सकते हैं.

import { importButton, drawBlob } from './script.mjs';

const importImage = async () => {
  return new Promise((resolve) => {
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = 'image/png, image/jpeg, image/*';
    input.addEventListener('change', () => {
      const file = input.files[0];
      input.remove();
      return resolve(file);
    });
    input.click();
  });
};

importButton.style.display = 'block';
importButton.addEventListener('click', async () => {
  const file = await importImage();
  if (file) {
    await drawBlob(file);
  }
});

7. ⇨ एक्सपोर्ट इमेज सहायता जोड़ें

आपका उपयोगकर्ता, ऐप्लिकेशन में बनाई गई फ़ाइल को अपने डिवाइस पर कैसे सेव करेगा? अब तक, ऐसा <​a
download>
एलिमेंट से किया जाता है.

export_image_legacy.mjs फ़ाइल में नीचे दिए गए तरीके से कॉन्टेंट जोड़ें. एक्सपोर्ट बटन और toBlob() सुविधा फ़ंक्शन को इंपोर्ट करें, जो कैनवस के कॉन्टेंट को BLOB में बदल देता है.

import { exportButton, toBlob } from './script.mjs';

export const exportImage = async (blob) => {
  const a = document.createElement('a');
  a.download = 'fugu-greeting.png';
  a.href = URL.createObjectURL(blob);
  a.addEventListener('click', (e) => {
    a.remove();
    setTimeout(() => URL.revokeObjectURL(a.href), 30 * 1000);
  });
  setTimeout(() => a.click(), 0);
};

exportButton.style.display = 'block';
exportButton.addEventListener('click', async () => {
  exportImage(await toBlob());
});

8. ⇨ फ़ाइल सिस्टम ऐक्सेस एपीआई के लिए सहायता जोड़ें

शेयर करना बहुत आसान है, लेकिन हो सकता है कि आपके उपयोगकर्ता अपना सबसे अच्छा काम अपने डिवाइस पर ही सेव करना चाहें. एक ऐसी सुविधा जोड़ें जो आपके उपयोगकर्ताओं को उनकी ड्रॉइंग सेव करने (और फिर से खोलने) देती है.

पहले, फ़ाइलें इंपोर्ट करने के लिए, <​input type=file> लेगसी तरीके और फ़ाइलों को एक्सपोर्ट करने के लिए, <​a download> पुराने तरीके का इस्तेमाल किया जाता था. अब आप बेहतर अनुभव के लिए फ़ाइल सिस्टम ऐक्सेस एपीआई का इस्तेमाल करेंगे.

इस एपीआई से ऑपरेटिंग सिस्टम के फ़ाइल सिस्टम को खोला और सेव किया जा सकता है. नीचे दी गई सामग्री जोड़कर, import_image.mjs और export_image.mjs की दोनों फ़ाइलों में बदलाव करें. इन फ़ाइलों को लोड करने के लिए, script.mjs से 🐡 इमोजी हटाएं.

इस लाइन को बदलें:

// Remove all the emojis for this feature test to succeed.
if ('show🐡Open🐡File🐡Picker' in window) {
  /* ... */
}

...इस लाइन के साथ:

if ('showOpenFilePicker' in window) {
  /* ... */
}

import_image.mjs में:

import { importButton, drawBlob } from './script.mjs';

const importImage = async () => {
  try {
    const [handle] = await window.showOpenFilePicker({
      types: [
        {
          description: 'Image files',
          accept: {
            'image/*': ['.png', '.jpg', '.jpeg', '.avif', '.webp', '.svg'],
          },
        },
      ],
    });
    return await handle.getFile();
  } catch (err) {
    console.error(err.name, err.message);
  }
};

importButton.style.display = 'block';
importButton.addEventListener('click', async () => {
  const file = await importImage();
  if (file) {
    await drawBlob(file);
  }
});

export_image.mjs में:

import { exportButton, toBlob } from './script.mjs';

const exportImage = async () => {
  try {
    const handle = await window.showSaveFilePicker({
      suggestedName: 'fugu-greetings.png',
      types: [
        {
          description: 'Image file',
          accept: {
            'image/png': ['.png'],
          },
        },
      ],
    });
    const blob = await toBlob();
    const writable = await handle.createWritable();
    await writable.write(blob);
    await writable.close();
  } catch (err) {
    console.error(err.name, err.message);
  }
};

exportButton.style.display = 'block';
exportButton.addEventListener('click', async () => {
  await exportImage();
});

9. ⇨ संपर्क पिकर एपीआई सहायता जोड़ें

हो सकता है कि आपके उपयोगकर्ता अपने ग्रीटिंग कार्ड में कोई मैसेज जोड़ना चाहें और किसी व्यक्ति को व्यक्तिगत तौर पर निर्देश देना चाहें. एक ऐसी सुविधा जोड़ें जो आपके उपयोगकर्ताओं को अपने स्थानीय संपर्कों में से एक या एक से ज़्यादा को चुनने और शेयर मैसेज में उनके नाम जोड़ने देती है.

Android या iOS डिवाइस पर, संपर्क पिकर API आपको डिवाइस's संपर्क मैनेजर ऐप्लिकेशन से संपर्क चुनने और ऐप्लिकेशन पर वापस लौटने देता है. contacts.mjs फ़ाइल में बदलाव करें और नीचे कोड जोड़ें.

import { contactsButton, ctx, canvas } from './script.mjs';

const getContacts = async () => {
  const properties = ['name'];
  const options = { multiple: true };
  try {
    return await navigator.contacts.select(properties, options);
  } catch (err) {
    console.error(err.name, err.message);
  }
};

contactsButton.style.display = 'block';
contactsButton.addEventListener('click', async () => {
  const contacts = await getContacts();
  if (contacts) {
    ctx.font = '1em Comic Sans MS';
    contacts.forEach((contact, index) => {
      ctx.fillText(contact.name.join(), 20, 16 * ++index, canvas.width);
    });
  }
});

10. ⇨ Async क्लिपबोर्ड एपीआई सहायता जोड़ें

हो सकता है कि आपके उपयोगकर्ता, दूसरे ऐप्लिकेशन से मौजूद इमेज को अपने ऐप्लिकेशन में चिपकाना चाहें या अपने ऐप्लिकेशन से किसी ड्रॉइंग को दूसरे ऐप्लिकेशन में कॉपी करना चाहें. एक ऐसी सुविधा जोड़ें जो आपके उपयोगकर्ताओं को आपके ऐप्लिकेशन में और उससे इमेज कॉपी और पेस्ट करने की अनुमति देती है. सिंक करने वाला क्लिपबोर्ड एपीआई PNG इमेज का इस्तेमाल करता है, ताकि आप क्लिपबोर्ड पर इमेज डेटा पढ़ और लिख सकें.

clipboard.mjs फ़ाइल को खोजें और ये जोड़ें:

import { copyButton, pasteButton, toBlob, drawImage } from './script.mjs';

const copy = async (blob) => {
  try {
    await navigator.clipboard.write([
      /* global ClipboardItem */
      new ClipboardItem({
        [blob.type]: blob,
      }),
    ]);
  } catch (err) {
    console.error(err.name, err.message);
  }
};

const paste = async () => {
  try {
    const clipboardItems = await navigator.clipboard.read();
    for (const clipboardItem of clipboardItems) {
      try {
        for (const type of clipboardItem.types) {
          const blob = await clipboardItem.getType(type);
          return blob;
        }
      } catch (err) {
        console.error(err.name, err.message);
      }
    }
  } catch (err) {
    console.error(err.name, err.message);
  }
};

copyButton.style.display = 'block';
copyButton.addEventListener('click', async () => {
  await copy(await toBlob());
});

pasteButton.style.display = 'block';
pasteButton.addEventListener('click', async () => {
  const image = new Image();
  image.addEventListener('load', () => {
    drawImage(image);
  });
  image.src = URL.createObjectURL(await paste());
});

11. ⇨ बैज एपीआई के लिए सहायता जोड़ना

जब उपयोगकर्ता आपके ऐप्लिकेशन को इंस्टॉल करेंगे, तब उनकी होम स्क्रीन पर एक आइकॉन दिखेगा. आप इस आइकॉन का इस्तेमाल, मज़ेदार जानकारी देने के लिए कर सकते हैं. जैसे, किसी ड्रॉइंग की ब्रशस्ट्रोक की संख्या.

वह सुविधा जोड़ें जो बैज को तब गिनती है, जब आपका उपयोगकर्ता नया ब्रशस्ट्रोक बनाता है. बैज एपीआई ऐप्लिकेशन आइकॉन पर अंकों वाला बैज सेट करने की अनुमति देता है. pointerdown इवेंट होने पर (यानी ब्रशस्ट्रोक होने पर) बैज को अपडेट किया जा सकता है. साथ ही, कैनवस को मिटाए जाने पर बैज को रीसेट किया जा सकता है.

कोड को नीचे दी गई badge.mjs फ़ाइल में डालें:

import { canvas, clearButton } from './script.mjs';

let strokes = 0;

canvas.addEventListener('pointerdown', () => {
  navigator.setAppBadge(++strokes);
});

clearButton.addEventListener('click', () => {
  strokes = 0;
  navigator.setAppBadge(strokes);
});

12. ⇨ स्क्रीन वेक लॉक एपीआई सहायता जोड़ें

कभी-कभी आपके उपयोगकर्ताओं को कुछ समय लग सकता है, ताकि वे ड्रॉइंग बनाने के लिए दिलचस्पी दिखा सकें. इससे उन्हें प्रेरणा मिलती है. ऐसी सुविधा जोड़ें जो स्क्रीन को चालू रखती है और स्क्रीन सेवर को चालू होने से रोकती है. स्क्रीन वेक लॉक एपीआई, उपयोगकर्ता की स्क्रीन को स्लीप मोड में जाने से रोकता है. जब 'किसको दिखाई दे' इवेंट में बदलाव होता है, उसके हिसाब से 'वेक लॉक' अपने-आप रिलीज़ हो जाता है, जैसे कि पेज किसको दिखाई दे. इसलिए, पेज के वापस दिखने पर वेक लॉक की ज़रूरत फिर से होनी चाहिए.

wake_lock.mjs फ़ाइल ढूंढें और नीचे कॉन्टेंट जोड़ें. यह जांचने के लिए कि यह काम करता है या नहीं, अपने स्क्रीन सेवर को एक मिनट के बाद दिखाने के लिए कॉन्फ़िगर करें.

import { wakeLockInput, wakeLockLabel } from './script.mjs';

let wakeLock = null;

const requestWakeLock = async () => {
  try {
    wakeLock = await navigator.wakeLock.request('screen');
    wakeLock.addEventListener('release', () => {
      console.log('Wake Lock was released');
    });
    console.log('Wake Lock is active');
  } catch (err) {
    console.error(err.name, err.message);
  }
};

const handleVisibilityChange = () => {
  if (wakeLock !== null && document.visibilityState === 'visible') {
    requestWakeLock();
  }
};

document.addEventListener('visibilitychange', handleVisibilityChange);

wakeLockInput.style.display = 'block';
wakeLockLabel.style.display = 'block';
wakeLockInput.addEventListener('change', async () => {
  if (wakeLockInput.checked) {
    await requestWakeLock();
  } else {
    wakeLock.release();
  }
});

13. BrailleBack समय-समय पर बैकग्राउंड सिंक एपीआई सहायता जोड़ें

खाली कैनवस से शुरुआत करना उबाऊ हो सकता है. आप हर दिन बैकग्राउंड को सिंक करने वाले एपीआई का इस्तेमाल करके, अपने उपयोगकर्ताओं के लिए हर दिन एक नई इमेज बनाएं. उदाहरण के लिए, Unsplash's रोज़ की फ़ुगु फ़ोटो.

इसके लिए दो फ़ाइलों की ज़रूरत होती है, एक फ़ाइल periodic_background_sync.mjs जिसमें पीरियॉडिक बैकग्राउंड सिंक रजिस्टर होता है और दूसरी फ़ाइल image_of_the_day.mjs जो दिन की इमेज डाउनलोड करने का काम करती है.

periodic_background_sync.mjs में:

import { periodicBackgroundSyncButton, drawBlob } from './script.mjs';

const getPermission = async () => {
  const status = await navigator.permissions.query({
    name: 'periodic-background-sync',
  });
  return status.state === 'granted';
};

const registerPeriodicBackgroundSync = async () => {
  const registration = await navigator.serviceWorker.ready;
  try {
    registration.periodicSync.register('image-of-the-day-sync', {
      // An interval of one day.
      minInterval: 24 * 60 * 60 * 1000,
    });
  } catch (err) {
    console.error(err.name, err.message);
  }
};

navigator.serviceWorker.addEventListener('message', async (event) => {
  const fakeURL = event.data.image;
  const mediaCache = await getMediaCache();
  const response = await mediaCache.match(fakeURL);
  drawBlob(await response.blob());
});

const getMediaCache = async () => {
  const keys = await caches.keys();
  return await caches.open(keys.filter((key) => key.startsWith('media'))[0]);
};

periodicBackgroundSyncButton.style.display = 'block';
periodicBackgroundSyncButton.addEventListener('click', async () => {
  if (await getPermission()) {
    await registerPeriodicBackgroundSync();
  }
  const mediaCache = await getMediaCache();
  let blob = await mediaCache.match('./assets/background.jpg');
  if (!blob) {
    blob = await mediaCache.match('./assets/fugu_greeting_card.jpg');
  }
  drawBlob(await blob.blob());
});

image_of_the_day.mjs में:

const getImageOfTheDay = async () => {
  try {
    const fishes = ['blowfish', 'pufferfish', 'fugu'];
    const fish = fishes[Math.floor(fishes.length * Math.random())];
    const response = await fetch(`https://source.unsplash.com/daily?${fish}`);
    if (!response.ok) {
      throw new Error('Response was', response.status, response.statusText);
    }
    return await response.blob();
  } catch (err) {
    console.error(err.name, err.message);
  }
};

const getMediaCache = async () => {
  const keys = await caches.keys();
  return await caches.open(keys.filter((key) => key.startsWith('media'))[0]);
};

self.addEventListener('periodicsync', (syncEvent) => {
  if (syncEvent.tag === 'image-of-the-day-sync') {
    syncEvent.waitUntil(
      (async () => {
        try {
          const blob = await getImageOfTheDay();
          const mediaCache = await getMediaCache();
          const fakeURL = './assets/background.jpg';
          await mediaCache.put(fakeURL, new Response(blob));
          const clients = await self.clients.matchAll();
          clients.forEach((client) => {
            client.postMessage({
              image: fakeURL,
            });
          });
        } catch (err) {
          console.error(err.name, err.message);
        }
      })(),
    );
  }
});

14. आदेश के आकार की पहचान करने के लिए Google API जोड़ें

कभी-कभी आपके उपयोगकर्ता' ड्रॉइंग या इस्तेमाल की गई बैकग्राउंड की इमेज में काम की जानकारी हो सकती है, जैसे कि बारकोड. आकार की पहचान एपीआई और खास तौर पर बारकोड की पहचान करने वाले एपीआई की मदद से, आप यह जानकारी निकाल सकते हैं. एक ऐसी सुविधा जोड़ें जो आपके उपयोगकर्ताओं' ड्रॉइंग से बारकोड का पता लगाने की कोशिश करती हो. barcode.mjs फ़ाइल ढूंढें और नीचे कॉन्टेंट जोड़ें. इस सुविधा की जांच करने के लिए, कैनवस पर बारकोड वाली इमेज को लोड या पेस्ट करें. आप क्यूआर कोड के लिए इमेज खोज से एक उदाहरण बारकोड कॉपी कर सकते हैं.

/* global BarcodeDetector */
import {
  scanButton,
  clearButton,
  canvas,
  ctx,
  CANVAS_BACKGROUND,
  CANVAS_COLOR,
  floor,
} from './script.mjs';

const barcodeDetector = new BarcodeDetector();

const detectBarcodes = async (canvas) => {
  return await barcodeDetector.detect(canvas);
};

scanButton.style.display = 'block';
let seenBarcodes = [];
clearButton.addEventListener('click', () => {
  seenBarcodes = [];
});
scanButton.addEventListener('click', async () => {
  const barcodes = await detectBarcodes(canvas);
  if (barcodes.length) {
    barcodes.forEach((barcode) => {
      const rawValue = barcode.rawValue;
      if (seenBarcodes.includes(rawValue)) {
        return;
      }
      seenBarcodes.push(rawValue);
      ctx.font = '1em Comic Sans MS';
      ctx.textAlign = 'center';
      ctx.fillStyle = CANVAS_BACKGROUND;
      const boundingBox = barcode.boundingBox;
      const left = boundingBox.left;
      const top = boundingBox.top;
      const height = boundingBox.height;
      const oneThirdHeight = floor(height / 3);
      const width = boundingBox.width;
      ctx.fillRect(left, top + oneThirdHeight, width, oneThirdHeight);
      ctx.fillStyle = CANVAS_COLOR;
      ctx.fillText(
        rawValue,
        left + floor(width / 2),
        top + floor(height / 2),
        width,
      );
    });
  }
});

15. 🐡 आइडल डिटेक्शन एपीआई सहायता जोड़ें

अगर आपको लगता है कि आपका ऐप्लिकेशन किसी किओस्क जैसे सेट अप में चल रहा था, तो आप कैनवस को कुछ समय तक बंद रखने के बाद भी उसे रीसेट कर सकते हैं. इस्तेमाल न होने वाले एपीआई की पहचान करने से आप यह पता लगा सकते हैं कि उपयोगकर्ता अब अपने डिवाइस से कब इंटरैक्ट नहीं करता.

idle_detection.mjs फ़ाइल ढूंढें और उसे नीचे दिए गए कॉन्टेंट में चिपकाएं.

import { ephemeralInput, ephemeralLabel, clearCanvas } from './script.mjs';

let controller;

ephemeralInput.style.display = 'block';
ephemeralLabel.style.display = 'block';

ephemeralInput.addEventListener('change', async () => {
  if (ephemeralInput.checked) {
    const state = await IdleDetector.requestPermission();
    if (state !== 'granted') {
      ephemeralInput.checked = false;
      return alert('Idle detection permission must be granted!');
    }
    try {
      controller = new AbortController();
      const idleDetector = new IdleDetector();
      idleDetector.addEventListener('change', (e) => {
        const { userState, screenState } = e.target;
        console.log(`idle change: ${userState}, ${screenState}`);
        if (userState === 'idle') {
          clearCanvas();
        }
      });
      idleDetector.start({
        threshold: 60000,
        signal: controller.signal,
      });
    } catch (err) {
      console.error(err.name, err.message);
    }
  } else {
    console.log('Idle detection stopped.');
    controller.abort();
  }
});

16. 🐡 फ़ाइल हैंडलिंग एपीआई के लिए सहायता जोड़ें

क्या होगा अगर आपके उपयोगकर्ता किसी इमेज फ़ाइल को सिर्फ़ doubleclick कर लेते हैं और आपका ऐप्लिकेशन पॉप-अप हो सकता है? फ़ाइल मैनेज करने वाले एपीआई की मदद से आप ऐसा कर सकते हैं.

आपको #39;इमेज के लिए PWA को फ़ाइल हैंडलर के तौर पर रजिस्टर करना होगा. यह वेब ऐप्लिकेशन मेनिफ़ेस्ट में होता है, फ़ाइल manifest.webmanifest के नीचे का भाग इसे दिखाता है. (यह पहले से ही मेनिफ़ेस्ट का हिस्सा है. इसे खुद जोड़ने की ज़रूरत नहीं है.)

{
  "file_handlers": [
    {
      "action": "./",
      "accept": {
        "image/*": [".jpg", ".jpeg", ".png", ".webp", ".svg"]
      }
    }
  ]
}

खुली फ़ाइलों को मैनेज करने के लिए, नीचे दी गई फ़ाइल file-handling.mjs पर कोड जोड़ें:

import { drawBlob } from './script.mjs';

const handleLaunchFiles = () => {
  window.launchQueue.setConsumer((launchParams) => {
    if (!launchParams.files.length) {
      return;
    }
    launchParams.files.forEach(async (handle) => {
      const file = await handle.getFile();
      drawBlob(file);
    });
  });
};

handleLaunchFiles();

17. बधाई हो

🎉 वाह, आपने कर दिखाया!

Project Fugu 🐡 के संदर्भ में बहुत सारे रोमांचक ब्राउज़र एपीआई बनाए जा रहे हैं, जिससे यह कोडलैब सरफ़ेस में मुश्किल से स्क्रैच हो सकता है.

ज़्यादा जानकारी के लिए या सिर्फ़ ज़्यादा जानने के लिए, हमारी साइट web.dev पर हमारे प्रकाशनों को फ़ॉलो करें.

साइट web.dev के &ldko;Capabilities&rdqua; सेक्शन का लैंडिंग पेज.

से टैग किए गए सभी लेख

हालांकि, यह खत्म नहीं होता. जिन अपडेट को अभी तक सार्वजनिक नहीं किया गया है उनके लिए, आप हमारे Fugu API ट्रैकर को ऐक्सेस कर सकते हैं. इसमें वे सभी प्रस्ताव शामिल होते हैं जिन्हें भेज दिया गया है. साथ ही, ये उन ऑरिजिन के ट्रायल या डेवलपर के ट्रायल में शामिल हैं जिन पर काम शुरू हो चुका है. इसके अलावा, उन सभी बातों पर भी विचार किया जा रहा है जिन्हें अभी तक शुरू नहीं किया गया है.

Fugu API ट्रैकर वेबसाइट

यह कोडलैब थॉमस स्टाइनर ने लिखा है (@tomayac), मुझे'आपके सवालों का जवाब देकर खुशी होगी. हमें आपके सुझाव का इंतज़ार रहेगा! हेमंथ एच.एम (@GNUmanth), क्रिश्चियन लिएबेल (@christianlybel), स्वेन मे (@Sven उछल), लार्स शूडसेन (@larsgk), और जैकी हान (@anguokai) का धन्यवाद!