Excalidraw وFugu: تحسين تجربة المستخدم الأساسية

لا يمكن تمييز أي تقنية متقدمة بما يكفي عن السحر. ما لم تفهم ذلك. اسمي توماس شتاينر، وأعمل في قسم علاقات المطوّرين في Google. ومن خلال كتابة محادثتي في مؤتمر Google I/O، سألقي نظرة على بعض واجهات برمجة تطبيقات Fugu API الجديدة وكيفية تحسينها لتجارب المستخدمين الأساسية في تطبيق ExcaliDraw PWA، وذلك لاستلهام الأفكار من هذه الأفكار وتطبيقها على تطبيقاتك.

كيف جئت إلى ExcaliDraw

أريد أن أبدأ بقصة. في 1 يناير 2020، كريستوفر تشيدو، مهندس برمجيات في Facebook، نشر تغريدة عن تطبيق رسم صغير كان يملكه بدأت في العمل عليها. وباستخدام هذه الأداة، يمكنك رسم مربعات وأسهم ذات طابع كرتوني برسم اليد. وفي اليوم التالي، يمكنك أيضًا رسم علامات حذف ونصوص، وتحديد عناصر ونقلها. حولها. في 3 كانون الثاني (يناير)، حصل التطبيق على اسمه ExcaliDraw، وحصل على العديد من الميزات المفيدة. كان شراء اسم النطاق من أولى أعمال كريستوفر. من الآن، يمكنك استخدام الألوان وتصدير الرسم بأكمله كملف PNG.

لقطة شاشة لتطبيق النموذج الأوّلي ExcaliDraw توضح أنه يدعم المستطيلات والأسهم والأشكال البيضاوية والنص.

في 15 يناير، وضع كريستوفر مشاركة مدونة جذبت الكثير من الاهتمام على Twitter، بما في ذلك أنا. بدأت المشاركة ببعض الإحصاءات المثيرة للإعجاب:

  • 12 ألف مستخدم نشط فريد
  • 1.5 ألف نجمة على GitHub
  • 26 مساهمًا

بالنسبة للمشروع الذي بدأ منذ أسبوعين فقط، فإن هذا ليس سيئًا على الإطلاق. لكن الشيء الذي زاد اهتمامي بالمنشور أكثر من ذلك. كتب كريستوفر أنه جرب شيئًا جديدًا هذا الوقت: منح كل المستخدمين الذين قدّموا طلب السحب إمكانية الوصول غير المشروط إلى البيانات نفس يوم كنت أقرأ مشاركة المدونة، تلقيت طلب سحب لأعلى التي أضافت دعم واجهة برمجة التطبيقات File System Access API إلى ExcaliDraw، ما يؤدي إلى إصلاح طلب ميزة قدّمه مستخدم

لقطة شاشة للتغريدة حيث أعلن عن العلاقات العامة

تم دمج طلب السحب بعد يوم واحد، وبعد ذلك، تمكنتُ من الوصول الكامل. لا حاجة للقول، لم أإساءة استخدامي للقوة. ولم يحصل حتى الآن على أي جهة أخرى من المساهمين البالغ عددهم 149 مساهمًا.

اليوم، Excali draw هو تطبيق ويب تقدّمي شامل وقابل للتثبيت مزوّد تتوفر إمكانية فتح الملفات وحفظها بلا اتصال بالإنترنت، فضلاً عن الوضع الداكن المذهل، فضلاً عن إمكانية فتح الملفات وحفظها. واجهة برمجة التطبيقات File System Access API

لقطة شاشة لتطبيق الويب التقدّمي Excali draw في الوقت الحالي.

"لابيس" عن سبب تخصيص الكثير من وقته لتطبيق ExcaliDraw

لقد وصلت إلى نهاية فيديو "كيف جئت إلى تطبيق ExcaliDraw". القصة، ولكن قبل أن أتعمق في بعض يسرّني أن أقدّم لكم لعبة Panayiotis بفضل ميزات Excali draw الرائعة. بانيوتيس ليبيريديس، في شبكة الإنترنت التي تُعرف ببساطة باسم lipis، هي أكثر المساهمين انتشارًا في استكشِف المسارات. سألت ليبيس ما الذي يحفزه على تخصيص الكثير من وقته لتطبيق ExcaliDraw:

