بحث باسم الموضوع المطلوب

الجيد يجب ان يكون تصميم UX

قابل للاستخدام Usable

منصف Equitable

ممتع Enjoyable

مفيد Useful


هذه هي الخصائص الأساسية التي تجعل تصميم تجربة المستخدم (UX) جيداً. لنوضح كل منها بشكل بسيط:


1.قابل للاستخدام (Usable): يجب أن يكون التصميم سهل الاستخدام ومفهوم، بحيث يستطيع المستخدم إنجاز مهامه بسهولة دون تعقيد أو حاجة لشرح طويل.


2.منصف (Equitable): يجب أن يكون التصميم مناسباً لمختلف أنواع المستخدمين، بغض النظر عن خلفياتهم أو قدراتهم، بمعنى أن يكون شاملاً ومتاحاً للجميع.


3.ممتع (Enjoyable): تجربة استخدام المنتج يجب أن تكون ممتعة ومرضية، بحيث يشعر المستخدم بالراحة والسرور أثناء التفاعل معه، مما يزيد من احتمال استخدامه مرة أخرى.


4.مفيد (Useful): يجب أن يقدم المنتج فائدة حقيقية ويحل مشكلة أو يحقق حاجة محددة للمستخدم، مما يجعله ضروريًا ومهمًا بالنسبة لهم.


التصميم الجيد يجمع بين هذه العناصر لتحقيق تجربة استخدام متكاملة ومتميزة.

شرح مبسط وسريع figma ui/ux

↢ ماذ يعني تصميم واجهه الاستخدام UI

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

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

↢ ماذا يعني تصميم تجربة المستخدم UX

تصميم تجربة المستخدم (UX) هو عملية تصميم منتج أو خدمة بحيث يقدم تجربة إيجابية ومفيدة للمستخدمين. يتعلق ذلك بكيفية تفاعل المستخدم مع المنتج، ويشمل دراسة احتياجاتهم، وتحليل سلوكهم، وتصميم الحلول التي تجعل استخدام المنتج سهلاً وممتعاً.

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

↢ الفرق بين UX و UI:
  • UI (واجهة المستخدم) يركز على التصميم البصري، مثل الألوان والأيقونات والخطوط.
  • UX (تجربة المستخدم) يركز على كيفية عمل التطبيق والتفاعل معه بشكل كامل، بحيث يكون بسيطاً ومفهوماً وسريعاً.
↢ علاقه تصميم واجهات الايتحدام وتجربة المستخدم

تصميم واجهات المستخدم (UI) وتصميم تجربة المستخدم (UX) مرتبطان ببعضهما بشكل كبير، حيث يكمل كل منهما الآخر لتحقيق منتج ناجح وممتع للاستخدام. يمكن توضيح العلاقة بينهما كالتالي:

1. تصميم تجربة المستخدم (UX): يركز على التخطيط الكلي للتجربة، ويشمل كيفية تنظيم المحتوى، وسير العمل داخل التطبيق، وتحديد أهداف المستخدم واحتياجاته. بعبارة أخرى، يهتم بتوفير تجربة سهلة ومنطقية بحيث يتمكن المستخدم من إنجاز مهامه دون تعقيدات. يقوم مصمم تجربة المستخدم بإنشاء خرائط تدفق المستخدم (User Flows) وهياكل الأسلاك (Wireframes) لتوضيح كيفية عمل التطبيق وتفاعله.

2. تصميم واجهات المستخدم (UI): يركز على الجانب البصري والجمالي، أي الشكل الذي يراه المستخدم عند استخدام التطبيق. يشمل ذلك تصميم الأزرار، الألوان، الخطوط، الأيقونات، والتفاصيل التي تجعل التطبيق جذاباً وسهل الاستخدام. بعد أن يحدد مصمم تجربة المستخدم كيفية عمل التطبيق، يأتي دور مصمم الواجهة ليجعل هذه التجربة مرئية وملموسة.

↢ العلاقة بينهما:

  • تجربة المستخدم (UX) تهتم بـ "كيف يعمل التطبيق؟" و "ما الذي يجعل المستخدم يشعر بالراحة أثناء استخدامه؟".
  • واجهة المستخدم (UI) تهتم بـ "كيف يبدو التطبيق؟" و "ما الذي يجعل المستخدم يستمتع برؤية واستخدام الواجهة؟".
لذلك، لتحقيق منتج ناجح، يجب أن تكون تجربة المستخدم مصممة بشكل جيد ومتناسق مع واجهة المستخدم، بحيث تكون سهلة الاستخدام وجميلة المظهر في نفس الوقت.


↢ اهميه تصميم تجربه المستخدم وواجهه الاستخدام وللاعمال والمنتجات

تصميم تجربة المستخدم (UX) وواجهة المستخدم (UI) مهم جداً للأعمال والمنتجات لأنه يساعد في جذب المستخدمين وإبقائهم لفترة أطول. تصميم تجربة المستخدم الجيد يجعل المنتج سهلاً وممتعاً للاستخدام، مما يزيد من رضا العملاء وولائهم، بينما يساهم تصميم واجهة المستخدم الجذاب في جذب انتباه المستخدمين وتشجيعهم على التفاعل مع المنتج.

⇐ باختصار، تصميم UX/UI يساعد في:

  • زيادة المبيعات: تجربة مستخدم جيدة تشجع الناس على استخدام المنتج وشرائه.
  • رفع مستوى رضا العملاء: واجهة سهلة وجميلة تجعل المستخدمين سعداء وراضين.
  • بناء ولاء للعلامة التجارية: تجربة استخدام ممتازة تعزز الثقة وتجعل العملاء يعودون للمنتج مرة أخرى.
↢ ماذا احتاج كي اكون مصمم تجربه المستخدم وواجهه الاستخدام

لتصبح مصمم تجربة المستخدم وواجهة المستخدم (UX/UI)، تحتاج إلى اكتساب مجموعة من المهارات والمعرفة في مجالات مختلفة. إليك بعض الخطوات التي يمكن أن تساعدك:

1.تعلم الأساسيات:
  • مبادئ التصميم: فهم أساسيات التصميم مثل التوازن، الألوان، التباين، والتسلسل الهرمي.
  • تصميم تجربة المستخدم (UX): تعلم كيفية تحليل احتياجات المستخدمين، وإنشاء خرائط التدفق، والنماذج الأولية، وتجربة التصميم.
2.استخدام أدوات التصميم:

  • تعلم كيفية استخدام أدوات التصميم الشهيرة مثل Figma، Sketch وغيرها لتصميم واجهات المستخدم والنماذج الأولية.
3.تحليل سلوك المستخدم:

  • فهم كيفية البحث عن المستخدمين واختبار التصاميم بناءً على تجاربهم الفعلية.
4.مهارات التواصل:

  • القدرة على توصيل الأفكار والتصاميم بشكل فعال مع فريق العمل والعملاء.

5.الاطلاع على أفضل الممارسات:

  • متابعة تصاميم التطبيقات والمواقع الشهيرة، ومعرفة أحدث الاتجاهات في تصميم UX/UI.

6.التدريب والممارسة:

  • تنفيذ مشاريع صغيرة أو تجريبية لتحسين مهاراتك، مثل إعادة تصميم واجهات لتطبيقات موجودة أو إنشاء نماذج أولية لأفكار جديدة.
من خلال تطوير هذه المهارات، ستتمكن من بناء أساس قوي لتصبح مصمم UX/UI محترف.

⚠️ فكر مرتين قبل أن تطلب من الـChatGPT كتابة رسالة البريد الإلكتروني لك

إذا كنت تستخدم ChatGPT في عملك، فمن 

المحتمل أنك لاحظت مدى فائدته .

سواء كان كتابة البريد الإلكتروني الغريب أو تحليل جدول بيانات أو توليد الأفكار، يمكن أن توفر لك أداة الذكاء الاصطناعي هذه الوقت والجهد .

ولكن، مثل أي أداة قوية، تأتي بمخاطرها الخاصة .

أحد الشواغل الكبيرة هو كيف يتعلم ChatGPT من البيانات المقدمة .


دعنا نتعمق في سبب أهمية هذا وما تحتاج إلى الانتباه إليه .


💡فوائد استخدام ChatGPT


