المحتوى عن 'notification'.



مزيد من الخيارات

  • ابحث بالكلمات المفتاحية

    أضف وسومًا وافصل بينها بفواصل ","
  • ابحث باسم الكاتب

نوع المُحتوى


التصنيفات

  • التخطيط وسير العمل
  • التمويل
  • فريق العمل
  • دراسة حالات
  • نصائح وإرشادات
  • التعامل مع العملاء
  • التعهيد الخارجي
  • التجارة الإلكترونية
  • مقالات ريادة أعمال عامة

التصنيفات

  • PHP
    • Laravel
    • ووردبريس
  • جافاسكريبت
    • Node.js
    • jQuery
    • AngularJS
    • Cordova
  • HTML5
  • CSS
    • Sass
    • إطار عمل Bootstrap
  • SQL
  • سي شارب #C
    • منصة Xamarin
  • بايثون
    • Flask
    • Django
  • لغة روبي
    • إطار العمل Ruby on Rails
  • لغة Go
  • لغة جافا
  • لغة Kotlin
  • برمجة أندرويد
  • لغة Swift
  • لغة R
  • لغة TypeScript
  • سير العمل
    • Git
  • صناعة الألعاب
    • Unity3D
  • مقالات برمجة عامة

التصنيفات

  • تجربة المستخدم
  • الرسوميات
    • إنكسكيب
    • أدوبي إليستريتور
    • كوريل درو
  • التصميم الجرافيكي
    • أدوبي فوتوشوب
    • أدوبي إن ديزاين
    • جيمب
  • التصميم ثلاثي الأبعاد
    • 3Ds Max
    • Blender
  • مقالات تصميم عامة

التصنيفات

  • خواديم
    • الويب HTTP
    • قواعد البيانات
    • البريد الإلكتروني
    • DNS
    • Samba
  • الحوسبة السّحابية
    • Docker
  • إدارة الإعدادات والنّشر
    • Chef
    • Puppet
    • Ansible
  • لينكس
  • FreeBSD
  • حماية
    • الجدران النارية
    • VPN
    • SSH
  • مقالات DevOps عامة

التصنيفات

  • التسويق بالأداء
    • أدوات تحليل الزوار
  • تهيئة محركات البحث SEO
  • الشبكات الاجتماعية
  • التسويق بالبريد الالكتروني
  • التسويق الضمني
  • استسراع النمو
  • المبيعات

التصنيفات

  • إدارة مالية
  • الإنتاجية
  • تجارب
  • مشاريع جانبية
  • التعامل مع العملاء
  • الحفاظ على الصحة
  • التسويق الذاتي
  • مقالات عمل حر عامة

التصنيفات

  • الإنتاجية وسير العمل
    • مايكروسوفت أوفيس
    • ليبر أوفيس
    • جوجل درايف
    • شيربوينت
    • Evernote
    • Trello
  • تطبيقات الويب
    • ووردبريس
    • ماجنتو
  • أندرويد
  • iOS
  • macOS
  • ويندوز

التصنيفات

  • شهادات سيسكو
    • CCNA
  • شهادات مايكروسوفت
  • شهادات Amazon Web Services
  • شهادات ريدهات
    • RHCSA
  • شهادات CompTIA
  • مقالات عامة

أسئلة وأجوبة

  • الأقسام
    • أسئلة ريادة الأعمال
    • أسئلة العمل الحر
    • أسئلة التسويق والمبيعات
    • أسئلة البرمجة
    • أسئلة التصميم
    • أسئلة DevOps
    • أسئلة البرامج والتطبيقات
    • أسئلة الشهادات المتخصصة

التصنيفات

  • ريادة الأعمال
  • العمل الحر
  • التسويق والمبيعات
  • البرمجة
  • التصميم
  • DevOps