ومثل أي شخص آخر تعرفت على هذا المشروع من تغريدة كريستوفر. مساهمةي الأولى هو إضافة مكتبة الألوان المفتوحة، وهي الألوان التي لا تزال كجزء من ExcaliDraw اليوم. ومع نمو المشروع وتلقينا العديد من الطلبات، ازداد المساهمة في إنشاء خلفية لتخزين الرسومات بحيث يمكن للمستخدمين مشاركتها. ولكن ماذا: تدفعني حقًا إلى المشاركة، أن كل من يجرّب تطبيق Excali draw يسعى إلى إيجاد الأعذار لاستخدامه. مرة أخرى.

أتفق تمامًا مع lipis. يريد كل مَن حاول استخدام تطبيق ExcaliDraw العثور على الأعذار لاستخدامه مجددًا.

ألعاب الالتقاط بشكل عملي

أود أن أوضح لك الآن كيفية استخدام ExcaliDraw عمليًا. لست فنانًا رائعًا، ولكن شعار مؤتمر Google I/O بسيط بدرجة كافية، لذا سأحاول تجربته. المربع هو "i"، ويمكن أن يكون الخط والشرطة المائلة و"o" عبارة عن دائرة. اضغط مع الاستمرار على shift للحصول على دائرة مثالية. اسمحوا لي أن أتحرك الشرطة المائلة قليلاً، حتى تبدو أفضل. الآن بعض ألوان "i" و"o". اللون الأزرق جيد. ربما بنمط تعبئة مختلف؟ هل هي ذات إطارات ثابتة أم ذات إطارات متقاطعة؟ لا، يبدو أن هاشير رائع. إنه ليس مثاليًا، لكنه هذه فكرة ExcaliDraw، لذا اسمح لي بحفظها.

أنقر فوق أيقونة الحفظ وأدخل اسم ملف في مربع حوار حفظ الملف. في Chrome، وهو متصفح واجهة برمجة تطبيقات File System Access API، فإن هذه ليست عملية تنزيل، بل عملية حفظ حقيقية، حيث يمكنني اختيار مكان الملف واسمه، وأين يمكنني إجراء تعديلات لحفظها في نفس الملف.

اسمحوا لي أن أغير الشعار وأجعل "i" أحمر إذا نقرت الآن على حفظ مرة أخرى، يتم حفظ التعديل في نفس الملف كما كان من قبل. كدليل على ذلك، اسمح لي بمحو اللوحة وإعادة فتح الملف. كما ترى، الشعار الأحمر والأزرق المعدّل هناك مرة أخرى.

التعامل مع الملفات

في المتصفحات التي لا تتيح حاليًا واجهة برمجة تطبيقات File System Access API، تُعتبر كل عملية حفظ تنزيل، لذا عندما أقوم بإجراء تغييرات، ينتهي بي الأمر إلى الحصول على عدة ملفات بعدد متزايد في اسم ملف يملأ مجلد التنزيلات. ولكن بالرغم من هذا الجانب السلبي، لا يزال بإمكاني حفظ الملف.

فتح الملفات

إذن ما هو السر؟ كيف يعمل الفتح والحفظ على متصفحات مختلفة قد لا تعمل واجهة برمجة التطبيقات File System Access API؟ يحدث فتح ملف في ExcaliDraw في دالة تُسمى loadFromJSON)()، والتي بدورها تستدعي دالة تُسمى fileOpen().

export const loadFromJSON = async (localAppState: AppState) => {
  const blob = await fileOpen({
    description: 'Excalidraw files',
    extensions: ['.json', '.excalidraw', '.png', '.svg'],
    mimeTypes: ['application/json', 'image/png', 'image/svg+xml'],
  });
  return loadFromBlob(blob, localAppState);
};

إن الدالة fileOpen() التي تأتي من مكتبة صغيرة كتبتها تسمى browser-fs-access التي نستخدمها في استكشِف المسارات. توفر هذه المكتبة الوصول إلى نظام الملفات من خلال File System Access API: احتياطي قديم، لكي يتم استخدامه في أي المتصفح.

سأوضّح لك أولاً طريقة تنفيذ واجهة برمجة التطبيقات. بعد التفاوض على لامتدادات الملفات وأنواع MIME المقبولة، يستدعي الجزء المركزي واجهة برمجة تطبيقات File System Access API الدالة showOpenFilePicker(). تعرض هذه الدالة صفيفًا من الملفات أو ملفًا واحدًا اعتمادًا على حول ما إذا كان سيتم تحديد ملفات متعددة. كل ما تبقى هو وضع مؤشر الملف على الملف وبالتالي يمكن استرداده مرة أخرى.