أولا، دعنا نتحدث عن الأشياء الجيدة .

يمكن لـ ChatGPT:

✔️ كتابة رسائل البريد الإلكتروني: هل تحتاج إلى إرسال ملاحظة سريعة أو بريد إلكتروني للمتابعة؟ يمكن لـ ChatGPT صياغته لك في ثوان .

✔️ تحليل البيانات: هل لديك جدول بيانات يحتاج إلى الفرز أو التحليل؟ يمكن أن يساعد ChatGPT في فهم أرقامك .

✔️ توليد الأفكار: عالق في جلسة العصف الذهني؟ يمكن أن يقدم ChatGPT أفكارا ووجهات نظر جديدة .


هذه مجرد طرق قليلة يمكن لـ ChatGPT أن تجعل مهامك اليومية أسهل .


⚠️ الخطر الكبير : حساسية البيانات


يتعلم ChatGPT من البيانات التي يعالجها .

هذا يعني أن لصق المعلومات الحساسة فيها أمر محفوف بالمخاطر .

تخيل كتابة خوارزمية سرية لشركتك أو بيانات العملاء الطبية أو غيرها من المعلومات السرية .

من المحتمل استخدام هذه البيانات لتدريب الذكاء الاصطناعي، مما قد يكون له آثار خطيرة .


ماذا يعني "التدريب"؟


عندما نقول إن ChatGPT "يتدرب" على البيانات، فإننا نعني أنه يتعلم من المدخلات التي يتلقاها لتحسين استجاباته.

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

ومع ذلك، فإن هذا يعني أيضا أن أي معلومات حساسة مقدمة يمكن أن تكون جزءا من عملية التعلم هذه .


💡💭 فكر قبل أن تلصق بياناتك


قبل لصق هذا الجزء المهم من المعلومات في ChatGPT، اسأل نفسك :

✔️ هل هذه البيانات سرية؟ إذا كانت الإجابة بنعم، فكر مرتين .

✔️ هل يمكن لهذه المعلومات أن تضر بعملي إذا تم تسريبها؟ إذا كانت الإجابة بنعم، فمن الأفضل عدم مشاركتها .

✔️ هل ستكون مرتاحا لوجود هذه المعلومات في المجال العام؟ إذا لم يكن الأمر كذلك، فأبقه بعيدا عن ChatGPT .


نصائح عملية للبقاء آمنا


إليك بعض النصائح البسيطة لمساعدتك في استخدام ChatGPT بأمان .

* تجنب البيانات الحساسة .

لا تقم بإدخال معلومات تجارية شخصية أو طبية أو مالية أو خاصة حساسة .

* استخدم بيانات مجهولة المصدر. 

إذا كنت بحاجة إلى استخدام بيانات حقيقية، فتأكد من أنها مجهولة الهوية .

قم بإزالة الأسماء والعناوين وأي تفاصيل تعريف أخرى .

* راجع سياسات الخصوصية .

فهم سياسات الخصوصية لأي أداة ذكاء اصطناعي تستخدمها. تعرف على البيانات المخزنة وكيفية التعامل معها .

* قم بتدريب فريقك .

تأكد من أن موظفيك على دراية بالمخاطر وفهم أنواع المعلومات التي لا ينبغي مشاركتها باستخدام أدوات الذكاء الاصطناعي .


🗓️ الخلاصة: استخدم بحكمة، ابق آمنا


يمكن أن يكون ChatGPT مساعدا رائعا، ولكن تذكر: مع القوة العظيمة تأتي مسؤولية كبيرة .

من خلال مراعاة البيانات التي تشاركها واتخاذ خطوات لحماية المعلومات الحساسة، يمكنك الاستمتاع بفوائد ChatGPT مع الحفاظ على أمان عملك .


ثورة في التواصل: جيميني يرتقي بتجربتك على واتساب إلى آفاق جديدة

أعلنت جوجل عن خطوة ثورية جديدة تعيد تعريف طريقة تفاعلك مع واتساب فمن خلال تكامل عميق مع مساعدها الذكي Gemini، يصبح واتساب أكثر من مجرد تطبيق للدردشة بل يصبح مساعدًا شخصيًا ذكيًا قادرًا على مساعدتك في العديد من المهام اليومية. دعونا نستكشف معًا أبرز الميزات التي يقدمها هذا التكامل المذهل


أبرز الميزات الجديدة

كتابة الرسائل تلقائيًا:

  • استخدام جيميناي لكتابة رسائل احترافية وجذابة نيابة عن المستخدم.
  • اقتراح ردود سريعة على الرسائل الواردة.
  • ترجمة الرسائل إلى لغات مختلفة.
  • التذكير بالمواعيد والمهام:
  • إضافة مواعيد وتذكير مباشرة في المحادثات.
  • تلقي تنبيهات قبل المواعيد الهامة.
  • إدارة المهام اليومية بسهولة.


البحث في المحادثات:

  • البحث السريع عن رسائل معينة أو ملفات تم مشاركتها.
  • تنظيم المحادثات وتصنيفها حسب الموضوع.
  • التكامل مع تطبيقات جوجل الأخرى:
  • الوصول إلى خدمات جوجل الأخرى مثل Google Calendar و Google Maps مباشرة من خلال واتساب.
  • حجز المطاعم أو الفنادق أو طلب سيارات الأجرة.

تحسين تجربة المستخدم:

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

لتفعيل الميزه يجب ان يكون لديك احدث نسخه من وتساب وجيميني


خاتمة:


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

كيفية اكتشاف ما إذا كان تطبيق Flutter موجودًا في الخلفية

في Flutter، توجد طرق متعددة للكشف عما إذا كان التطبيق في الخلفية أم في المقدمة. يتيح لك اكتشاف هذه الحالات تنفيذ إجراءات محددة بناءً على ما إذا كان التطبيق قيد الاستخدام النشط (في المقدمة) أو غير مرئي ولا يتلقى إدخال المستخدم (في الخلفية). في هذا المنشور، سنغطي طريقتين لتحديد ما إذا كان التطبيق في الخلفية أم في المقدمة.

استخدم WidgetsBindingObserver

النهج الأول هو استخدام WidgetsBindingObserverالفئة للكشف عما إذا كان تطبيق Flutter في الخلفية أم في المقدمة. يمكن لهذه الفئة ملاحظة التغييرات في دورة حياة التطبيق من خلال didChangeAppLifecycleStateالطريقة، التي توفر الوصول إلى AppLifecycleState.

يمكن استخدام الفئة WidgetsBindingObserverكمزيج باستخدام withالكلمة الأساسية. لذلك، سنقوم بإنشاء عنصر واجهة مستخدم جديد يسمى BackgroundDetectorيستخدم هذا المزيج.

كاشف الخلفية. دارت

(C)

import 'dart:ui';

import 'package:flutter/material.dart';

class BackgroundDetector extends StatefulWidget {
  const BackgroundDetector({
    required this.child,
    super.key,
  });

  final Widget child;

  @override
  State<BackgroundDetector> createState() => _BackgroundDetectorState();
}

class _BackgroundDetectorState extends State<BackgroundDetector>
    with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) =>
      print('\x1B[34m $state \x1B[0m');

  @override
  Widget build(BuildContext context) {
    return widget.child;
  }
}

(C)

في مقتطف التعليمات البرمجية هذا، قمنا بإنشاء BackgroundDetectorعنصر واجهة مستخدم بحالة. _BackgroundDetectorStateتستخدم الفئة WidgetsBindingObserverالفئة كمزيج مع withالكلمة الأساسية.

في _BackgroundDetectorState، نتجاوز ثلاث وظائف: initStateو dispose، و didChangeAppLifecycleState.

تتوفر الدالتان and دائمًا للأدوات ذات الحالة. نستخدم الدالة initStateلإضافة المراقب والدالة لإزالته بمجرد التخلص من الأداة.disposeinitStatedispose

تم تجاوز الوظيفة didChangeAppLifecycleStateحتى نتمكن من الوصول إلى AppLifecycleState. يتم استدعاء هذه الطريقة كلما تغيرت حالة دورة حياة التطبيق. في الوقت الحالي، نقوم فقط بطباعة حالة دورة الحياة الحالية.