تمّ العثور على 4 نتائج

  1. يتميز نظام تشغيل أندرويد بوجود شريط أعلى الشاشة يمُد المستخدم بالعديد من المعلومات الهامة من ضمنها الإشعارات التي ترسلها التطبيقات. فالإشعارات هي جزء من واجهة المستخدم لكنها تظهر خارج التطبيق لإعلام المستخدم بحدث معين، مما يُمكّن المستخدم من عرضه والتفاعل معه بينما يستخدم تطبيقًا آخر. ويحتوي الإشعار على رسالة مختصرة عن هذا الحدث. ويظهر الإشعار عند حدوثه كأيقونة تعبر عن التطبيق في شريط الحالة أعلى الشاشة، ويمكنك معرفة تفاصيله عند سحب درج الإشعارات والضغط على الإشعار. هناك عدة خطوات لصنع الإشعارات من داخل تطبيقك: صنع كائن البناء الخاص بالإشعار من الصنف Notification.Builder Notification.Builder mBuilder = new Notification.Builder(this); من خلال هذا الكائن يمكننا التحكم في الخصائص الخاصة بالإشعار مثل عنوان الإشعار، الأيقونة المستخدمة، التحكم في الأولوية، التحكم في المهام التي يستطيع القيام بها عند الضغط عليه وغيرهم من الخصائص المختلفة. تخصيص الحد الأدنى من الخصائص للإشعار بعد الحصول على كائن البناء نبدأ في التحكم في خصائص الإشعار، وهناك بعض الخصائص الأساسية اللازم توافرها في الإشعار وهي: الأيقونة الخاصة بالإشعار. عنوان الإشعار. المحتوى الخاص بالإشعار. mBuilder.setSmallIcon(R.drawable.msg_icon); mBuilder.setContentTitle("New Message"); mBuilder.setContentText("Hi, This is the message text."); ويوجد العديد من الخصائص الأخرى التي يمكنك استخدامها حسب حاجة التطبيق لها. بناء الإشعار بالخصائص السابقة يتم ذلك باستدعاء التابع ()build والحصول على كائن من Notification. Notification notif = mBuilder.build(); إظهار الإشعار في درج الإشعارات يوفر أندرويد الصنف NotificationManager لإدارة الإشعارات من حيث إصدار الإشعار، تعديل الإشعار بعد إصداره أو إلغاء الإشعار برمجيًا. لذا يجب أولًا الحصول على كائن من هذا الصنف وذلك عن طريق استدعاء الدالة ()getSystemService وتمرير الثابت NOTIFICATION_SERVICE والذي يعني طلب الخدمات الخاصة بالإشعارات من خدمات النظام. وسيتم استخدام الدالة ()getSystemService كثيرًا عند الحاجة لطلب خدمات من النظام. NotificationManager notifyMngr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); بعد ذلك نستدعي التابع ()notify باستخدام الكائن من NotificationManager ليظهر الإشعار في الحال، وتمرير رقم مميز له يُعبر عن الإشعار ليُستخدم هذا الرقم فيما بعد للتعديل على الإشعار أو إلغائه، كما يتم تمرير الإشعار الذي تم بنائه من قبل. int notificationId = 103; notifyMngr.notify(notificationId, notif); تطبيق 1 سنقوم في هذا التطبيق بتجربة الخطوات السابق شرحها لتكوين التطبيق مثل الصورة التالية: أولًا نبدأ بصنع واجهة المستخدم البسيطة في ملف activity_main.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Show Notification" android:id="@+id/shw_notification"/> </LinearLayout> بعد ذلك ننتقل إلى الشيفرة الخاصة بالتطبيق في MainActivity.java باتباع الخطوات ذاتها لصنع الإشعار عند الضغط على الزر. package apps.noby.simplenotification; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends Activity { private Button shwbtn; private String title; private String detailText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); shwbtn = (Button) findViewById(R.id.shw_notification); title = "New Message"; detailText ="Hi, This is the message text."; shwbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Step 1 Notification.Builder mBuilder = new Notification.Builder(MainActivity.this); //Step 2 mBuilder.setSmallIcon(R.drawable.ic_message); mBuilder.setContentTitle(title); mBuilder.setContentText(detailText); //Step 3 Notification notif = mBuilder.build(); //Step 4 NotificationManager notifyMngr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); int notificationId = 103; notifyMngr.notify(notificationId,notif); } }); } } ثم نقوم بتجربة التطبيق على المحاكي للتأكد من عمله كما ينبغي. تطبيق 2 في التطبيق السابق عند الضغط على الإشعار لا يحدث شيئ، لذا في هذا التطبيق سنقوم بفتح نشاط جديد يعرض تفاصيل الإشعار أو ما نريد من معلومات عند الضغط على الإشعار. ولفتح نشاط جديد داخل التطبيق سنستخدم Intent ولكن سنقوم بتغليف الكائن من Intent داخل كائن آخر من PendingIntent وفائدة هذا التغليف هو أنه لا يمكن استخدام الكائن من Intent خارج التطبيق، والإشعار كما ذكرنا يُعرض خارج حدود التطبيق لذا يقوم PendingIntent بإعطاء الصلاحية للتطبيقات الأخرى أو النظام والذي نُرسل إليه PendingIntent القدرة على تنفيذ الأوامر كأنها تتم داخل تطبيقك. أولًا نقوم بصنع نشاط جديد يُدعى ResultActivity. ثانيًا سنقوم بتعديل الشيفرة الخاصة بـ MainActivity.java وإضافة كائن من Intent. Intent intent = new Intent(MainActivity.this,ResultActivity.class); ونستطيع إرسال بيانات إلى النشاط الآخر بنفس الطريقة المستخدمة في الدروس السابقة. intent.putExtra(DESC_KEY,detailText); ثم نقوم بتغليف الكائن داخل PendingIntent: PendingIntent pIntent = PendingIntent.getActivity(MainActivity.this , 0 , intent , PendingIntent.FLAG_UPDATE_CURRENT); والخطوة الأخيرة هي وضع هذا Intent ضمن خصائص الإشعار باستخدام كائن البناء: mBuilder.setContentIntent(pIntent); لتُصبح الشيفرة النهائية لملف MainActivity.java بعد التعديل هي: package apps.noby.simplenotification; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends Activity { private Button shwbtn; private String title; private String detailText; public final static String DESC_KEY ="descriptionKey"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); shwbtn = (Button) findViewById(R.id.shw_notification); title = "New Message"; detailText ="Hi, This is the message text."; shwbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Step 1 Notification.Builder mBuilder = new Notification.Builder(MainActivity.this); //Step 2 mBuilder.setSmallIcon(R.drawable.ic_message); mBuilder.setContentTitle(title); mBuilder.setContentText(detailText); Intent intent = new Intent(MainActivity.this,ResultActivity.class); intent.putExtra(DESC_KEY,detailText); PendingIntent pIntent = PendingIntent.getActivity(MainActivity.this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(pIntent); //Step 3 Notification notif = mBuilder.build(); //Step 4 NotificationManager notifyMngr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); int notificationId = 103; notifyMngr.notify(notificationId,notif); } }); } } ولم نقم بتغيير شيء في ملف الواجهة activity_main.xml. الآن لعرض التفاصيل التي سترسل إلى النشاط الجديد ResultActivity.java نبدأ في صنع واجهة المستخدم الخاصة بالنشاط ثم بتغيير الشيفرة الخاصة به ولا يوجد اختلاف بينها وبين الطريقة المستخدمة في الدروس السابقة. <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="25sp" android:id="@+id/desc"/> </LinearLayout> package apps.noby.simplenotification; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView; public class ResultActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_result); TextView tv = (TextView) findViewById(R.id.desc); Intent intent = getIntent(); String description = intent.getExtras().getString(MainActivity.DESC_KEY); tv.setText(description); } } ثم نقوم بتجربة التطبيق على المحاكي. تطبيق 3 لاحظ أنه عند الضغط على الإشعار في التطبيق السابق يقوم بفتح نشاط جديد ولكن يظل الإشعار متواجدًا في درج الإشعارات رغم عرضه والتفاعل معه لذا سنقوم في هذا التطبيق بتغيير بسيط حتى يختفي الإشعار بمجرد التفاعل معه. في شيفرة التطبيق السابق بداخل الملف MainActivity.java سنقوم بتعديل السطور الخاصة بالخطوة الثانية لتُصبح. mBuilder.setContentTitle(title); mBuilder.setContentText(detailText); mBuilder.setAutoCancel(true); Intent intent = new Intent(MainActivity.this,ResultActivity.class); intent.putExtra(DESC_KEY,detailText); قمنا فقط بإضافة السطر الخاص باستدعاء التابع ()setAutoCancel وتمرير القيمة true باستخدام كائن البناء، والآن عند تجربة التطبيق بعد هذا التعديل ستجد أنه يقوم بإزالة الإشعار بمجرد الضغط عليه. تطبيق 4 يتم استخدام الشكل السابق بكثرة خاصة في تطبيقات المحادثة أو رسائل البريد حيث يتم عرض صورة المستخدم وبجانبها بحجم صغير الأيقونة الخاصة بالتطبيق. ولصنع ذلك يتم استدعاء التابع ()setLargeIcon باستخدام كائن البناء وتمرير له الصورة المراد عرضها بحجم كبير. لكن هناك شرط وهو أن تكون الصورة بصيغة Bitmap ولأننا حتى الآن نقوم في الدروس باستخدام الصور المتواجدة في مجلد drawable لذا ينبغي قبل تمريرها للتابع ()setLargeIcon أن نقوم بتحويلها إلى Bitmap ويتم ذلك عن طريق الخطوة التالية. Bitmap img = BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.ic_person); ثم بعد ذلك تمريرها كما سبق لبناء الإشعار. mBuilder.setLargeIcon(img); لتُصبح الشيفرة الكاملة الخاصة بالملف MainActivity.java هي: package apps.noby.simplenotification; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends Activity { private Button shwbtn; private String title; private String detailText; public final static String DESC_KEY ="descriptionKey"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); shwbtn = (Button) findViewById(R.id.shw_notification); title = "New Message"; detailText ="Hi, This is the message text."; shwbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Step 1 Notification.Builder mBuilder = new Notification.Builder(MainActivity.this); //Step 2 mBuilder.setSmallIcon(R.drawable.ic_message); Bitmap img = BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.ic_person); mBuilder.setLargeIcon(img); mBuilder.setContentTitle(title); mBuilder.setContentText(detailText); mBuilder.setAutoCancel(true); Intent intent = new Intent(MainActivity.this,ResultActivity.class); intent.putExtra(DESC_KEY,detailText); PendingIntent pIntent = PendingIntent.getActivity(MainActivity.this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(pIntent); //Step 3 Notification notif = mBuilder.build(); //Step 4 NotificationManager notifyMngr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); int notificationId = 103; notifyMngr.notify(notificationId,notif); } }); } } ليعمل التطبيق كما هو متوقع على المحاكي. تطبيق 5 في بعض الأحيان نحتاج إلى التفاعل السريع للمستخدم مع التطبيق دون الحاجة لفتح التطبيق أو لتوفير أكثر من اختيار لفتح أجزاء محددة في التطبيق. للقيام بذلك نستخدم التابع ()addAction والذي يمكننا من إضافة زر إلى الإشعار. PendingIntent pIntent = PendingIntent.getActivity(MainActivity.this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(pIntent); mBuilder.addAction(R.drawable.ic_reply,"Reply",pIntent); mBuilder.addAction(R.drawable.ic_content_copy,"Copy",pIntent); //Step 3 Notification notif = mBuilder.build(); ولاستخدام هذا التابع نقوم بتمرير صورة لتظهر داخل الزر، النص الخاص بالزر وأخيرًا كائن من PendingIntent ليتم تنفيذه عند الضغط على هذا الزر. ويمكنك عمل ()addAction حتى ثلاث مرات فقط، ويمكن لكل زر أن يكون له PendingIntent مختلف خاص به ليقوم بتنفيذ أمر مختلف وفي المثال السابق لشرح الفكرة تم استخدام PendingIntent واحد. والآن نقوم بتشغيل التطبيق على المحاكي للتأكد من عمله بشكل صحيح. تطبيق 6 في بعض الأحيان تحتاج إلى التعديل على إشعار سابق دون إصدار إشعار جديد، وذلك بإضافة بعض المعلومات له أو بتغيير محتوى الإشعار أو كلاهما. وقد تحتاج أيضًا إلى إزالة الإشعار برمجيًا دون تدخل من المستخدم وذلك عند حدوث شيء محدد أو مرور وقت محدد. أولًا للقيام بالتعديل أو بتغيير محتوى إشعار دون إصدار إشعار آخر جديد نقوم ببناء الإشعار ثم نقوم بإصداره باستخدام نفس الـ NotificationID الذي نمرره للتابع ()notify حتى يقوم بتعديل الإشعار صاحب ID ذاته. بفرض أن لدينا هذا الإشعار عند الضغط على زر Show Notification. shwbtn = (Button) findViewById(R.id.shw_notification); shwbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Step 1 Notification.Builder mBuilder = new Notification.Builder(MainActivity.this); //Step 2 mBuilder.setSmallIcon(R.drawable.ic_message); Bitmap img = BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.ic_person); mBuilder.setLargeIcon(img); mBuilder.setContentTitle("New Message"); mBuilder.setContentText("Hi, This is the message text."); mBuilder.setNumber(++totalNumber); mBuilder.setAutoCancel(true); Intent intent = new Intent(MainActivity.this,ResultActivity.class); intent.putExtra(DESC_KEY,"Hi, This is the message text."); PendingIntent pIntent = PendingIntent.getActivity(MainActivity.this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(pIntent); //Step 3 Notification notif = mBuilder.build(); //Step 4 NotificationManager notifyMngr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); int notificationId = 103; notifyMngr.notify(notificationId,notif); } }); ثم عند الضغط على الزر Update Notification يتم تغييرها إلى المحتوى التالي. updatebtn = (Button) findViewById(R.id.upd_notification); updatebtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Step 1 Notification.Builder mBuilder = new Notification.Builder(MainActivity.this); //Step 2 mBuilder.setSmallIcon(R.drawable.ic_message); Bitmap img = BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.ic_person); mBuilder.setLargeIcon(img); mBuilder.setContentTitle("Updated Message"); mBuilder.setContentText("Hi, This is an updated Message."); mBuilder.setNumber(++totalNumber); mBuilder.setAutoCancel(true); Intent intent = new Intent(MainActivity.this,ResultActivity.class); intent.putExtra(DESC_KEY,"Hi, This is an updated Message."); PendingIntent pIntent = PendingIntent.getActivity(MainActivity.this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(pIntent); //Step 3 Notification notif = mBuilder.build(); //Step 4 NotificationManager notifyMngr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); int notificationId = 103; notifyMngr.notify(notificationId,notif); } }); لاحظ أننا قمنا باستخدام نفس NotificationID في خطوة إظهار الإشعار وذلك لإخبار النظام أننا نريد التعديل على إشعار متواجد بالفعل. والآن لإزالة الإشعار نضغط على الزر Cancel Notification. cnclbtn = (Button) findViewById(R.id.cncl_notification); cnclbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { NotificationManager notifyMngr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); totalNumber = 0; int notificationId = 103; notifyMngr.cancel(notificationId); } }); لإزالة الإشعار نستدعي التابع ()cancel باستخدام الكائن من NotificationManager ونمرر لها الـ ID الخاص بالإشعار. لاحظ أننا قد قمنا باستخدام التابع ()setNumber عند بناء الإشعار وذلك ليُظهر عدد مرات بناء وتعديل الإشعار ذاته، ويتم بدأ العد مجددًا عند الضغط على الزر Cancel Notification. وبتغيير ملف الواجهة في activity_main.xml ليُصبح. <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Show Notification" android:id="@+id/shw_notification"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Update Notification" android:id="@+id/upd_notification"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Cancel Notification" android:id="@+id/cncl_notification"/> </LinearLayout> تستطيع أن تلاحظ الرقم المتواجد أقصى يمين الإشعار والذي يُعبر عن عدد مرات التعديل على الإشعار ذاته، ويتحكم التابع ()setNumber في القيمة التي ستظهر بناءً على قيمة المعامل الذي تم تمريره له. تطبيق 7 هناك العديد من الإشعارات التي لا يستطيع المستخدم من إزالتها ويجب عليه انتظار انتهاء حدث معين أو القيام بمهمة معينة حتى يختفي الإشعار، مثال على ذلك عند تحميلك لملف تجد إشعار لا يمكنك إزالته يُخبرك بمعلومات عن التحميل وللتخلص منه ينبغي الانتظار حتى اكتمال تحميل الملف أو إلغاء التحميل. لتفعيل هذه النوعية من الإشعارات داخل التطبيق لدينا طريقتان 1. نقوم بتغير قيمة إحدى خصائص الإشعار الذي قمنا ببنائه وتدعى flags، حيث نقوم بإضافة خاصيتين إلى الإشعار وهما: Notification.FLAG_NO_CLEAR وهي تلغي تأثير التابع ()setAutoCancel فلا يتم مسح الإشعار عند الضغط عليه. Notification.FLAG_ONGOING_EVENT وهي المسؤولة عن إخبار النظام أن هذا الإشعار لديه معلومات لا زالت لها أهمية ولا ينبغي إزالتها الآن. //Step 3 Notification notif = mBuilder.build(); notif.flags |= Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT; 2. استدعاء التابع ()setOngoing باستخدام كائن البناء و تمرير له القيمة true، مع إزالة سطر استدعاء التابع ()setAutoCancel حتى لا يتم إزالة الإشعار عند الضغط عليه. //Step 2 mBuilder.setSmallIcon(R.drawable.ic_message); mBuilder.setContentTitle("New Message"); mBuilder.setContentText("Hi, This is the message text."); mBuilder.setOngoing(true); ملحوظة: لا يوجد فرق بين أي من الطريقتين من حيث الوظيفة أو التأثير. ولإزالة هذا الإشعار عند الانتهاء من الحدث ينبغي استدعاء التابع ()cancel وتمرير له NotificationID كما سبق، ولا يمكن إزالته إلا بهذه الطريقة. تطبيق 8 عندما يأتي تنبيه من تطبيق ما وكانت شاشة القفل مغلقة فهناك ثلاثة اختيارات للنظام للتعامل مع هذا الإشعار. إما إظهار محتوى الإشعار على شاشة القفل، أو إظهار الإشعار مع إخفاء محتواه أو عدم إظهار الإشعار ويمكن التحكم في هذه الاختيارات برمجيًا من خلال التابع ()setVisibility باستخدام كائن البناء ويُمرر له ثابت قيمته: Notification.VISIBILITY_PUBLIC إذا أردت أن يظهر محتوى الإشعار. Notification.VISIBILITY_PRIVATE إذا أردت إظهار الإشعار فقط دون إظهار محتواه. Notification.VISIBILITY_SECRET وذلك لعدم ظهور الإشعار على شاشة القفل ويظهر حين نتجاوز قفل الشاشة أولًا. //Step 2 mBuilder.setSmallIcon(R.drawable.ic_message); mBuilder.setContentTitle("New Message"); mBuilder.setContentText("Hi, This is the message text."); mBuilder.setAutoCancel(true); mBuilder.setVisibility(Notification.VISIBILITY_PRIVATE); ملحوظة: حتى يعمل التابع ()setVisibility يجب أن يكون الحد الأدنى من نسخة النظام التي يدعمها التطبيق هي Lollipop API 21، حيث لا تدعم النسخ الأقدم هذه الميزة لذا تأكد من تغييرها عند عمل مشروع جديد. تطبيق 9 يدعم أندرويد عدة أنواع من الإشعارات بجانب النوع الأساسي الذي استخدمناه في الأمثلة السابقة. Big Text Style حيث تستطيع أن تجمع بين الأمرين، إشعار بسيط يعرض نصًا مختصرًا ويمكن للمستخدم أن يقوم بتكبيره لعرض المزيد من التفاصيل. ويكثر استخدام هذه الطريقة عند عرض إشعار برسالة بريد إلكتروني جديدة فيمكن لك تكبيرها وقراءة تفاصيل الرسالة دون فتح التطبيق. ويمكنك تطبيق ذلك في تطبيقك عن طريق. عمل إشعار وتحديد خصائصه كما سبق وذلك لتُعرض هذه المعلومات عندما يكون الإشعار صغير الحجم. عمل كائن من Notification.BigTextStyle وتحديد عنوان جديد وعرض تفاصيل أكثر ثم إضافته لخصائص الإشعار. بناء الإشعار. ولتوضيح هذه الخطوات بالشيفرة نقوم بالتالي: private void showBigTextNotification() { //Step 1 mBuilder = new Notification.Builder(this); mBuilder.setSmallIcon(R.drawable.ic_txt); mBuilder.setContentTitle(“Big Text in Normal Mode”); mBuilder.setContentText(“Example of a Big Text Notification.”); //Step 2 Notification.BigTextStyle bigText = new Notification.BigTextStyle(); bigText.bigText(“This Text will be repeated over and over.This Text will be repeated over and over.This Text will be repeated over and over.This Text will be repeated over and over.”); bigText.setBigContentTitle(“Big Text in Expansion Mode”); mBuilder.setStyle(bigText); //Step 3 Notification notfi = mBuilder.build(); mNotificationManager.notify(200,notfi); } Inbox Style يختلف هذا النوع عن النوع السابق في أنه يتيح لك عرض التفاصيل في أكثر من سطر، أما النوع السابق سيعرض كافة التفاصيل في نفس السطر دون القدرة على التحكم فيما يُعرض في كل سطر على حدا. ويُستخدم هذا النوع عند التعديل على إشعار وإضافة المزيد من التفاصيل إليه. مثل تطبيقات البريد الإلكتروني عند عرض في نفس الإشعار سطرًا عن كل رسالة قادمة. لتطبيق هذا النوع نمر بنفس الخطوات السابقة ولكن باستخدام كائن من الصنف Notification.InboxStyle. لاحظ أن لكل صنف توابعه الخاصة التي تُمكنك من إضافة الخصائص له. private void showInboxNotification() { //Step 1 mBuilder = new Notification.Builder(this); mBuilder.setSmallIcon(R.drawable.ic_inbox); mBuilder.setContentTitle(“Inbox in Normal Mode”); mBuilder.setContentText(“Example of a Inbox Notification.”); lines = new String[6]; lines[0] = “Line number 1”; lines[1] = “Line number 2”; lines[2] = “Line number 3”; lines[3] = “Line number 4”; lines[4] = “Line number 5”; lines[5] = “Line number 6”; //Step 2 Notification.InboxStyle inbox = new Notification.InboxStyle(); for(int I = 0 ; i<lines.length; i++) inbox.addLine(lines[i]); inbox.setBigContentTitle(“Inbox in Expansion Mode”); mBuilder.setStyle(inbox); //Step 3 Notification notfi = mBuilder.build(); mNotificationManager.notify(97,notfi); } Big Picture Style عندما تكون تفاصيل الإشعار هي صورة يُفضل استخدام هذا النوع. وأيضًا يختلف نوع الكائن المستخدم Notification.BigPictureStyle. private void showBigPictureNotification() { //Step 1 mBuilder = new Notification.Builder(this); mBuilder.setSmallIcon(R.drawable.ic_picture); mBuilder.setContentTitle(“Big Picture in Normal Mode”); mBuilder.setContentText(“Example of a Big Picture Notification.”); Bitmap img = BitmapFactory.decodeResource(getResources(),R.drawable.picture); //Step 2 Notification.BigPictureStyle bigPic = new Notification.BigPictureStyle(); bigPic.bigPicture(img); bigPic.setBigContentTitle(“Big Picture in Expansion Mode”); mBuilder.setStyle(bigPic); //Step 3 Notification notfi = mBuilder.build(); mNotificationManager.notify(6,notfi); } وبدمج كافة الأنواع في تطبيق واحد يعرض الإشعار عند الضغط على الزر المناسب لتُصبح الشيفرة النهائية لملف MainActivity.java هي: package apps.noby.advancednotification; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends Activity { private Button bigTextButton; private Button inboxButton; private Button bigPictureButton; private Button cancelButton; private Notification.Builder mBuilder; private NotificationManager mNotificationManager; private String[] lines; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bigTextButton = (Button) findViewById(R.id.bg_txt); inboxButton = (Button) findViewById(R.id.inbx); bigPictureButton = (Button) findViewById(R.id.bg_pic); cancelButton = (Button) findViewById(R.id.cncl); mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); bigTextButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v){ showBigTextNotification(); } } ); inboxButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showInboxNotification(); } }); bigPictureButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showBigPictureNotification(); } }); cancelButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { cancelNotification(); } }); } private void cancelNotification() { mNotificationManager.cancelAll(); } private void showBigTextNotification() { mBuilder = new Notification.Builder(this); mBuilder.setSmallIcon(R.drawable.ic_txt); mBuilder.setContentTitle("Big Text in Normal Mode"); mBuilder.setContentText("Example of a Big Text Notification."); Notification.BigTextStyle bigText = new Notification.BigTextStyle(); bigText.bigText("This Text will be repeated over and over.This Text will be repeated over and over.This Text will be repeated over and over.This Text will be repeated over and over."); bigText.setBigContentTitle("Big Text in Expansion Mode"); mBuilder.setStyle(bigText); Notification notfi = mBuilder.build(); mNotificationManager.notify(200,notfi); } private void showInboxNotification() { mBuilder = new Notification.Builder(this); mBuilder.setSmallIcon(R.drawable.ic_inbox); mBuilder.setContentTitle("Inbox in Normal Mode"); mBuilder.setContentText("Example of a Inbox Notification."); lines = new String[6]; lines[0] = "Line number 1"; lines[1] = "Line number 2"; lines[2] = "Line number 3"; lines[3] = "Line number 4"; lines[4] = "Line number 5"; lines[5] = "Line number 6"; Notification.InboxStyle inbox = new Notification.InboxStyle(); for(int i = 0 ; i<lines.length; i++) inbox.addLine(lines[i]); inbox.setBigContentTitle("Inbox in Expansion Mode"); mBuilder.setStyle(inbox); Notification notfi = mBuilder.build(); mNotificationManager.notify(97,notfi); } private void showBigPictureNotification() { mBuilder = new Notification.Builder(this); mBuilder.setSmallIcon(R.drawable.ic_picture); mBuilder.setContentTitle("Big Picture in Normal Mode"); mBuilder.setContentText("Example of a Big Picture Notification."); Bitmap img = BitmapFactory.decodeResource(getResources(),R.drawable.picture); Notification.BigPictureStyle bigPic = new Notification.BigPictureStyle(); bigPic.bigPicture(img); bigPic.setBigContentTitle("Big Picture in Expansion Mode"); mBuilder.setStyle(bigPic); Notification notfi = mBuilder.build(); mNotificationManager.notify(6,notfi); } } وملف واجهة المستخدم activity_main.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Big Text Style" android:id="@+id/bg_txt"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Inbox Style" android:id="@+id/inbx"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Big Picture Style" android:id="@+id/bg_pic"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Cancel ALL" android:id="@+id/cncl"/> </LinearLayout> بهذا نكون قد وصلنا إلى نهاية هذا الدرس، في انتظار تجربتكم وآرائكم.
  2. يرسل مركز الإشعارات الكثير من الإشعارات المفيدة التي تبقيك مطلعًا على كل ما يحدث على هاتفك. مثل إشعار استلام بريد إلكتروني جديد، إشعارات الأحداث على التقويم، إشعارات تحديث التطبيقات، إلخ. لكن في بعض الأحيان تصبح هذه الإشعارات مصدر إزعاج، خصوصًا إذا كانت تتعلّق بأمور غير مهمة بالنسبة لك. لحسن الحظ، بإمكانك التحكّم في إعدادات هاتفك ليقوم بإرسال الإشعارات حول الأحداث التي تريد معرفتها فقط. وهذا ما سنتعلّمه في هذا الدرس. كيف يمكنني الوصول إلى مركز الإشعارات؟ يمكنك الوصول إلى مركز الإشعارات لهواتف iPhone بمجرّد سحب الستارة العلوية، سواء كان من على شاشة القفل، الشاشة الرئيسية، أو من داخل التطبيقات. يحتوي مركز الإشعار على تبويبين: اليوم Today، والإشعارات Notifications. يعرض تبويب "اليوم" بعض المعلومات المفيدة مثل حالة الطقس أو الأسهم، أحداث التقويم القادمة، ظروف حركة المرور وغيرها. ويمكن تخصيص هذا التبويب بإضافة ودجات قياسية أو ودجات التطبيقات إذا كانت مُتاحة. أمّا تبويب الإشعارات فيعرض جميع الإشعارات التي تصلك من التطبيقات، سواء وصل الإشعار أثناء استخدام الهاتف ولم تقم بفتحه، أو أثناء قفل الهاتف: تخصيص تبويب اليوم إذا كانت بعض ودجات تبويب اليوم تعرض معلومات غير مهمة بالنسبة لك، بإمكانك حذفها أو استبدالها بودجات أخرى. اسحب الستارة العلوية، انقر على تبويب اليوم، ثم انقر على زر تحرير Edit في الجزء السفلي منه: لحذف أحد الودجات، انقر على أيقونة (-) الحمراء المقابلة للودجت، ثم انقر على حذف Remove. لإضافة ودجت، انقر على أيقونة (+) الخضراء. لتغيير ترتيب الودجات في التبويب، اضغط على أيقونة التطابق (≡) واستخدم خاصية السحب والإفلات لتغيير موضعه. بعد الانتهاء من تخصيصه انقر على تم Done. كيف أقوم بتعطيل الوصول إلى مركز الإشعارات من شاشة القفل؟ يمكن لأي شخص قراءة الإشعارات على هاتفك بسحب الستارة من شاشة القفل حتّى وإن لم يكن يملك رمز المرور. فإذا كنت تريد المزيد من الخصوصية أو الأمان، بإمكانك تعطيل خاصية عرض الإشعارات من شاشة القفل. اذهب إلى الإعدادات Settings> Touch ID & Passcode> أدخل رمز المرور: انتقل إلى قسم السماح بالوصول عند القفل Allow Access when Locked ثم قم بتعطيل الخيار عرض الإشعارات Notification View. وبإمكانك أيضًا تعطيل خيار اليوم Today لإلغاء الوصول إلى مركز الإشعارات بالكامل من شاشة القفل: ما هي أنماط الإشعارات وكيف يمكنني تخصيصها؟ أثناء استخدام الهاتف، ستلاحظ وصول الإشعارات بنمطين مختلفين وبأصوات مختلفة. فعندما يتم تنبيهك على أمور اعتيادية مثل الرسائل النصية، رسائل التطبيقات، إشعارات التذكير التي ترسلها بعض التطبيقات، إشعارات الألعاب وغيرها، سيكون التنبيه عبر لافتة/شعار Banner تظهر في الجزء العلوي من شاشة الهاتف وتختفي تلقائيًا بعد مرور فترة قصيرة: عند النقر على هذه اللافتة سيتم نقلك إلى التطبيق المعني مباشرة. وبإمكانك إخفاء هذه اللافتة دون الانتقال إلى التطبيق بالنقر بخفّة على السهم في الجزء السفلي منها وسحبها إلى الأعلى. أما عندما يتم تنبيهك على أمور عاجلة وحساسة من ناحية الوقت كمنبّه الساعة، التذكيرات، إلخ، سيُعرض التنبيه بشكل نافذة منبثقة صغيرة تظهر على الشاشة ولا تختفي حتّى تقوم بإجراء يؤكّد على رؤيتك للتنبيه: يمكن تخصيص أنماط الإشعارات لكل تطبيق على حدة وحسب ما تراه مناسبًا لك. للقيام بذلك، اذهب إلى إعدادات Settings> الإشعارات Notification: ستجد قائمة تحتوي على جميع التطبيقات المثبتة على جهازك والتي ترسل الإشعارات. انقر على التطبيق الذي تريد تخصيص خيارات الإشعارات الخاصة به. ما يهمّنا هنا هو تغيير نمط التنبيه عندما يكون الهاتف غير مقفل. اختر النمط المرغوب: التنبيهات Alerts، الشعارات Banners، أو لا شيء None. كرّر هذه الخطوات على جميع التطبيقات التي تريد تخصيص أنماط الإشعارات الخاصة بها، لأنّه لا توجد طريقة لتغيير إعدادات جميع التطبيقات مرّة واحدة. كيف أمنع الإشعارات من الظهور على شاشة القفل؟ تُعرض الإشعارات التي تصلك عندما يكون الهاتف مقفلًا على شاشة القفل بالإضافة إلى مركز الإشعارات. لكن في بعض الأحيان يكون هذا الأمر غير مرغوب به خصوصًا من باب الخصوصية، لأنّ الإشعارات تكون قابلة للقراءة من قبل الجميع. فإذا كنت تريد منع الإشعارات من الظهور على شاشة القفل، اذهب إلى إعدادات Settings> الإشعارات Notifications ثم انقر على التطبيق الذي تريد منع إشعاراته من الظهور على شاشة القفل. بعدها قم بتعطيل الخيار إظهار في قفل الشاشة Show on Lock Screen: كيف أكتم أصوات الإشعارات؟ بنفس الطريقة، يمكنك جعل الإشعارات صامتة إذا كانت أصواتها تزعجك. من إعدادات الإشعارات انقر على التطبيق المطلوب ثم قم بتعطيل الخيار الأصوات Sounds: لا يمكن تعطيل الأصوات بصورة مباشرة كما في الخطوة أعلاه مع بعض التطبيقات، وخصوصًا التطبيقات القياسية. في هذه الحالة انقر على الأصوات من إعدادات إشعارات التطبيق ثم اختر لا شيء None من قائمة نغمات التنبيه: كيف أقوم بتعطيل إشعارات تطبيق معيّن كما أسلفنا الذكر، لا توجد طريقة لإيقاف إشعارات جميع التطبيقات مرّة واحدة، لذلك يجب أن تقوم بإيقافها لكل تطبيق على حدة. اذهب إلى إعدادات Settings> الإشعارات Notifications>انقر على التطبيق المطلوب> قم بتعطيل الخيار السماح بالإشعارات Allow Notifications. كيف استخدم خاصيّة عدم الإزعاج؟ عند تفعيل خاصية عدم الإزعاج Do Not Disturb سيتم تحويل جميع الإشعارات إلى صامتة مع الاحتفاظ بها في مركز الإشعارات. ويمكنك استخدامها في الأماكن والأوقات التي تحتاج فيها إلى الهدوء التام بدون أي مشتتات. تختلف خاصية عدم الإزعاج عن الوضع الصامت في أنّ الهاتف لن يصدر أي صوت، إضاءة أو اهتزاز عند تفعيلها، حتّى في حالة منبّه الساعة. بينما في الوضع الصامت سيتم كتم الصوت فقط (باستثناء منبّه الساعة)، ويمكن أن تضيء الشاشة أو يهتز الهاتف عند استلام إشعار ما. لتفعيل وضع عدم الإزعاج يدويًا اسحب الستارة السفلية، ثم انقر على أيقونة الهلال: يمكنك جدولة وضع عدم الإزعاج ليعمل بصورة تلقائية وفي أوقات محددة. اذهب إلى إعدادات Settings> عدم الإزعاج Do Not Disturb: قبل بتفعيل الخيار مُجدول Scheduled ثم حدد أوقات من From وإلى To: من نفس نافذة الإعدادات، بإمكانك استثناء المكالمات التي ترد من جهات اتصال محددة من وضع عدم الإزعاج. انقر على السماح بالمكالمات من Allow Calls From وحدد الخيار أو المجموعة التي تريد استثناءها. كما بإمكانك استثناء مكالمات الشخص الذي يتصل أكثر من مرة خلال ثلاث دقائق بتفعيل الخيار مكالمات متكررة Repeated Calls، وهذا من الخيارات المفيدة لتجنّب تفويت المكالمات التي قد تكون ضرورية أو عاجلة. وكما ذكرنا، أي إشعار يصلك أثناء استخدام وضع عدم الإزعاج سيتم الاحتفاظ به في مركز الإشعارات ويمكنك الوصول إليه وقتما تشاء.
  3. هل تحاول متابعة آخر التحديثات لعدِّة مشاريع على GitHub؟ إذًا أنت لست حديث العهد باستقبال العديد من الإشعارات حول: التبليغ عن العلل، ونشر تعليقات، وقبول طلبات إضافة (pull requests). تتطلب بعض الأمور السابقة تدخلًا منك، وعليك أن تعلم عن بعضها الآخر، والباقي مجرد ضوضاء. هذه مُرشِّحات (filters) لبريد Gmail التي أستعملها لكي أحصل على الإشعارات المفيدة بسرعة. لدى GitHub مركز إشعارات خاص به يسمح بترشيح الإشعارات لكل مشروع، بالإضافة إلى إظهار الإشعارات للأشياء التي تُشارِك فيها فقط. وكل إشعار له أيقونة خاصة به تُحدِّد ما إن كان مشكلةً أو طلبَ دمجٍ وسواءً بقي مفتوحًا/أو لم يُدمَج بعد. هذا مفيدٌ حقًا، ويقلل الوقت اللازم لتفقد اللائحة كل يوم؛ على سبيل المثال، ربما تريد تخطي المشكلات التي تم إغلاقها أو الطلبات التي تم دمجها، وتتطلع بسرعة على المشكلات التي لم تُذكَر فيها، وتُركِّز على ما أنت مشاركٌ فيه. ماذا لو كنت تفضل التعامل مع الإشعارات عبر البريد الإلكتروني؟ أنا أفضل أن يكون كل شيءٍ موجودًا في مكانٍ واحد في صندوق الوارد. لكني سأفوت على نفسي كل الميزات الموفرة للوقت التي يعطيني إياها مركز الإشعارات. لن يكون المرور على الإشعارات واحدًا واحدًا ذا إنتاجيةٍ عالية. لكن لحسن الحظ، يمكن جلب بعض ميزات مركز الإشعارات إلى بريدك الإلكتروني باستعمال "المرشحات" (filters)، وهذه هي المرشحات التي أستعملها مع Gmail. وسم جميع الإشعارات من GitHub لأنني أستقبل عددًا كبيرًا من الرسائل من GitHub، فأحب أن أوسمها (tag) جميعًا كي أميز بينها وبين الرسائل الأخرى بسهولة؛ ومن النادر أن تكون إشعارات GitHub ذات أولويةً عالية، ووسمها كلها سيسمح لي بإخفائها بسهولة كي أتأكد أنني لم أفوِّت رسالةً مهمةً. لضبط ما سبق، رشِّح حقل "From:‎" للبريد "notifications@github.com"، يبدو هذا في Gmail كالآتي: from:(notifications@github.com) التكليفات أحاول أن أهتم بما أنا مكلفٌ به، ولهذا أعلِّم تلك الرسائل بوسم "Assignment"، وعندما أكون مشغولًا، أنظر إلى هذه القائمة فقط لكي أتأكد أنَّ كل شيءٍ أنا مسؤولٌ عن إنجازه قد أُنجِز. عندما يُسنِد أحدهم مشكلةٍ إليك، فسيُرسِل GitHub تنبيهًا، ويمكن تعليم (أو توسيم) كامل الموضوع (thread) كتكليفٍ إليك عبر مطابقة هذه الرسالة التنبيهية. سيبدو مُرشِّح Gmail كالآتي (ابحث عن معرفك@ Assigned to): from:(notifications@github.com) Assigned to @pazdera هنالك بعض المحدوديات لهذه الطريقة لسوء الحظ، فلن يُرسَل إليك إشعارٌ إن أسندتَ المشكلة إلى نفسك ولن يُوسَّم الموضوع بشكلٍ صحيح في هذه الحالة؛ وإن أعيد إسناد المشكلة إلى شخصٍ آخر، فسيبقى الموضوع موسمًا على أنك مكلّف بالمشكلة. ذكر معرفك (Mentions) ربما هذا المرشح هو أكثرهم فائدةً لأنه يسمح لك برؤية الرسائل التي ذُكِرتَ فيها دون الحاجة إلى النظر إلى جميع الرسائل غير المهمة بحثًا عن مُعرِّفك على GitHub، فستعلم تمامًا أين طُلِبَت مداخلتك. استعمل مُرشِّحًا يطابق مُعرِّفك على GitHub في جسد الرسالة كما يلي: from:(notifications@github.com) @pazdera طلب pull request تم دمجه Merged لن تكون -في أغلب الأوقات- هنالك حاجةٌ لمداخلتك عندما يُدمج طلب Pull Request ويمكنك تجاوزها في أغلب الأحيان (خصيصًا إن لم تُذكَر في النقاش في طلب Pull Request ‏[PR]). يُرسِل GitHub إشعارًا يمكِّنك من إنشاء مُرشِّح لتوسيم الموضوع (thread) على أنه Merged. from:(notifications@github.com) Merged للأسف، لا يوجد دعم للتعابير النمطية (regular expressions) في Gmail، ولهذا سيُطابِق المرشح السابق التعليقات التي يذكر فيها صاحبها الكلمة "Merged". لكن -وإن كان يبدو ذلك مشكلةً كبيرةً- من النادر حدوث ذلك حسب تجربتي. مشكلة تم إغلاقها Closed في نهاية المطاف، من المفيد -عندما تُغلق مشكلة- أن تعرف عن ذلك دون الحاجة إلى النقر على الرسالة لفتحها. أستعمل المُرشِّح الآتي لتعليم كل تلك الرسائل للحذف مباشرةً. from:(notifications@github.com) Closed \# هذه هي المرشحات الخمسة التي تساعدني في التخلص من الكم الكبير من تنبيهات GitHub في بريدي. ما الذي تستعمله كيلا تقضي ساعاتٍ في بريدك؟ شارك ذلك في التعليقات أدناه. ترجمة -وبتصرّف- للمقال ‎5 Useful Gmail Filters for GitHub Users لصاحبه Radek Pazdera.
  4. في هذا المقال القصير سوف نصنع تنبيها مؤقتا بسيطا عبر CSS animations. ما سنفعله بالتحديد هو إظهار تنبيه بسيط أو عبارة ما أسفل الشاشة لمدة معينة، ثم إخفائها. وسوف سنعمل شريط تقدم (progress bar) لنعرف كم تبقى من الوقت ليختفي التنبيه. ستكون تنبيهات هذا الدرس من الشكل التالي: بالنسبة للهيكلة فسوف نستخدم div يحتوي على الرسالة وبداخله div آخر من أجل شريط التقدم: <div class="tn-box tn-box-color-1"> <p>Your settings have been saved successfully!</p> <div class="tn-progress"></div> </div>سيملك التنبيه tn-box. و tn-box-color-1. من أجل تحديد اللون، سوف نثبت الصندوق أسفل النافذة حتى يرتفع عندما يظهر: .tn-box { width: 360px; position: fixed; bottom: 20px; left: 20px; padding: 25px 15px; text-align: right; border-radius: 5px; box-shadow: 0 1px 1px rgba(0,0,0,0.1), inset 0 1px 0 rgba(255,255,255,0.6); opacity: 0; cursor: default; display: none; transform: translateY(30px) } .tn-box-color-1{ background: #ffe691; border: 1px solid #f6db7b; }أما بالنسبة لشريط التقدم فسنعطيه التالي: .tn-progress { width: 0; height: 4px; background: rgba(255,255,255,0.3); position: absolute; bottom: 5px; right: 2%; border-radius: 3px; box-shadow: inset 0 1px 1px rgba(0,0,0,0.05), 0 -1px 0 rgba(255,255,255,0.6); }في البداية، سيكون عرض شريط التقدم 0. في هذا المثال، أنا أستخدم checkbox من أجل إطلاق animation عندما يتم الضغط عليه: <input type="checkbox" class="fire-check"> <section> <div class="tn-box tn-box-color-1"> <p>شريط التقدم الجميل!</p> <div class="tn-progress"></div> </div> </section>الزر يسبق صندوق التنبيهات لذا نستطيع استخدام محدد ~ من أجل تحديد العنصر الذي يأتي بعده. وإذا أردت أن تتحكم بالأمر عبر جافاسكربت (عبر إضافة tn-box-active. )، فاستخدم التالي: .tn-box.tn-box-active { display: block; animation: fadeOut 5s cubic-bezier(0.4, 0, 0.2, 1) forwards; } .tn-box.tn-box-active .tn-progress { animation: runProgress 4s linear forwards 0.5s; }أما بالنسبة للحركية (animation) فهي كالتالي: @keyframes fadeOut { 0% { opacity: 0; } 10% { opacity: 1; transform: translateY(0px);} 90% { opacity: 1; transform: translateY(0px);} 99% { opacity: 0; transform: translateY(30px);} 100% { opacity: 0; } } @keyframes runProgress { 0% { width: 0%; background: rgba(255,255,255,0.3); } 100% { width: 96%; background: rgba(255,255,255,1); } }ما ستقوم به الـحركية (animation) هو إظهار الصندوق (عبر رفعه ورفع درجة الشفافية) ثم تكبير عرض شريط التقدم. حددنا عرض شريط التقدم إلى 96% (لأنه يبعد عن يمين الصندوق بـ 2% لذا نريده أن يتوقف قبل 2% من اليسار أيضا). مثال حيSee the Pen ZbzMWQ by Hsoub Academy (@HsoubAcademy) on CodePen. ملاحظة: شيء إضافي وجدت أنه من الجميل إضافته هو إيقاف animation عند تمرير المؤشر على الصندوق. ولكن للأسف، الأمر لم ينجح في chrome بينما نجح في فيرفكس. .tn-box:hover, .tn-box:hover .tn-progress{ animation-play-state: paused; }ترجمة -وبتصرف- للمقال: Timed Notifications with CSS Animations لصاحبه Mary Lou. حقوق الصورة البارزة: Designed by Freepik.