export default async (options = {}) => {
  const accept = {};
  // Not shown: deal with extensions and MIME types.
  const handleOrHandles = await window.showOpenFilePicker({
    types: [
      {
        description: options.description || '',
        accept: accept,
      },
    ],
    multiple: options.multiple || false,
  });
  const files = await Promise.all(handleOrHandles.map(getFileWithHandle));
  if (options.multiple) return files;
  return files[0];
  const getFileWithHandle = async (handle) => {
    const file = await handle.getFile();
    file.handle = handle;
    return file;
  };
};

ويعتمد التنفيذ الاحتياطي على عنصر input من النوع "file". بعد التفاوض على أنواع وإضافات MIME التي سيتم قبولها، فإن الخطوة التالية هي النقر على الإدخال آليًا العنصر حتى يظهر مربع حوار فتح الملف. عند التغيير، أي عندما يختار المستخدم واحدًا أو ملفات متعددة، يتم حل الوعد.

export default async (options = {}) => {
  return new Promise((resolve) => {
    const input = document.createElement('input');
    input.type = 'file';
    const accept = [
      ...(options.mimeTypes ? options.mimeTypes : []),
      options.extensions ? options.extensions : [],
    ].join();
    input.multiple = options.multiple || false;
    input.accept = accept || '*/*';
    input.addEventListener('change', () => {
      resolve(input.multiple ? Array.from(input.files) : input.files[0]);
    });
    input.click();
  });
};

حفظ الملفات

والآن، لننتقل إلى الحفظ. في ExcaliDraw، يحدث الحفظ في دالة تُسمى saveAsJSON(). الهدف الأول تسلسل مصفوفة عناصر Excali draw إلى JSON، وتحويل JSON إلى كائن ثنائي كبير (blob)، ثم استدعاء الدالة تسمى fileSave(). وبالمثل، يتم توفير هذه الدالة بواسطة browser-fs-access.

export const saveAsJSON = async (
  elements: readonly ExcalidrawElement[],
  appState: AppState,
) => {
  const serialized = serializeAsJSON(elements, appState);
  const blob = new Blob([serialized], {
    type: 'application/vnd.excalidraw+json',
  });
  const fileHandle = await fileSave(
    blob,
    {
      fileName: appState.name,
      description: 'Excalidraw file',
      extensions: ['.excalidraw'],
    },
    appState.fileHandle,
  );
  return { fileHandle };
};

سألقي نظرة أولاً على طريقة تنفيذ المتصفّحات التي تتوافق مع File System Access API. تشير رسالة الأشكال البيانية يبدو الخطان الأوّلان معقدَين بعض الشيء، ولكن كل ما يفعلونه هو التفاوض بشأن أنواع MIME وملفاته الإضافات. إذا سبق لي الحفظ من قبل ولديك بالفعل مؤشر ملفات، فلا حاجة إلى حفظ مربع حوار الحفظ كما هو موضح. ولكن إذا كانت هذه هي عملية الحفظ الأولى، يتم عرض مربع حوار الملف ويحصل التطبيق على اسم معرِّف للملف لاستخدامها في المستقبل. والباقي بعد ذلك تتم الكتابة في الملف، وهو ما يحدث من خلال بث قابل للكتابة.

export default async (blob, options = {}, handle = null) => {
  options.fileName = options.fileName || 'Untitled';
  const accept = {};
  // Not shown: deal with extensions and MIME types.
  handle =
    handle ||
    (await window.showSaveFilePicker({
      suggestedName: options.fileName,
      types: [
        {
          description: options.description || '',
          accept: accept,
        },
      ],
    }));
  const writable = await handle.createWritable();
  await writable.write(blob);
  await writable.close();
  return handle;
};

يعمل الخيار "حفظ باسم" ميزة

إذا قررت تجاهل مؤشر ملف موجود بالفعل، فيمكنني تنفيذ الإعداد "حفظ باسم" ميزة لإنشاء ملف جديد بناءً على ملف حالي. لعرض ذلك، دعني أفتح ملفًا حاليًا، وأقوم بعمل بعض عن طريق التعديل، ثم لا تستبدل الملف الحالي، ولكن أنشئ ملفًا جديدًا باستخدام الطريقة "حفظ باسم" الجديدة. وهذا يترك الملف الأصلي سليمًا.