أخيرًا، BackgroundDetectorتتطلب الأداة childعنصر واجهة مستخدم سيتم إرجاعه.

في هذه didChangeAppLifecycleStateالوظيفة، تستخدم عبارة الطباعة أكواد الهروب ANSI لإضافة الألوان في واجهة سطر الأوامر. هذا التلوين مخصص لأغراض العرض التوضيحي فقط.


الرئيسية.دارت

 (C)

import 'package:application_in_background_demo/background_detector.dart';

import 'package:flutter/material.dart';


void main() => runApp(const BackgroundDetector(child: MyApp()));


class MyApp extends StatelessWidget {

  const MyApp({super.key});


  @override

  Widget build(BuildContext context) {

    return const MaterialApp(

      home: Scaffold(),

    );

  }

}


(C)

في main.dartالملف، قمنا بتغليف MyAppالأداة باستخدام BackgroundDetectorالأداة الخاصة بنا. من خلال تغليف تطبيقنا بالكامل بالفئة BackgroundDetector، فسوف يتم دائمًا اكتشاف ما إذا كان التطبيق في الخلفية أم في المقدمة.

راجع ملف GIF أدناه لترى ذلك أثناء العمل. في واجهة سطر الأوامر، نقوم بطباعة حالة دورة حياة التطبيق الحالية في كل مرة تتغير فيها.


تغيير دالة DidChangeAppLifecycleState

بدلاً من طباعة كل شيء، AppLifecycleStateمن الأفضل تنفيذ الإجراءات على حالات معينة فقط. في هذه الحالة، سنغير الوظيفة didChangeAppLifecycleStateلتنفيذ الإجراء على الحالة resumedو فقط paused.

(C)

@override

void didChangeAppLifecycleState(AppLifecycleState state) {

  if (state == AppLifecycleState.resumed) {

    print('\x1B[34m App in foreground\x1B[0m');

  }


  if (state == AppLifecycleState.paused) {

    print('\x1B[33m App in background\x1B[0m');

  }

}

(C)


في مثال الكود هذا، نستخدم AppLifecycleStateالتعداد للكشف عما إذا كانت الحالة الحالية تساوي الحالة التي نريد التصرف بها. resumedتعني الحالة أن التطبيق موجود في المقدمة pausedوتعني الحالة أن التطبيق موجود في الخلفية.


إذا قمنا بتشغيل تطبيقنا مرة أخرى، ستلاحظ أننا الآن ننفذ الإجراءات على الحالة resumedو فقط paused.

الحالات المختلفة لـ AppLifecycleState Enum

حتى الآن، استخدمنا اثنين من الإدخالات الخمسة من AppLifecycleStateالتعداد، الذي يمثل الحالات المختلفة التي يمكن أن يوجد بها التطبيق. فيما يلي قائمة تشرح كل حالة:


  1. detached:يتم تشغيل التطبيق بدون شاشة مرئية في تلك اللحظة المحددة. إما أنه في عملية عرض شيء ما لأول مرة أو بعد إخفاء الشاشة مؤقتًا وقبل أن تصبح مرئية مرة أخرى.
  2. hidden:يتم إخفاء كافة وجهات نظر التطبيق.
  3. inactive:يتم إخفاء التطبيق جزئيًا بواسطة تطبيق آخر أو ورود مكالمة هاتفية. في هذه الحالة، قد يظل التطبيق مرئيًا ولكنه لا يتلقى إدخال المستخدم.
  4. paused:التطبيق موجود في الخلفية ولا يمكن للمستخدم رؤيته. قد يحدث ذلك عندما يقوم المستخدم بالتبديل إلى تطبيق آخر أو عندما ينتقل الجهاز إلى وضع السكون.
  5. resumed:التطبيق موجود في المقدمة ويمكن للمستخدم رؤيته. إنه الحالة النشطة حيث يمكن للمستخدم التفاعل مع التطبيق


باستخدام WidgetsBindingObserverclass و AppLifecycleStateenum، يمكنك بسهولة تتبع حالة دورة حياة التطبيق. ومع ذلك، هناك نهج بديل يمكنك اتباعه لمراقبة حالة دورة حياة التطبيق باستخدام حزمة Flutter FGBG.

إشعار بحدث المقدمة/الخلفية في Flutter

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

تركز حزمة Flutter FGBG فقط على تطبيقك وتلاحظ بدقة متى ينتقل إلى الخلفية أو المقدمة. وهي تفعل ذلك بشكل مختلف بالنسبة لنظامي التشغيل iOS وAndroid للتأكد من صحة الملاحظات.


تثبيت حزمة Flutter FGBG

للبدء في التنفيذ، نحتاج أولاً إلى تثبيت  حزمة  Flutter FGBG  في مشروعنا . يمكننا تثبيت الحزمة من خلال تنفيذ الأمر التالي داخل مشروعنا:

(C)

flutter pub add flutter_fgbg

(C)

بمجرد تنفيذ الأمر، تأكد من التحقق من ملفك pubspec.yamlبحثًا عن التبعيات المضافة. يجب أن ترى حزمة Flutter FGBG مضمنة في قسم التبعيات، مثل هذا:


(C)

dependencies:

  flutter_fgbg: ^0.3.0

(C)

تنفيذ فئة FGBGNotifier

توفر حزمة Flutter FGBG FGBGNotifierعنصر واجهة مستخدم يستخدم للاستماع إلى الأحداث في المقدمة والخلفية. عندما تتغير حالة دورة حياة التطبيق، onEventيتم تشغيل معاودة الاتصال. يتيح لنا هذا تنفيذ إجراءات محددة بناءً على الحالة الحالية للتطبيق.

(C)

import 'package:flutter/material.dart';

import 'package:flutter_fgbg/flutter_fgbg.dart';


void main() => runApp(

  FGBGNotifier(

    onEvent: (FGBGType type) => switch (type) {

      FGBGType.foreground => print('\x1B[34mApp in the foreground (FGBGNotifier)\x1B[0m'),

      FGBGType.background => print('\x1B[33mApp in the background (FGBGNotifier)\x1B[0m'),

    },

    child: const MyApp(),

  ),

);


class MyApp extends StatelessWidget {

  const MyApp({super.key});


  @override

  Widget build(BuildContext context) {

    return const MaterialApp(

      home: Scaffold(),

    );

  }

}

(C)

في main.dartالملف المحدث، قمنا بتنفيذ FGBGNotifierعنصر واجهة المستخدم. يحتاج هذا العنصر إلى onEventخاصية، والتي تأخذ دالة استدعاء تتلقى قيمة من FGBGTypeالتعداد. يحتوي التعداد على قيمتين: foregroundو background.


داخل معاودة الاتصال، نستخدم ifعبارة بسيطة لطباعة رسائل مختلفة بناءً على النوع المستلم. بالإضافة إلى ذلك، FGBGNotifierتأخذ الأداة رمزًا child، وفي هذه الحالة، نضبط MyAppالأداة باعتبارها الطفل.


عندما نقوم بتشغيل التطبيق، سنحصل على نفس السلوك كما في النهج السابق. ومع ذلك، تعمل هذه الحزمة على تبسيط التنفيذ ولا تبلغ إلا عن الأحداث على https://pub.dev/packages/flutter_fgbg#why مستوى التطبيق .


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

(C)
FGBGEvents.ignoreWhile(() {
  // your function
});
(C)

خاتمة
يكتشف كلا النهجين بنجاح ما إذا كان التطبيق في الخلفية أم في المقدمة. يستخدم النهج الأول WidgetsBindingObserverو AppLifecycleStateلمراقبة سلوك التطبيق. النهج الثاني أبسط ويستخدم حزمة Flutter FGBG، التي توفر FGBGNotifierأداة لتتبع الأحداث في الخلفية والمقدمة.

القائمة النهائية لإضافات المتصفح لصائدي الثغرات browser extensions for bugs hunters

في مجال الأمن السيبراني يعد البحث عن الأخطاء البرمجية أمرًا بالغ الأهمية لتأمين التطبيقات والأنظمة .


إن استخدام الأدوات المناسبة، وخاصة ملحقات المتصفح، يمكن أن يعزز من فعاليتك وكفاءتك .

فيما يلي قائمة بالملحقات الأساسية التي يجب أن يمتلكها كل صائد الثغرات البرمجية .


Wappalyzer:  أداة تحليل التكنولوجيا التي تحدد التقنيات المستخدمة في مواقع الويب، من CMS إلى مكتبات JavaScript .


WhatRuns:  يكشف عن التقنيات والأطر والخدمات التي يستخدمها موقع الويب، مما يوفر طبقة أخرى من الفهم للثغرات الأمنية المحتملة


https://chromewebstore.google.com/detail/whatruns/cmkdbmfndkfgebldhnkbfhlneefdaaip


Hackbar:  ملحق للمتصفح لاختبار الاختراق، متوفر لمتصفحي Chrome وFirefox


https://addons.mozilla.org/en-US/firefox/addon/hackbar-free/versions/


FoxyProxy :  قياسي قم بتبسيط الوصول إلى خادم الوكيل في المتصفحات باستخدام القواعد وخيارات التبديل السريع


https://addons.mozilla.org/en-US/firefox/addon/foxyproxy-standard/


مجموعة اختبار الاختراق OWASP : قم بتبسيط أمان التطبيق باستخدام فحص DAST وSCA داخل المتصفح بحثًا عن الثغرات الأمنية


https://chromewebstore.google.com/detail/owasp-penetration-testing/ojkchikaholjmcnefhjlbohackpeeknd


KNOXSS Community Edition: أداة لاكتشاف 

XSS (Cross-Site Scripting)


https://addons.mozilla.org/ar/firefox/addon/knoxss-community-edition/


Retire.js:  فحص تطبيقات الويب بحثًا عن مكتبات JavaScript المعرضة للخطر وتحديد الإصدارات القديمة


https://addons.mozilla.org/en-US/firefox/addon/retire-js/


Trufflehog:  ملحق للكشف التلقائي عن مفاتيح API وبيانات الاعتماد على مواقع الويب


https://addons.mozilla.org/en-US/firefox/addon/trufflehog/


DotGit:  اكتشاف أدلة .git المعرضة للخطر وغيرها من الثغرات الأمنية في مواقع الويب التي تمت زيارتها.


https://addons.mozilla.org/ar/firefox/addon/dotgit/


Bishop Vulnerability Scanner فحص الخلفية لأنظمة التحكم في الإصدار المكشوفة وأدوات الإدارة التي تم تكوينها بشكل غير صحيح


https://chromewebstore.google.com/detail/bishop-vulnerability-scan/cbkdeoaaclnbidadjimofnhpbfhjakoe


Modheader: تعديل رؤوس HTTP ورؤوس الاستجابة وعناوين URL باستخدام الخيارات المتقدمة لمتصفحي Chrome و Firefox


https://addons.mozilla.org/en-US/firefox/addon/modify-header-value/


HackTools:  تسهيل اختبارات اختراق تطبيقات الويب باستخدام أوراق الغش والأدوات مثل حمولات XSS والأصداف العكسية


https://addons.mozilla.org/en-US/firefox/addon/hacktools/


Request Maker : التقاط وتعديل وإرسال طلبات HTTP لاختبار الاختراق والتحليل


https://addons.mozilla.org/en-US/firefox/addon/http-request-maker/


 Shodan:  ابحث عن مكان استضافة مواقع الويب، ومالكي IP، والخدمات/المنافذ المفتوحة


https://addons.mozilla.org/en-US/firefox/addon/shodan-addon/


Open Multiple URLs  افتح صفحات ويب متعددة في علامات تبويب جديدة من قائمة نصية عادية


https://chromewebstore.google.com/detail/open-multiple-urls/oifijhaokejakekmnjmphonojcfkpbbh?hl=ar


Cookie-Editor  إنشاء ملفات تعريف الارتباط وتحريرها وحذفها للعلامة التبويب الحالية، وهو مثالي للخصوصية والتطوير


https://addons.mozilla.org/en-US/firefox/addon/cookie-editor/


Mitaka : ابحث عن عنوان IP والنطاق وعنوان URL والهاش والمزيد عبر قائمة السياق باستخدام امتداد المتصفح هذا


https://addons.mozilla.org/en-US/firefox/addon/mitaka/


 D3coder: ملحق لترميز وفك تشفير النص باستخدام base64 وrot13 والمزيد


https://addons.mozilla.org/en-US/firefox/addon/encoder-decoder/


Redirect Path:  يتتبع عمليات إعادة توجيه HTTP للكشف عن مسارات إعادة التوجيه غير الآمنة وأكواد الحالة


https://addons.mozilla.org/en-US/firefox/addon/redirect-url-path/

كيفية عرض مقاطع فيديو YouTube في Flutter

يعد عرض مقاطع فيديو YouTube في تطبيق Flutter أمرًا سهلاً باستخدام المكون الإضافي المناسب. في هذا المنشور، ستتعلم كيفية استخدام مكون Youtube Player Flutter الإضافي لإضافة مقاطع فيديو YouTube إلى تطبيقك. سنغطي كل ما تحتاج إلى معرفته، من الإعداد والتخصيص إلى معالجة المشكلات الشائعة مع المكون الإضافي.

إضافة Flutter لمشغل YouTube


لبدء عرض مقاطع فيديو YouTube في Flutter، نحتاج أولاً إلى تثبيت  مكون https://pub.dev/packages/youtube_player_flutter Youtube Player Flutter  في مشروعنا. يتيح هذا المكون الإضافي البث المباشر لمقاطع فيديو YouTube ويستخدم واجهة برمجة تطبيقات مشغل IFrame الرسمية الخاصة بـ YouTube https://developers.google.com/youtube/iframe_api_reference?hl=ar . وهو متوافق مع كل من منصتي Android وiOS.

تثبيت البرنامج الإضافي Youtube Player Flutter
يمكننا تثبيت البرنامج الإضافي عن طريق تنفيذ الأمر التالي داخل مشروعنا:
<C>
flutter pub add youtube_player_flutter:^8.1.2
<C>

السبب الذي يجعلنا نحدد إصدارًا محددًا هو أن الإصدار الأحدث https://pub.dev/packages/youtube_player_flutter/versions/9.0.2 ، وقت كتابة هذا التقرير، يحتوي على خطأ https://github.com/sarbagyastha/youtube_player_flutter/issues/955 يتسبب في ظهور شريط تحميل بشكل مستمر في الفيديو.

الرئيسية.دارت

<C>

dependencies:

  youtube_player_flutter: ^8.1.2

<C>


تنفيذ البرنامج الإضافي لمشغل اليوتيوب

لتنفيذ مكون Youtube Player Flutter، سنقوم بإنشاء YoutubePageعنصر واجهة مستخدم في ملف Dart منفصل باسم . سيتم بعد ذلك عرض youtube_page.dartهذا العنصر باستخدام سمة العنصر في الملف.YoutubePagehomeMaterialAppmain.dart

<C>

import 'package:flutter/material.dart';

import 'package:youtube_videos_demo/youtube_page.dart';


void main() => runApp(const MyApp());


class MyApp extends StatelessWidget {

  const MyApp({super.key});


  @override

  Widget build(BuildContext context) {

    return const MaterialApp(

      home: YoutubePage(),

    );

  }

}

<C>

في main.dartالملف، نقوم بإرجاع عنصر واجهة المستخدم الخاص بالتطبيق MaterialApp. داخل MaterialAppعنصر واجهة المستخدم، نستخدم homeالسمة لعرض YoutubePageعنصر واجهة المستخدم.


صفحة اليوتيوب.دارت

<C>
import 'package:flutter/material.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';

class YoutubePage extends StatefulWidget {
  const YoutubePage({super.key});

  @override
  State<YoutubePage> createState() => _YoutubePageState();
}

class _YoutubePageState extends State<YoutubePage> {
  final YoutubePlayerController _controller = YoutubePlayerController(
    initialVideoId: 'PAOAjOR6K_Q',
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: YoutubePlayer(
          controller: _controller,
        ),
      ),
    );
  }
}
<C>

في youtube_page.dartالملف، نبدأ بإنشاء عنصر واجهة مستخدم بحالة. داخل حالة العنصر، نقوم بتعريف _controllerمتغير خاص يحمل مثيلًا لـ YoutubePlayerController. في هذه الحالة، نقوم بتعيين initialVideoIdالسمة إلى معرف الفيديو الذي نريد عرضه. أخيرًا، نقوم بإرجاع عنصر YoutubePlayerواجهة مستخدم، مع تعيين _controllerالمتغير إلى controllerسماته.