بالنسبة إلى المتصفحات التي لا تتوافق مع واجهة File System Access API، تكون عملية التنفيذ قصيرة، لأنّ هو إنشاء عنصر ارتساء بسمة download تكون قيمتها هي اسم الملف المطلوب عنوان URL لملف blob كقيمة السمة href.

export default async (blob, options = {}) => {
  const a = document.createElement('a');
  a.download = options.fileName || 'Untitled';
  a.href = URL.createObjectURL(blob);
  a.addEventListener('click', () => {
    setTimeout(() => URL.revokeObjectURL(a.href), 30 * 1000);
  });
  a.click();
};

ويتم بعد ذلك النقر على عنصر الارتساء آليًا. لمنع تسرُّب الذاكرة، يحتاج عنوان URL للكائنات الثنائية الكبيرة (blob) إلى سيتم إبطاله بعد الاستخدام. بما أن هذا مجرّد تنزيل، لا يتم عرض أي مربّع حوار لحفظ الملفات، وسيتم سيتم نقل الملفات إلى مجلد Downloads التلقائي.

السحب والإفلات

يعد السحب والإفلات إحدى عمليات تكامل النظام المفضلة لدي على سطح المكتب. في ExcaliDraw، عندما أُسقِط .excalidraw على التطبيق، وسيتم فتحه على الفور ويمكنني بدء التعديل. على المتصفحات التي تدعم واجهة برمجة تطبيقات File System Access API، يمكنني بعد ذلك حفظ تغييراتي على الفور. لا حاجة إلى المغادرة من خلال مربع حوار حفظ الملفات نظرًا لأنه قد تم الحصول على مؤشر الملف المطلوب من عملية السحب والإفلات العملية.

بإمكانكم تحقيق ذلك من خلال الاتصال بالرقم getAsFileSystemHandle() على عنصر نقل البيانات عندما تكون واجهة برمجة التطبيقات File System Access API متوافقة. أوافق على ذلك مؤشر الملف إلى loadFromBlob()، والذي قد تتذكره من فقرتين أعلاه. كثيرة جدًا الإجراءات التي يمكنك تنفيذها في الملفات، مثل الفتح والحفظ والتوفير الزائد والسحب والإفلات. زميلي بيت وقد قمت بتوثيق كل هذه الحيل وغيرها في مقالتنا حتى تتمكن من وتعرَّف على آخر المستجدات في حالة حدوث كل هذا بسرعة كبيرة.

const file = event.dataTransfer?.files[0];
if (file?.type === 'application/json' || file?.name.endsWith('.excalidraw')) {
  this.setState({ isLoading: true });
  // Provided by browser-fs-access.
  if (supported) {
    try {
      const item = event.dataTransfer.items[0];
      file as any.handle = await item as any
        .getAsFileSystemHandle();
    } catch (error) {
      console.warn(error.name, error.message);
    }
  }
  loadFromBlob(file, this.state).then(({ elements, appState }) =>
    // Load from blob
  ).catch((error) => {
    this.setState({ isLoading: false, errorMessage: error.message });
  });
}

مشاركة الملفات

تتمثل عملية دمج أخرى للنظام حاليًا على Android وChromeOS وWindows في Web Share Target API: أنا هنا في تطبيق Files في مجلد Downloads. مع نسبة شوائب سيتمكّن من الاطّلاع على ملفَين، أحدهما يحمل اسمًا غير وصفي untitled وطابع زمني. للتحقق مما يحتوي عليه، أنقر على النقاط الثلاث، ثم أشارك، وأحد الخيارات التي تظهر استكشِف المسارات. عندما أنقر على الرمز، يتبيّن لي أنّ الملف لا يحتوي إلا على شعار I/O مرة أخرى.

Lipis على إصدار Electron المتوقّف

هناك شيء واحد يمكنك فعله مع الملفات التي لم أتحدث عنها حتى الآن هو النقر المزدوج عليها. ما يحدث عادةً عندما تنقر على زر النقر مرّتين على ملف، أي أن التطبيق المرتبط بنوع MIME للملف يفتح. على سبيل المثال، بالنسبة إلى .docx، سيكون هذا Microsoft Word.