يمكنك بسهولة العثور على معرف الفيديو في عنوان URL لمقطع فيديو YouTube الذي تريد عرضه. يقع المعرف بعد watch?v=عنوان URL. على سبيل المثال، في عنوان URL https://www.youtube.com/watch?v=PAOAjOR6K_Q، يكون معرف الفيديو هو PAOAjOR6K_Q.

كما هو موضح في لقطة الشاشة أعلاه، يمكننا عرض مقاطع فيديو YouTube في Flutter باستخدام قدر صغير فقط من التعليمات البرمجية.


تجنب تسربات الذاكرة

ولمنع تسرب الذاكرة، من الضروري التخلص من وحدة التحكم بشكل صحيح عندما لا تكون هناك حاجة إليها بعد الآن.

<C>

import 'package:flutter/material.dart';

import 'package:youtube_player_flutter/youtube_player_flutter.dart';


class YoutubePage extends StatefulWidget {

  const YoutubePage({super.key});


  @override

  State<YoutubePage> createState() => _YoutubePageState();

}


class _YoutubePageState extends State<YoutubePage> {

  final YoutubePlayerController _controller = YoutubePlayerController(

    initialVideoId: 'PAOAjOR6K_Q',

  );


  @override

  void dispose() {

    _controller.dispose();

    super.dispose();

  }


  @override

  Widget build(BuildContext context) {

    return Scaffold(

      body: Center(

        child: YoutubePlayer(

          controller: _controller,

        ),

      ),

    );

  }

}

<C>

في مقتطف التعليمات البرمجية أعلاه، نتخلص من الدالة _controllerعن طريق استدعاء دالة disposeداخل disposeالدالة التي تم تجاوزها. عند استخدام disposeالدالة التي تم تجاوزها، تأكد دائمًا من استدعاء الدالة super.disposeالأخيرة.


إضافة YoutubePlayerFlags

بالإضافة إلى initialVideoIdسمة YoutubePlayerController، يمكننا أيضًا استخدام flagsالسمة. تتيح لنا هذه السمة تعيين مثيل للفئة YoutubePlayerFlagsلتخصيص كيفية تصرف اللاعب.

<C>

final YoutubePlayerController _controller = YoutubePlayerController(

  initialVideoId: 'PAOAjOR6K_Q',

  flags: const YoutubePlayerFlags(

    forceHD: true,

    endAt: 20,

    enableCaption: false,

    hideThumbnail: true,

  ),

);

<C>

في مقتطف التعليمات البرمجية هذا، أضفنا flagsالسمة إلى YoutubePlayerControllerمثيل المتغير _controller. على flagsالسمة، قمنا بتعيين مثيل للفئة YoutubePlayerFlagsوأضفنا أربع سمات لفرض الدقة العالية وإنهاء الفيديو بعد 20 ثانية وتعطيل التسميات التوضيحية وإخفاء الصورة المصغرة.

تخصيص الإجراءات السفلية والعلوية

داخل YoutubePlayer، يمكننا أيضًا تخصيص الإجراءات السفلية والعلوية. راجع المثال أدناه:

<C>

import 'package:flutter/material.dart';

import 'package:youtube_player_flutter/youtube_player_flutter.dart';


class YoutubePage extends StatefulWidget {

  const YoutubePage({super.key});


  @override

  State<YoutubePage> createState() => _YoutubePageState();

}


class _YoutubePageState extends State<YoutubePage> {

  final YoutubePlayerController _controller = YoutubePlayerController(

    initialVideoId: 'PAOAjOR6K_Q',

  );


  @override

  void dispose() {

    _controller.dispose();

    super.dispose();

  }


  @override

  Widget build(BuildContext context) {

    return Scaffold(

      body: Center(

        child: YoutubePlayer(

          bottomActions: [

            const SizedBox(width: 14),

            CurrentPosition(),

            const SizedBox(width: 8),

            ProgressBar(

              isExpanded: true,

              colors: const ProgressBarColors(

                playedColor: Color(0xFFFF0000),

                handleColor: Color(0xFFFF0000),

                backgroundColor: Colors.grey,

              ),

            ),

            RemainingDuration(),

          ],

          controller: _controller,

          topActions: const [

            PlaybackSpeedButton(),

          ],

        ),

      ),

    );

  }

}

<C>

في مقتطف التعليمات البرمجية أعلاه، قمنا بتخصيص كل من الإجراءات السفلية والعلوية لعلامتي YoutubePlayer. بالنسبة للإجراءات السفلية، قمنا بتضمين CurrentPositionالمؤشر وعلامة ProgressBar, والمؤشر RemainingDuration. لقد استخدمنا SizedBoxعناصر واجهة المستخدم لإضافة مسافات بين هذه العناصر وضبطنا ProgressBarألوان عناصر واجهة المستخدم لتتوافق مع مشغل YouTube الأصلي.

تخصيص مشغل اليوتيوب

لمزيد من المرونة، يمكننا استخدام YoutubePlayerBuilderالفئة لتخصيص المشغل. يوفر هذا النهج تحكمًا أكبر في سلوك المشغل، وخاصةً عند دخوله أو خروجه من وضع ملء الشاشة.

<C>

import 'package:flutter/material.dart';

import 'package:youtube_player_flutter/youtube_player_flutter.dart';


class YoutubePage extends StatefulWidget {

  const YoutubePage({super.key});


  @override

  State<YoutubePage> createState() => _YoutubePageState();

}


class _YoutubePageState extends State<YoutubePage> {

  final YoutubePlayerController _controller = YoutubePlayerController(

    initialVideoId: 'PAOAjOR6K_Q',

  );


  @override

  void dispose() {

    _controller.dispose();

    super.dispose();

  }


  @override

  Widget build(BuildContext context) {

    final size = MediaQuery.of(context).size;

    final width = size.width;

    final height = size.height;


    return Scaffold(

      body: Center(

        child: OrientationBuilder(

          builder: (BuildContext context, Orientation orientation) =>

              YoutubePlayerBuilder(

            builder: (BuildContext context, Widget player) => SizedBox(

              width: orientation == Orientation.landscape ? height : width,

              height: orientation == Orientation.landscape ? width : height,

              child: player,

            ),

            player: YoutubePlayer(

              controller: _controller,

            ),

            onExitFullScreen: () {},

            onEnterFullScreen: () {},

          ),

        ),

      ),

    );

  }

}

<C>

في مقتطف التعليمات البرمجية أعلاه، نستخدم OrientationBuilderالأداة لتحديد اتجاه الشاشة الحالي. داخل منشئها، نعيد YoutubePlayerBuilder، والتي تعيد بدورها SizedBoxأداة. يتم تعديل أبعاد الأداة SizedBoxبناءً على الاتجاه.


في YoutubePlayerBuilder، نقوم بتعريف player، والتي تأخذ مثيلًا من YoutubePlayerالفئة. لدينا أيضًا إمكانية الوصول إلى السمات onEnterFullScreenو onExitFullScreen، والتي يمكن استخدامها لتحريك الإجراءات عندما يدخل اللاعب إلى وضع ملء الشاشة أو يخرج منه. في القسم القادم ، سنناقش onExitFullScreenالسمة بمزيد من التفصيل، وخاصةً لمعالجة مشكلة في شريط التنقل في Android.

تغيير الصورة المصغرة

بالاستمرار في استخدام الكود من القسم السابق، ربما لاحظت أن الصورة المصغرة لا يتم عرضها بشكل صحيح عند إيقاف تشغيل الفيديو مؤقتًا، وخاصة في الوضع الأفقي. لحسن الحظ، يمكننا تخصيص الصورة المصغرة لمعالجة هذه المشكلة.

<C>

import 'package:flutter/material.dart';

import 'package:youtube_player_flutter/youtube_player_flutter.dart';


class YoutubePage extends StatefulWidget {

  const YoutubePage({super.key});


  @override

  State<YoutubePage> createState() => _YoutubePageState();

}


class _YoutubePageState extends State<YoutubePage> {

  final YoutubePlayerController _controller = YoutubePlayerController(

    initialVideoId: 'PAOAjOR6K_Q',

  );


  @override

  void dispose() {

    _controller.dispose();

    super.dispose();

  }


  @override

  Widget build(BuildContext context) {

    final size = MediaQuery.of(context).size;

    final width = size.width;

    final height = size.height;


    return Scaffold(

      body: Center(

        child: OrientationBuilder(

          builder: (BuildContext context, Orientation orientation) =>

              YoutubePlayerBuilder(

            builder: (BuildContext context, Widget player) => SizedBox(

              width: orientation == Orientation.landscape ? height : width,

              height: orientation == Orientation.landscape ? width : height,

              child: player,

            ),

            player: YoutubePlayer(

              controller: _controller,

              thumbnail: ColoredBox(

                color: Colors.black,

                child: Image.network(

                  YoutubePlayer.getThumbnail(

                    videoId: _controller.metadata.videoId.isEmpty

                        ? _controller.initialVideoId

                        : _controller.metadata.videoId,

                  ),

                  fit: BoxFit.contain,

                  loadingBuilder: (_, child, progress) =>

                      progress == null ? child : Container(color: Colors.black),

                  errorBuilder: (context, _, __) => Image.network(

                    YoutubePlayer.getThumbnail(

                      videoId: _controller.metadata.videoId.isEmpty

                          ? _controller.initialVideoId

                          : _controller.metadata.videoId,

                      webp: false,

                    ),

                    fit: BoxFit.contain,

                    loadingBuilder: (_, child, progress) => progress == null

                        ? child

                        : Container(color: Colors.black),

                    errorBuilder: (context, _, __) => Container(),

                  ),

                ),

              ),

            ),

          ),

        ),

      ),

    );

  }

}

<C>

في مقتطف التعليمات البرمجية أعلاه، أضفنا thumbnailالسمة إلى YoutubePlayerالمثيل. thumbnailتقبل السمة عنصر واجهة مستخدم، وفي هذه الحالة، استخدمنا عنصر ColoredBoxواجهة مستخدم بخلفية سوداء. داخل ColoredBoxعنصر واجهة المستخدم، قمنا بتضمين عنصر Image.networkواجهة مستخدم لعرض الصورة المصغرة.


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

إصلاح المشكلات المتعلقة بشريط التنقل في Android بعد الخروج من وضع ملء الشاشة


في قسم تخصيص مشغل YouTube ، ناقشنا هذه onExitFullScreenالخاصية بإيجاز. في هذا القسم، ستتعلم كيفية استخدام هذه الخاصية لحل مشكلة محتملة عندما تريد أن يعرض تطبيقك شريط التنقل الخاص بنظام Android.

<C>
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';

class YoutubePage extends StatefulWidget {
  const YoutubePage({super.key});

  @override
  State<YoutubePage> createState() => _YoutubePageState();
}

class _YoutubePageState extends State<YoutubePage> {
  final YoutubePlayerController _controller = YoutubePlayerController(
    initialVideoId: 'PAOAjOR6K_Q',
    flags: const YoutubePlayerFlags(
      forceHD: true,
    ),
  );

  Future<void> _onExitFullScreen() async {
    await SystemChrome.setPreferredOrientations([]);
    await SystemChrome.setEnabledSystemUIMode(
      SystemUiMode.manual,
      overlays: [SystemUiOverlay.top, SystemUiOverlay.bottom],
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    _onExitFullScreen();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    final width = size.width;
    final height = size.height;

    return Scaffold(
      body: Center(
        child: OrientationBuilder(
          builder: (BuildContext context, Orientation orientation) =>
              YoutubePlayerBuilder(
            builder: (BuildContext context, Widget player) => SizedBox(
              width: orientation == Orientation.landscape ? width : height,
              height: orientation == Orientation.landscape ? width : height,
              child: player,
            ),
            player: YoutubePlayer(
              controller: _controller,
            ),
            onExitFullScreen: _onExitFullScreen,
          ),
        ),
      ),
    );
  }
}
<C>

في مقتطف التعليمات البرمجية أعلاه، أضفنا _onExitFullScreenوظيفة خاصة. يتم تشغيل هذه الوظيفة عندما يخرج المشغل من وضع ملء الشاشة. بشكل افتراضي، يخفي المكون الإضافي شريط التنقل في Android، ولكن يمكننا تجاوز هذا السلوك. نستخدم وظيفة setEnabledSystemUIModeالفصل SystemChromeلاستعادة شريط التنقل في Android. يمكنك ضبط المعلمات لتناسب احتياجات مشروعك.

حساب نسبة العرض إلى الارتفاع
YoutubePlayerتتضمن الفئة أيضًا سمة aspectRatio، والتي تكون افتراضيًا 16:9. ومع ذلك، لدينا خيار تجاوز هذه القيمة. في الكود التالي، نحسب نسبة العرض إلى الارتفاع المثلى باستخدام خوارزمية إقليدية https://sites.math.rutgers.edu/~greenfie/gs2004/euclid.html . تساعدنا هذه الخوارزمية في العثور على القاسم المشترك الأعظم https://insaneimpact.com/aspect-ratio-calculator/#:~:text=To%20calculate%20an%20aspect%20ratio,height%20divided%20by%20the%20GCF ، والذي نستخدمه بعد ذلك لتحديد أفضل نسبة عرض إلى ارتفاع بناءً على أبعاد جهاز المستخدم.

<C>
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:youtube_player_flutter/youtube_player_flutter.dart';

class YoutubePage extends StatefulWidget {
  const YoutubePage({super.key});

  @override
  State<YoutubePage> createState() => _YoutubePageState();
}

class _YoutubePageState extends State<YoutubePage> {
  final YoutubePlayerController _controller = YoutubePlayerController(
    initialVideoId: 'PAOAjOR6K_Q',
  );

  double _calculateAspectRatio(double width, double height) {
    final greatestCommonFactor = _calculateGreatestCommonFactor(width, height);

    if (greatestCommonFactor == 0.0) {
      return 16 / 9;
    }

    return (width / greatestCommonFactor) / (height / greatestCommonFactor);
  }

  double _calculateGreatestCommonFactor(double width, double height) {
    final size = [width, height];
    final lowest = size.reduce(min);
    final highest = size.reduce(max);

    var remainder = highest % lowest;
    var greatestCommonFactor = 0.0;

    while (remainder != 0) {
      if ((lowest % remainder) == 0) {
        greatestCommonFactor = remainder;
        break;
      }

      remainder = lowest % remainder;
    }

    return greatestCommonFactor.abs();
  }

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.sizeOf(context);
    final width = size.width;
    final height = size.height;

    return Scaffold(
      body: Center(
        child: OrientationBuilder(
          builder: (BuildContext context, Orientation orientation) =>
              YoutubePlayer(
            controller: _controller,
            aspectRatio: _calculateAspectRatio(
              orientation == Orientation.landscape ? height : width,
              orientation == Orientation.landscape ? width : height,
            ),
          ),
        ),
      ),
    );
  }
}

<C>

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

أثناء تطوير تطبيقي Your News https://yournews.app/ ، واجهت مشكلات تتعلق بنسبة العرض إلى الارتفاع. إذا واجهت مشكلات مماثلة، فقد تجد أن الشوكة التي أنشأتها مفيدة https://github.com/sarbagyastha/youtube_player_flutter/compare/develop%E2%80%A6TijnvandenEijnde:youtube_player_flutter:develop . وهي تستند إلى الإصدار 8.1.2 من البرنامج الإضافي Youtube Player Flutter.


الاستنتاجات
في هذه المقالة، تعلمت كيفية عرض مقاطع فيديو YouTube في Flutter. بدأنا بالتنفيذ الأساسي وناقشنا خيارات التخصيص المختلفة. أخيرًا، تناولنا بعض المشكلات الشائعة مع المكون الإضافي التي اكتشفتها أثناء استخدامه. آمل أن تجد هذه المقالة مفيدة. إذا كانت لديك أي أسئلة أو واجهتك مشكلات، فلا تتردد في ترك تعليق.

لا تفوتك أية تفاصيل! حمل تطبيقنا الآن وابدأ رحلتك في عالم التكنولوجيا Technical-information1.0.5