اعتاد تطبيق ExcaliDraw أن يكون لديه إصدار Electron من التطبيق الذي هذه النوعية من الملفات، لذا عندما تنقر نقرًا مزدوجًا على ملف .excalidraw، سيفتح تطبيق ExcaliDraw Electron. "ليبيس" الذي قابلته من قبل هو صانع المحتوى وإيقاف شركة ExcaliDraw Electron. فسألته عن سبب شعوره بإمكانية إيقاف العمل إصدار الإلكترونات:

طلب الناس الحصول على تطبيق Electron منذ البداية، لأنهم أرادوا في المقام الأول لفتح الملفات عن طريق النقر المزدوج. كما كنا نعتزم وضع التطبيق في متاجر التطبيقات. في المقابل، شخص ما اقترحنا إنشاء تطبيق ويب تقدّمي (PWA) بدلاً من ذلك، فلقد نفّذنا كلا الإجراءين. لحسن الحظ لقد تعرفنا على Project Fugu واجهات برمجة التطبيقات (API) مثل الوصول إلى نظام الملفات، والوصول إلى الحافظة، ومعالجة الملفات، وغيرها. بنقرة واحدة، يمكنك بتثبيت التطبيق على سطح المكتب أو الهاتف المحمول، بدون أي وزن إضافي من Electron. لقد كان سؤالاً سهلاً إيقاف إصدار Electron، والتركيز فقط على تطبيق الويب، وجعله تطبيق الويب التقدّمي (PWA) الخيار الأفضل. يمكننا الآن نشر تطبيقات الويب التقدّمية (PWA) على "متجر Play" وMicrosoft المتجر. هذا ضخم!

يمكن للمرء أن يقول إنّ ExcaliDraw لـ Electron لم يتم إيقافها نهائيًا لأنّ Electron سيئة، ولكنها ليست أداة على الإطلاق. لأنّ الويب أصبح جيدًا بما فيه الكفاية. أحب هذا!

معالجة الملفات

عندما أقول "أصبح الويب جيدًا بما فيه الكفاية"، يكون ذلك بسبب ميزات مثل الملف القادم التعامل مع الجهاز.

هذا تثبيت عادي لنظام التشغيل macOS Big Sur. تحقق الآن مما يحدث عندما أنقر بزر الماوس الأيمن على ملف ExcaliDraw. يمكنني اختيار فتحه باستخدام ExcaliDraw، وهو تطبيق الويب التقدّمي (PWA) المثبَّت. طبعًا كما يمكن أن يؤدي النقر المزدوج إلى النتيجة المضرّة أيضًا، ولكن في التسجيل الرقمي للشاشة، يكون أقل دراميًا.

كيف يعمل هذا؟ الخطوة الأولى هي جعل أنواع الملفات التي يمكن لتطبيقي التعامل معها نظام التشغيل. أفعل ذلك في حقل جديد يُسمى file_handlers في بيان تطبيق الويب. من القيمة هي مصفوفة من العناصر التي تحتوي على إجراء والسمة accept. يحدّد الإجراء عنوان URL المسار الذي يشغِّل نظام التشغيل تطبيقك فيه ويكون كائن القبول أزواجًا من القيم الرئيسية لمعيار MIME الأنواع وامتدادات الملفات المرتبطة بها.

{
  "name": "Excalidraw",
  "description": "Excalidraw is a whiteboard tool...",
  "start_url": "/",
  "display": "standalone",
  "theme_color": "#000000",
  "background_color": "#ffffff",
  "file_handlers": [
    {
      "action": "/",
      "accept": {
        "application/vnd.excalidraw+json": [".excalidraw"]
      }
    }
  ]
}

الخطوة التالية هي التعامل مع الملف عند تشغيل التطبيق. يحدث هذا في launchQueue حيث أحتاج إلى ضبط مستهلك من خلال استدعاء setConsumer(). المعلمة إلى هذا هي دالة غير متزامنة تتلقى launchParams. عنصر launchParams هذا على حقل يسمى "files" (الملفات) تحصل على مجموعة من الأسماء المعرِّفة للملفات للعمل عليها. أنا أهتم فقط أول واحد ومن مؤشر الملف هذا أحصل على كائن ثنائي كبير أمرره إلى صديقنا القديم loadFromBlob()

if ('launchQueue' in window && 'LaunchParams' in window) {
  window as any.launchQueue
    .setConsumer(async (launchParams: { files: any[] }) => {
      if (!launchParams.files.length) return;
      const fileHandle = launchParams.files[0];
      const blob: Blob = await fileHandle.getFile();
      blob.handle = fileHandle;
      loadFromBlob(blob, this.state).then(({ elements, appState }) =>
        // Initialize app state.
      ).catch((error) => {
        this.setState({ isLoading: false, errorMessage: error.message });
      });
    });
}

مرة أخرى، إذا سار هذا الأمر بسرعة كبيرة، يمكنك قراءة المزيد عن واجهة برمجة تطبيقات معالجة الملفات في مقالتي. يمكنك تفعيل معالجة الملفات من خلال ضبط النظام الأساسي التجريبي على الويب. الجديدة. ومن المقرّر أن تظهر في Chrome في وقت لاحق من هذا العام.

دمج الحافظة

من الميزات الرائعة الأخرى في ExcaliDraw، وهي دمج الحافظة. يمكنني نسخ الرسم بالكامل أو أجزاء منها فقط في الحافظة، ويمكن إضافة علامة مائية عند الحاجة، ثم ألصقها تطبيق آخر. وبالمناسبة، هذا إصدار ويب من تطبيق Paint Windows 95.

طريقة عمل هذا بسيطة بشكل مدهش. كل ما أحتاج إليه هو لوحة الرسم التي أكتبها بعد ذلك إلى الحافظة عن طريق تمرير مصفوفة من عنصر واحد مع ClipboardItem مع الكائن الثنائي الكبير إلى navigator.clipboard.write(). لمزيد من المعلومات حول ما يمكنك فعله باستخدام الحافظة يمكنك الاطّلاع على كل من "جايسون" ومقالتي.

export const copyCanvasToClipboardAsPng = async (canvas: HTMLCanvasElement) => {
  const blob = await canvasToBlob(canvas);
  await navigator.clipboard.write([
    new window.ClipboardItem({
      'image/png': blob,
    }),
  ]);
};

export const canvasToBlob = async (canvas: HTMLCanvasElement): Promise<Blob> => {
  return new Promise((resolve, reject) => {
    try {
      canvas.toBlob((blob) => {
        if (!blob) {
          return reject(new CanvasError(t('canvasError.canvasTooBig'), 'CANVAS_POSSIBLY_TOO_BIG'));
        }
        resolve(blob);
      });
    } catch (error) {
      reject(error);
    }
  });
};

التعاون مع الآخرين

مشاركة عنوان URL لجلسة

هل تعلم أنّ تطبيق ExcaliDraw يوفّر أيضًا وضعًا تعاونيًا؟ يمكن للأشخاص المختلفين العمل معًا في المستند ذاته. لبدء جلسة جديدة، أنقر على زر التعاون المباشر ثم أبدأ جلسة المراجعة. يمكنني مشاركة عنوان URL للجلسة مع المتعاونين بسهولة بفضل واجهة برمجة تطبيقات Web Share API التي دمجتها ExcaliDraw.

التعاون المباشر

لقد محاكاةت جلسة تعاون محليًا من خلال تصميم شعار مؤتمر Google I/O على جهاز Pixelbook. وهاتف Pixel 3a وiPad Pro. يتضح لي أنّ التغييرات التي أُجريها على أحد الأجهزة تنعكس على جميع الأجهزة الأخرى.

أستطيع أيضًا أن أرى جميع المؤشرات تتحرك. يتحرك مؤشر Pixelbook بثبات، لأنّه يتم التحكّم فيه باستخدام لوحة اللمس، ولكن مؤشر الماوس على هاتف Pixel 3a ومؤشر الجهاز اللوحي iPad Pro يتنقلان، حيث التحكُّم في هذه الأجهزة من خلال النقر بإصبعي.

عرض حالات المتعاونين

لتحسين تجربة التعاون في الوقت الفعلي، هناك أيضًا نظام رصد غير مستخدَم حاليًا. يعرض مؤشر جهاز iPad Pro نقطة خضراء عند استخدامه. تتحول النقطة إلى اللون الأسود عندما أقوم بالتبديل إلى علامة تبويب متصفح أو تطبيق آخر. وعندما أستخدم تطبيق ExcaliDraw، ولكن لم أنفّذ أي إجراء، يظهرني المؤشر بحالة غير نشطة، يرمز إليها بـ zZZ الثلاثة.