رابط تنزيل مباشر :

https://github.com/sajafFON/Technical-information1.0.2/releases/download/v1.0.5/1.0.5.apk

‏أفضل 10 محركات بحث يجب على كل متخصص في الأمن السيبراني أن يعرفها 🔎🕵🏻‍♂️ ‏The 10 best search engines every cybersecurity professional should know about ‏⁧‫

في عالم الأمن السيبراني المتطور باستمرار، فإن إمتلاكك الأدوات المناسبة تحت تصرفك يمكن أن يحدث فرقًا كبيرًا .

‏سواءً كنت مختبر اختراق أو محلل أمان أو باحثًا في التهديدات، فإن محركات البحث والمنصات هذه ستساعدك في جمع المعلومات الاستخباراتية التي تحتاجها لحماية الشبكات والأنظمة والدفاع عنها .

‏فيما يلي ملخص لأفضل 10 محركات بحث يستخدمها محترفو الأمن السيبراني .

‏1: Dehashed

‏الغرض: بيانات الاعتماد المسربة

‏Dehashed هو محرك بحث قوي مصمم لتحديد بيانات الاعتماد المسربة من خروقات البيانات المختلفة .

‏من خلال السماح للمستخدمين بالبحث عن عناوين البريد الإلكتروني وأسماء المستخدمين وعناوين IP والمعرفات الأخرى، يساعد Dehashed في تحديد ما إذا كانت البيانات الشخصية أو التنظيمية قد تعرضت للخطر .

https://dehashed.com/

‏2. SecurityTrails

‏الغرض: نظرة عامة على بيانات DNS

‏توفر SecurityTrails بيانات DNS والنطاقات المتعمقة، وتقدم رؤى حول سجلات DNS وتاريخ النطاق وعناوين IP المرتبطة بها .

‏تعد هذه الأداة ضرورية لفهم البنية الأساسية للهدف وتحديد نقاط الضعف المحتملة .

https://securitytrails.com/

‏3. Google Dorking

‏الغرض: نظرة عامة على Google Dorking

‏يستفيد DorkSearch من استعلامات بحث Google المتقدمة للكشف عن معلومات حساسة لا يمكن الوصول إليها بسهولة من خلال عمليات البحث القياسية .

‏ويشمل ذلك الملفات غير الآمنة وبوابات تسجيل الدخول والبيانات الأخرى التي تم الكشف عنها عن غير قصد عبر الإنترنت .

https://dorksearch.com/

‏4. ExploitDB

‏الغرض: نظرة عامة على أرشيفات الثغرات الأمنية

‏ExploitDB هي قاعدة بيانات شاملة للثغرات الأمنية والثغرات المتاحة للعامة .

‏إنها مصدر لا يقدر بثمن لمختبري الاختراق والباحثين الأمنيين الذين يبحثون عن ثغرات أمنية محددة في البرامج والثغرات الأمنية المرتبطة بها .

https://www.exploit-db.com/

‏5. ZoomEye

‏الغرض: معلومات حول الأهداف

‏تقوم ZoomEye بمسح الإنترنت بحثًا عن الأجهزة والخدمات، وتوفر معلومات مفصلة حول البرامج والأجهزة المعرضة للخطر ،

‏تعد هذه الأداة بالغة الأهمية لتحديد نقاط الدخول المحتملة وفهم الوضع الأمني ​​للهدف .

https://www.zoomeye.hk/

‏6. Pulsedive

‏الغرض: نظرة عامة على استخبارات التهديدات

‏تجمع Pulsedive البيانات من مصادر متعددة لتقديم معلومات استخباراتية شاملة عن التهديدات .

‏وتوفر أدوات لتحليل مؤشرات التهديدات وتتبع الجهات الفاعلة في التهديدات ومراقبة التهديدات الناشئة، مما يجعلها موردًا حيويًا لفرق الأمن السيبراني .

https://pulsedive.com/

‏7. DNSDumpster

‏الغرض: نظرة عامة على بيانات DNS

‏DNSDumpster هي أداة مجانية تساعد المستخدمين على اكتشاف معلومات DNS حول المجال .

‏وهي مفيدة لتحديد متجهات الهجوم المحتملة وفهم البصمة الرقمية للهدف .

https://dnsdumpster.com/

‏8. AlienVault OTX

‏الغرض: نظرة عامة على استخبارات التهديدات

‏يعتبر برنامج تبادل التهديدات المفتوح (OTX) من AlienVault منصة تعاونية حيث يتشارك المتخصصون في الأمن بيانات التهديدات ويصلون إليها .

‏وهو يوفر رؤى قيمة حول الأنشطة الضارة ومؤشرات الاختراق (IOCs) .

https://otx.alienvault.com/

‏9. Netlas

‏الغرض: أجهزة الإنترنت (بديل لـ Shodan)

‏نظرة عامة: Netlas هو محرك بحث يحدد الأجهزة المتصلة بالإنترنت، على غرار Shodan .

‏يوفر معلومات مفصلة حول الأجهزة المختلفة المتصلة بالإنترنت، مما يساعد محترفي الأمن السيبراني على تقييم نقاط الضعف والمخاطر المحتملة .

https://netlas.io/

‏10. IntelligenceX

‏الغرض: البحث عن Tor وI2P وتسربات البيانات

‏يقوم IntelligenceX بفهرسة المحتوى من الويب المظلم، بما في ذلك شبكات Tor وI2P، ويتتبع تسريبات البيانات والاختراقات .

‏إنها أداة أساسية للاستخبارات والبحث عن التهديدات، وتوفر رؤى حول الأنشطة المخفية وغير المشروعة عبر الإنترنت .

https://intelligencex.com.hk/home

‏تُعد محركات البحث والمنصات هذه ضرورية لأي شخص يعمل في مجال الأمن السيبراني .

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

‏لمزيد من المعلومات، قم بزيارة المواقع الإلكترونية ذات الصلة  أعلاه وأستكشف الإمكانات التي تقدمها لتعزيز جهودك في مجال الأمن السيبراني .

أفضل مصادر ل تعلم لغة ➖ Java Script ➖ 👨‍💻💎

1- موقع learn-js  https://www.learn-js.org/


يساعدك هذا الموقع على احتراف وتعلم  كل الأساسيات المهمة في لغة جافا سكربت حيث يتميز بأنه من المواقع المجانية البسيطة في الاستخدام ليكون مناسب المبتدئين والمحترفين


2- موقع هرموش harmash https://harmash.com/

يوفر هذا الموقع شرح مبسط  لل javascript  والمميز فيه الأمثلة التفاعلية و باللغة العربية ،يقدم إليك المعرفة بشكل مبسّط و مفصّل، 


2-موقع JavaScript The Right WayKit


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


3- موقع JavaScript Kit  https://jstherightway.org/


يعتبر هذا الموقع من المواقع التي تشبه المنتديات القديمة التي كانت موجودة على الإنترنت لذلك يضم مجموعة من المقالات التي تساعدك على تعليم لغة جافا سكريبت حيث يحتوي على شروحات مجانية متعلقة بلغة جافا سكريبت بالإضافة إلى باقي لغات البرمجة المستخدمة في الويب مثل

• CSS

•HTML


4- موقع The Modern JavaScript Tutorial   https://javascript.info/


إذا لم تعرف أي شيء من قبل لغة جافا سكربت، فهذا الموقع لك لأنه يحتوي على كورس مجاني متوفر ككتيب إلكتروني حيث بإمكانك من خلال هذا المساق أن تتعرف على كل المبادئ المهمة في اللغة مثل أساسيات اللغة جودة البرمجيات ،أنواع البيانات

النماذج والوراثة ....


⁧‫البرمجة‬⁩ ضرورية للاختراق لأن معظم الثغرات تحدث في أكواد المواقع والتطبيقات

تعلم لغة البرمجة

ولذلك يعد تعلم لغة Python (بايثون) بداية رائعة، حيث تُستخدم على نطاق واسع في مجال ⁧‫#الأمن_السيبراني‬⁩.

المصادر:

✔️ تعلم بايثون للمبتدئين 

(دورة تعليمية تفاعلية مجانية)  

[Interactive Python Tutorial]( https://learnpython.org )

✔️ أتمتة الأشياء المملة بإستخدام بايثون

(كتاب مجاني)  

[Automate the Boring Stuff with Python]( https://automatetheboringstuff.com )

ونختم نهايه هذا الشهر بنشر اشياء جديده في برمجة فلاتر

 كيفية طلب المراجعات داخل التطبيق في تطبيق Flutter الخاص بك

في هذه المقالة، ستتعلم كيفية تثبيت in_app_review وكيفية عرض مطالبة مراجعة التطبيق برمجيًا، وتجنب عرض المطالبة في وقت مبكر جدًا، واستخدام التحليلات لضمان عرض المطالبة في الوقت المناسب.

https://codewithandrea.com/articles/flutter-in-app-review-prompt/


كيفية إضافة متغيرات البيئة في Flutter

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

https://onlyflutter.com/how-to-add-environment-variables-in-flutter/


كيفية إنشاء تطبيقات جوال متعددة الأنظمة — دليل كامل

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

https://flutterdesk.com/how-to-develop-a-cross-platform-mobile-app/


دليل عملي حول بنيات وحدة المعالجة المركزية لمطوري Flutter

في هذا الدليل، لن نتعمق في مستوى الأجهزة، بل سنتناول فقط المعلومات العملية التي يجب أن يعرفها كل مطور للهواتف المحمولة.

https://medium.com/@pomis172/a-practical-guide-on-cpu-architectures-for-flutter-developers-7ef80fbdb33a


ملخص مؤتمر FlutterCon USA 2024

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

https://medium.com/@elianortega/fluttercon-usa-2024-recap-80f63beefbd8

حول النص إلى فيديو مع مواقع الذكاء الاصطناعي

1ـ Brainy Docs
2ـ Zebracat
3ـ Mango AI
4ـ Viggle
5ـ Crayo
6ـ ViddyBot
7ـ Deforum Studio
8ـ aicut
9ـ Atlabs
10ـ Creatify
11ـ Video To Blog
12ـ Vidiofy AI
13ـ Fliz
14ـ Moonvalley
15ـ Adori Labs
16ـ Ssemble
17ـ Elai io
18ـ Dubverse ai

تطبيق Google Authenticator

 حساباتنا في الإنترنت غالباً معرّضة للاختراق، أو حتى نسيان بياناتها وما راح نقدر ندخلها لهذا السبب!

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


تطبيق Google Authenticator:


الآيفون:

https://apps.apple.com/us/app/google-authenticator/id388497605

الاندرويد:

https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=en_US

دورات وموارد مجانيه لتعلم الأمن السيبراني

1- الأمن السيبراني للطلاب

Cybersecurity for Students

https://app.letsdefend.io/path/cybersecurity-for-students


2- أساسيات SOC

SOC Fundamentals

https://app.letsdefend.io/training/lessons/soc-fundamentals


3- تحليل البريد الإلكتروني للتصيد الاحتيالي

Phishing Email Analysis

https://app.letsdefend.io/training/lessons/phishing-email-analysis


4- الكشف عن هجمات الويب

Detecting Web Attacks

https://app.letsdefend.io/training/lessons/web-attacks-101


5- تحليل حركة البرامج الضارة بإستخدام Wiershark

Malware Traffic Analysis with Wireshark

https://app.letsdefend.io/training/lessons/malware-traffic-analysis-with-wireshark


6- لينكس للفريق الأزرق

Linux for Blue Team

https://app.letsdefend.io/training/lessons/linux-for-blue-team


7- بناء مختبر تحليل البرامج الضارة

Building a Malware Analysis Lab

https://app.letsdefend.io/training/lessons/building-malware-analysis-lab


8-📊 Splunk for SOC:

https://app.letsdefend.io/training/lessons/splunk

‏دورات مجانيه بشهادات ‏تكنولوجيا المعلومات | الأمن السيبراني | البرمجة | المهارات الشخصية

‏✔️البرمجة 100: الأساسيات


‏Programming 100: Fundamentals


‏تعلم اللبنات الأساسية للبرمجة باستخدام بايثون.


https://academy.tcm-sec.com/p/programming-100-fundamentals


‏✔️ لينكس 100: الأساسيات


‏Linux 100: Fundamentals


‏تعلم أساسيات لينكس وابدأ حياتك المهنية في مجال تكنولوجيا المعلومات والأمن السيبراني.


https://academy.tcm-sec.com/p/linux-fundamentals


‏✔️ مكتب المساعدة العملية


‏Practical Help Desk


‏استعد لمهنة في تكنولوجيا المعلومات أو الأمن السيبراني من خلال تعلم كل ما تحتاج إلى معرفته للعمل في مكتب المساعدة.


https://academy.tcm-sec.com/p/practical-help-desk


‏✔️ المهارات الشخصية لسوق العمل


‏Soft Skills for the Job Market


‏تم تصميم هذه الدورة الشاملة بدقة لتزويد الباحثين عن عمل بالمهارات الشخصية الأساسية وتقنيات الاتصال واستراتيجيات تقديم طلبات التوظيف المطلوبة للتفوق في سوق العمل التنافسي اليوم.


https://academy.tcm-sec.com/p/soft-skills-for-the-job-market

إليك بعض مستودعات GitHub التي يجب أن تحفظها مهما كان تخصصك في البرمجة

1 - Tech Interview Handbook

 https://github.com/yangshun/tech-interview-handbook 


2 - The Algorithms

 https://github.com/TheAlgorithms 


3 - Free Programming Books

 https://github.com/EbookFoundation/free-programming-books 


4 - 1000+ Free APIs

 https://github.com/public-apis/public-apis 


5 - Coding Interview University

 https://github.com/jwasham/coding-interview-university 


6 - 30 Seconds of Code

 https://github.com/Chalarangelo/30-seconds-of-code 


7 - Freecodecamp

 https://github.com/freeCodeCamp/freeCodeCamp

كيفية التبديل بين الوضع الداكن والفاتح في Flutter باستخدام Bloc

تثبيت الحزم للتبديل بين الوضع الداكن والفاتح في Flutter
لكي يصبح من الممكن التبديل بين الوضع الداكن والوضع الفاتح في Flutter باستخدام Bloc with cubits، نحتاج إلى تثبيت حزمة  Flutter Bloc https://pub.dev/packages/flutter_bloc مع حزمة https://pub.dev/packages/shared_preferences Shared Preferences و https://pub.dev/packages/equatable Equatable . يمكن القيام بذلك عن طريق تنفيذ الأمر التالي داخل مشروعك:

إن السماح للمستخدمين بالتبديل بين الوضع الداكن والوضع الفاتح في تطبيق Flutter أمر ضروري في الوقت الحاضر. في هذا المنشور، ستتعلم كيفية تغيير السمات في Flutter باستخدام Bloc مع Cubits. يضمن Bloc أن التطبيق يفتح دائمًا بالسمات التي يختارها المستخدم. بدلاً من استخدام فئات Bloc العادية، يمكننا تحقيق الوظيفة المطلوبة باستخدام cubits مما يجعل التنفيذ أبسط كثيرًا.


تثبيت الحزم للتبديل بين الوضع الداكن والفاتح في Flutter

لكي يصبح من الممكن التبديل بين الوضع الداكن والوضع الفاتح في Flutter باستخدام Bloc with cubits، نحتاج إلى تثبيت حزمة Flutter Bloc مع حزمة Shared Preferences و Equatable . يمكن القيام بذلك عن طريق تنفيذ الأمر التالي داخل مشروعك:


🛡️ المهن الأكثر طلباً لوظائف الأمن السيبراني لعام 2024 💻

1. Threat Hunter

2. Red Teamer

3. Digital Forensic Analyst

4. Purple Teamer

5. Malware Analyst

6. Chief Information Security Officer (CISO)

7. Blue Teamer – All- Around Defender

8. Security Architect & Engineer

9. Incident Response Team Member

10. Cyber Security Analyst/ Engineer

11. OSINT Invest/Analyst

12. Technical Director

13. Cloud Analyst

14. Intrusion Detection / (SOC) Analyst

15. SecurityAwareness Officer

16. Vulnerability Researcher & Exploit Developer

17. ApplicationPenTester

18. ICS/OT Security Assessment Consultant

19. DevSecOpsEngineer

20. Media Exploitation Analyst