قد يميل القرّاء المتحمسون لجهات النشر الخاصة بنا إلى الاعتقاد بأنّ عملية رصد عدم النشاط غير متاحة من خلال Idle Detection API، وهي اقتراح لمرحلة مبكرة تم العمل عليه في سياق مشروع فوغو. تنبيه بكشف تفاصيل عن الحبكة: ليس كذلك. على الرغم من أننا كنا ننفذ عملية تنفيذ تستند إلى واجهة برمجة التطبيقات هذه في ExcaliDraw، قررنا في النهاية اعتماد نهج أكثر تقليدية يعتمد على قياس حركة المؤشر ورؤية الصفحة.

لقطة شاشة لملاحظات ميزة Idle Detection المقدَّمة في مستودع WICG Idle Detection

قدّمنا ملاحظات حول سبب ظهور Idle Detection API. لم يتم حل حالة الاستخدام التي لدينا. يتم تطوير جميع واجهات برمجة تطبيقات Project Fugu بشكل مفتوح، لذا يمكن للجميع التدخل وسماع أصواتهم!

Lipis حول ما يعيق ExcaliDraw

وبالحديث عن ذلك، طرحتُ على "ليبيس" سؤالاً أخيرًا حول ما يعتقده أنّه مفقود من الويب. التي تمنع ExcaliDraw:

تُعد واجهة برمجة التطبيقات File System Access API رائعة، لكنك تعرف ماذا؟ معظم الملفات التي أهتم بها هذه الأيام مباشرة في Dropbox أو Google Drive، وليس على القرص الثابت. أتمنى أن تتمكن واجهة برمجة تطبيقات File System Access API تقوم بتضمين طبقة تجريدية لمزودي أنظمة الملفات البعيدة مثل Dropbox أو Google لدمج والتي يمكن للمطورين استخدامها. يمكن للمستخدمين بعد ذلك الاسترخاء ومعرفة أن ملفاتهم آمنة مع مقدّم الخدمات السحابية الذي يثقون به

أوافق تمامًا على ذلك، أعيش في السحابة أيضًا. نأمل أن يتم تنفيذ ذلك قريبًا.

وضع التطبيقات المبوَّبة

ممتاز. لقد شهدنا العديد من عمليات الدمج الرائعة مع واجهة برمجة التطبيقات في ExcaliDraw. نظام الملفات ومعالجة الملفات الحافظ والمشاركة على الويب هدف حصة الويب. ولكن هناك شيء آخر. حتى الآن، لم يكن بإمكاني تحرير مستند واحد في وقت معين. لم يعد الأمر كذلك. يُرجى الاستمتاع لأول مرة بإصدار مبكر من وضع التطبيق ذو علامات التبويب في ExcaliDraw. هذا هو الشكل الذي يبدو عليه.

لديَّ ملف حالي مفتوح في تطبيق ExcaliDraw PWA المثبَّت يتم تشغيله في الوضع المستقل. الْآنْ أفتح علامة تبويب جديدة في النافذة المستقلة. هذه ليست علامة تبويب متصفِّح عادية، ولكنها علامة تبويب تطبيق ويب تقدّمي (PWA). في هذه الدورة، علامة تبويب جديدة يمكنني بعد ذلك فتح ملف ثانوي والعمل عليه بشكل مستقل من نافذة التطبيق نفسها.

ما زال وضع التطبيق المبوب في مراحله الأولى ولم يتم ضبط كل شيء على ما يرام. إذا كنت مهتمًا، فاحرص على قراءة الحالة الراهنة لهذه الميزة في مقالتي.

الخاتمة

للبقاء على اطّلاع على هذه الميزات وغيرها من الميزات، احرص على مشاهدة أداة تتبُّع واجهة برمجة تطبيقات Fuguu نحن متحمسون للغاية للمضي قدمًا بالويب تتيح لك إنجاز المزيد من المهام على المنصة نتمنى لك الاستمتاع بلعبة ExcaliDraw، ونتمنى لك أيضًا التطبيقات الرائعة التي ستنشئها. ابدأ الإنشاء في excalidraw.com.

لا يسعنا الانتظار لرؤية بعض واجهات برمجة التطبيقات التي عرضتها اليوم تظهر في تطبيقاتك. اسمي تامر، يمكنك العثور عليّ بـ @tomayac على Twitter وعلى الإنترنت بشكل عام. شكرًا جزيلاً على المشاهدة، ونتمنى لك وقتًا ممتعًا في مؤتمر Google I/O.