اذهب إلى المحتوى

Mustafa Suleiman

الأعضاء
  • المساهمات

    15399
  • تاريخ الانضمام

  • تاريخ آخر زيارة

  • عدد الأيام التي تصدر بها

    403

كل منشورات العضو Mustafa Suleiman

  1. عليك بتفقد سجل الأخطاء stack trace لرؤية سبب المشكلة بالضبط. والخطأ الذي يظهر لك هو خطأ في نظام التشغيل iOS وليس بالضرورة خطأ مرتبطًا بتطبيق React Native نفسه. وقد يحدث الخطأ عندما يتم استدعاء الدالة dealloc في صفحة التطبيق وتحاول إيقاف توليد إشعارات توجيه الجهاز قبل تدمير الكائن. حاول أن تستدعي الدالة endGeneratingDeviceOrientationNotifications في المكان الصحيح وفي الوقت المناسب. ويُفضل أن تقوم بإيقاف توليد إشعارات توجيه الجهاز في مكان مناسب في دورة حياة التطبيق، مثل viewWillDisappear أو deinit للصفحة التي تحتوي على الكود المشار إليه. وتأكد من أن لديك تحديثات مستقرة لنظام التشغيل iOS على جهازك، فقد يكون الخطأ مرتبطًا بمشكلة في إصدار سابق من نظام التشغيل، وقد تم إصلاحها في التحديثات الحديثة. وإذا لم تستخدم أحدث إصدار من React Native، فقد ترغب في تحديثه إلى الإصدار الأحدث، حيث قد تكون هناك تحسينات وإصلاحات لمشاكل سابقة.
  2. عليك بإعادة التثبيت وتأكد من إختيار الخيار التالي كما في الصورة لإضافة بايثون لمتغيرات البيئة: أو خيار باسم add python to environment variables. وأيضًا تم شرح كيفية التثبيت وتفاصيل أخرى مثل كيفية الإضافة لمتغيرات البيئة بشكل يدوي وأيضًا محرر بايثون على الإنترنت في النقاش التالي: وبعد تنفيذ الشرح عليك بغلق منفذ الأوامر تمامًا وإعادة تشغيله وتنفيذ أمر بايثون، وأيضًا تأكد في متغيرات البيئة أن لديك مثل المتغيرات التالية: وتستطيع الوصول إليها عن طريق البحث عن environment variables في شريط البحث بالأسفل ثم إخيار environment variables والضغط على path وستجد تلك المتغيرات. وإليك شرح وافي أيضًا:
  3. إذا كان السؤال خاص بأحد الدورات، فأرجو منك طرح السؤال أسفل فيديو الدورة الخاص به، وطرح الأسئلة العامة هنا. والسؤال الخاص بك غير واضح، ولكن علي أي حال الخاصية "name" تستخدم في اللغات والتقنيات المختلفة لتعيين اسم لكائن معين أو عنصر في النظام البرمجي. أي استخدامها للإشارة إلى الهوية أو التعرف على الكائن والوصول إليه بسهولة. وفي html تستخدم للتعرف على اسم حقل الاستمارة في جافاسكريبت بعد عمل submit لها، وأيضًا بالنسبة لعناصر أخرى تلك الخاصية متاحة. بالنسبة لعنصر <iframe> تستخدم الخاصية لاستهداف تقديم النموذج. وبالنسبة لعنصر <map>، ترتبط خاصية الاسم بسمة usemap في عنصر <img> وتُنشئ علاقة بين الصورة والخريطة. بالنسبة لعنصر <meta>، تُحدد خاصية الاسم اسمًا لمعلومة/قيمة السمة المحتوى (content). بالنسبة لعنصر <param>، يتم استخدام خاصية الاسم بالتزامن مع سمة القيمة (value) لتحديد المعلمات للوحدة الإضافية المحددة بواسطة علامة العنصر <object>. والخاصية name متاحة للعناصر التالية: <button> <fieldset> <form> <iframe> <input> <map> <meta> <object> <output> <param> <select> <textarea> وأرجو توضيح السؤال لمساعدتك بشكل أفضل.
  4. بالإضافة إلى ما تم ذكره، تستطيع استخدام إشارات Django لتنفيذ العملية الحسابية وعرض الرسالة المناسبة عند وصول تاريخ محدد في حقل التاريخ في نموذج Django. وإليك مثال لكيفية تنفيذ ذلك باستخدام إشارات Django: 1- في ملف models.py الخاص بالمشروع، استورد الإشارات والمكتبة datetime: from django.db import models from django.db.models.signals import post_save from django.dispatch import receiver from datetime import date class YourModel(models.Model): date_field = models.DateField() @receiver(post_save, sender=YourModel) def check_date(sender, instance, **kwargs): if instance.date_field == date.today(): # تنفيذ العملية الحسابية next_day = instance.date_field + timedelta(days=1) # عرض الرسالة print("تاريخ اليوم هو اليوم!") قمت باستيراد الإشارات والمكتبة datetime. ثم تعريف نموذج (YourModel) الذي يحتوي على حقل التاريخ (date_field). ثم تعريف دالة إشارة (signal function) باستخدام الديكورات (decorators) @receiver و @post_save للتأكيد على أن الدالة تستجيب لحدث حفظ النموذج بعد الحفظ. وفي تلك الدالة، يتم التحقق مما إذا كان حقل التاريخ في النموذج يساوي تاريخ اليوم، وإذا كان الأمر كذلك، تنفذ العملية الحسابية المطلوبة (وفي المثال تم طباعة اليوم التالي) وعرض الرسالة. تأكد من تسجيل الإشارة في ملف المشروع (apps.py) للتأكد من استدعائها عند تشغيل المشروع.
  5. أرجو منك نسخ رسالة الخطأ بالكامل ولصقها هنا بشكل نصي حتى أتمكن من قرائتها وأيضًا مشاركة مجلد المشروع الخاص بك بعد التعديل.
  6. عليك بكتابة الصيغة الخاصة بالملف وهي .mp3 وسأشرح لك الكود: System.getProperty("user.home"): يستخدم للحصول على مسار مجلد المستخدم الرئيسي. هذا الجزء يعيد سلسلة النص التي تمثل مسار المجلد الرئيسي للمستخدم. File.separator: هو فاصل الدليل الذي يستخدم لتجنب مشاكل التوافق بين أنظمة التشغيل المختلفة. يتم استخدامه هنا لتحديد فاصل الدليل في المسار. "Desktop": يشير إلى اسم المجلد المستهدف، وهو مجلد سطح المكتب. "al kouds.mp3": اسم الملف الصوتي الذي يتم تحديده في المسار. وما يحدث هو دمج جميع هذه الأجزاء لإنشاء المسار الكامل إلى الملف الصوتي، والمسار النهائي يعتمد على مسار المجلد الرئيسي للمستخدم واسم المجلد المستهدف واسم الملف الصوتي.
  7. يوجد استثناء FileNotFoundException في رسالة الخطأ وهذا يعني أن الملف الذي تحاولي قرائته للتشغيل الصوتي غير موجود في المسار المحدد، ويجب التأكد من أن الملف الصوتي المطلوب موجود في المسار الصحيح. أي تحققي من المسار الذي تم تحديده للملف في الكود التالي، والأفضل تسمية الملف باسم بسيط باللغة الإنجليزية. File file = new File(System.getProperty("user.home") + File.separator + "Desktop" + File.separator + "أغنيه الأرض لنا والقدس لنا بدون موسيقى وبدون ايقاع (256 kbps) (shabakngy.com).mp3"); وإذا كان الملف غير موجود في المسار الصحيح، عليك بتحديد المسار الصحيح للملف الصوتي أو بنقل الملف إلى المسار الحالي المحدد في الكود.
  8. ارفق مجلد المشروع بالكامل، واذكر الملف الذي به المشكلة إن أمكن.
  9. سأشرح لك الخطوات من البداية: عليك بتعديل ملف المشروع الرئيسي وهو لديك index.jsx بحيث تقوم بتعديل الـ Router وتضع بداخله basename له قيمة مماثلة تمامًا لاسم المستودع الخاص بمشروعك كالتالي: بعد ذلك عليك بتثبيت الحزمة التالية: npm i gh-pages والآن قم بإضافة سكريبت predeploy وdeploy إلى ملف package.json أي بجانب سكريبتات start وbuild لديك كالتالي: ولكن لاحظ اسم dist في الكود خاص بالمجلد النهائي الذي يتم عمل build له فإذا كان مختلف لديك فيجب تعديله، ولديك أنت في مشروعك اخترت dist كاسم للمجلد في إعدادات Webpack فلا مشكلة إذًا. والآن قم برفع مشروعك على GitHub كما تفعل ومن الأفضل أن تقوم بإنشاء مستودع جديد وحذف القديم وإليك طريقة حذف المستودع: وبعد رفع المشروع قم بتنفيذ الأمر التالي في مشروعك داخل منفذ الأوامر في محرر الأكواد VScode: npm run deploy والكود سينفذ أمر npm run buld بمفرده وسيتم إنشاء فرع جديد به الملفات الخاصة بمجلد dist لديك باسم فرع gh-pages ونشر مشروعك به وستجد به رابط Github pages كما بالصورة: وإذا استمرت المشكلة لديك استخدم استضافات أخرى مثل render وrailway.app وvercel، وأيضًا لديك Netlify.
  10. الأسئلة الإختبارية لا يتم الإجابة عليها بشكل مباشر، ولكن سأرشدك لطريقة الحل، وإذا واجهتك مشكلة بالكود يمكن المساعدة بذلك. خطوات الحل بشكل عام: 1- قومي بفتح محرر الأكواد لديك مثل (Eclipse أو IntelliJ). 2- إنشاء ملف جديد وتسميته بـ "Main.java" (يجب أن يتطابق اسم الملف مع اسم الكلاس الرئيسي في البرنامج). 3- وسأوضح لك بداية الكود الذي عليك كتابته داخل الملف "Main.java": import java.util.Scanner; public class Main { public static void main(String[] args) { //باقي الكود { وبالنسبة لباقي الكود عليك بالتالي: نقوم بتضمين فئة Scanner من مكتبة Java للسماح لنا بقراءة الإدخال من المستخدم. تعريف دالة main التي هي نقطة البداية لتنفيذ البرنامج. إنشاء كائن Scanner باستخدام new Scanner(System.in) للقراءة من وسيلة الإدخال القياسية (المستخدم). تعريف متغير number لتخزين العدد المدخل من المستخدم. نستخدم حلقة do-while للتأكد من أن المستخدم يدخل عددًا صحيحًا في النطاق المحدد. داخل الحلقة، نطلب من المستخدم إدخال رقم بين 10 و 50 باستخدام System.out.print و input.nextInt() لقراءة الرقم المدخل. إذا كان الرقم خارج النطاق المحدد، سيتم عرض رسالة خطأ باستخدام System.out.println. إذا كان الرقم داخل النطاق المحدد، سيتم طباعة رسالة الترحيب باستخدام System.out.println. 4- بعد الانتهاء من كتابة الكود، قومي بحفظ الملف "Main.java". 5- تشغيل المترجم لتحويل الكود إلى صيغة قابلة للتنفيذ، استخدمي مترجم سطر الأوامر (javac) لذلك، وافتحي نافذة الأوامر أو الطرفية وانتقلي إلى المجلد الذي يحتوي على الملف "Main.java" ثم أدخلي الأمر التالي: javac Main.java وسيقوم الأمر بتحويل الملف "Main.java" إلى ملف تنفيذي بامتداد ".class" يحمل نفس الاسم "Main.class". 6- بعد أن يتم تنفيذ الخطوة السابقة بنجاح، عليك بتشغيل البرنامج بإدخال الأمر التالي في نافذة الأوامر: java Main وستظهر رسالة تطلب من المستخدم إدخال عدد بين 10 و 50. إذا قام المستخدم بإدخال عدد خارج هذا النطاق، ستعرض رسالة الخطأ ويُطلب منه إدخال عدد جديد. وعندما يقوم المستخدم بإدخال عدد في النطاق المحدد (10-50)، ستظهر رسالة الترحيب وينتهي البرنامج. وهناك قسم كامل للدروس والشروحات الخاصة بلغة جافا في أكاديمية حسوب.
  11. الأمر يتوقف على الوقت المتاح لك والحالة المادية والسن ومستواك الحالي في علوم الحاسوب، وأيضًا اللغة الإنجليزية وهل تريد العمل على مواقع العمل الحر أم السوق المحلي في بلدك؟ وأولاً عليك بتعلم أساسيات علوم الحاسب أو تعلم أساسيات البرمجة لمدة شهر على الأقل قبل أن تقرر أي مجال تختار. ومجال الويب مناسب في البداية وقد شرح سبب ذلك في النقاشات المرفقة. حيث تم الشرح بشكل مفصل حول هذا الأمر في النقاشات والمقالات التالية:
  12. اعذرني لو بدى لك الأمر قاسيًا بعض الشيء، ولكن لمصلحتك، فتلك الأسئلة تراود أي شخص ليس لديه خبرة في البرمجة أو مبتدأ في البرمجة ويشتت نفسه بتلك الأسئلة بدلاً من تعلم أساسيات البرمجة ثم إختيار المجال الذي يريد التخصص به. وسيجد الإجابة بنفسه، وهي أن تلك الأسئلة تطرح منذ سنوات، بل وبعضها خاص بلغة مثل PHP فكل عام يتم الإشاعة أن لغة PHP في طريقها للإندثار وهو ما لا يحدث، بل يزداد استخدامها بفضل إطار لارافيل. وبالنسبة لمجال الويب حاليًا، الأمر أصبح أسهل وأصعب في نفس الوقت عن ذي قبل. فهو أسهل من حيث إزدياد سهولة إنشاء وواجهة مستخدم بسيطة أو إعتيادية في وقت قصير، من خلال المكتبات ومنصات الـ Low code أو بدون كود عن طريق السحب والإفلات. وهو أمر جيد وله استخداماته، لكن أصعب من حيث إنشاء واجهة مستخدم مخصصة ومعقدة، حيث سيتطلب منك الأمر تعلم استخدام العديد من المكتبات لتنفيذ المشروع، فمثلاً عند استخدام React ستقوم بتعلم مكتبات أخرى مثل Redux وReact Router لإدارة حالة التطبيق وتوجيه المسارات، أيضًا تعلم CSS frameworks مثل Bootstrap أو Material-UI لتنسيق وتصميم العناصر الواجهة، أو استخدام مكتبة styled-components لكتابة تنسيقاتك بنفسك في مشروع React. وأيضًا استخدام مكتبة AXios لإدارة طلبات Ajax والتعامل مع الـ APIs، إلخ.. من المكتبات الأخرى، وناهيك أن بعض المشاريع تحتاج إلى استخدام إطار عمل Next.js. لذلك الأمر يصبح أسهل من ناحية لكن أكثر تعقيدًا من ناحية أخرى، وعليك باستخدام كافة الأدوات التي تسهل عليك المهمة وإنجاز مهامك بشكل أسرع، لكن اختر الأدوات بعناية وكلما كانت أقل كان أفضل لك حتى لا تتشتت.
  13. الأسئلة الإختبارية لا يتم الإجابة عليها بشكل مباشر، وسأرشدك لطريقة الحل لتستفيد: أولاً قبل البدء في تصميم النماذج المختلفة، يجب عليك فهم المتطلبات والاحتياجات المحددة للنظام الذي تعمل على تصميمه، مما سيساعدك في تحديد الكائنات والعلاقات التي يجب تمثيلها في النماذج. بعد ذلك البدء بتصميم Class Diagram باستخدام أدوات رسم الـ Class Diagram مثل UML تطبيقات تحرير النماذج مثل: drawio smartdraw Visual Paradigm Lucidchart excalidraw أو أدوات برمجة متكاملة مثل Eclipse واستخدام الإضافات المتوفرة لرسم النماذج. بعدها عليك رسم Usecase Diagram باستخدام نفس الأدوات التي استخدمتها في الخطوة السابقة لرسم Use Case Diagram، وقم بتحديد الحالات الاستخدام الرئيسية للنظام وتمثيلها في النموذج. الآن لنرسم Sequence Diagram و Activity Diagram بواسطة نفس الأدوات لرسم هذه النماذج أيضًا، وعليك بتحديد الثلاثة حالات استخدام الرئيسية التي اخترتها ورسم Sequence Diagram و Activity Diagram لكل حالة استخدام. أخيرًا ارسم State Diagram بالأداة التي اخترتها وقم باختيار كائن رئيسي داخل النظام ورسم State Diagram الخاص به. وقبل كل ذلك عليك بفهم الـ UML والـ Class Diagram وإليك مصادر ستفيدك:
  14. بحثت عن البرنامج وكل ما وجدته هو النسخة التالية: https://proton-ide.software.informer.com/2.0/ وتكلفته 19 دولار. وهناك برنامج آخر باسم Amicus18 Compiler وهو مجاني وقد يفيدك. وأيضًا هناك موقع عبارة عن محرر أكواد باسم protonide تفقديه وهو مجاني أيضًا. وهناك بعض البدائل ولا أدري إذا كانت ستفيدك أم لا: MPLAB X IDE: يعتبر MPLAB X IDE منتجًا قويًا وشهيرًا في عالم برمجة الميكروكنترولر. Arduino IDE: يستخدم Arduino IDE في برمجة الأجهزة المبنية على منصة Arduino، وسهل الاستخدام ويحتوي على محرر برمجة مبسط ومكتبة واسعة من الأمثلة والموردين. PlatformIO: بيئة تطوير مفتوحة المصدر ومتعددة الأغرا، و يدعم العديد من منصات الميكروكنترولر والأجهزة واللغات المختلفة مثل Arduino وESP8266 وESP32 وRaspberry Pi وغيرها. Code::Blocks: بيئة تطوير متعددة الأغراض وقابلة للتوسعة، ويدعم العديد من لغات البرمجة مثل C وC++ ويوفر واجهة سهلة الاستخدام ومجموعة من الميزات.
  15. ما المقصود ببرنامج proton plus هل المقصود هو برنامج الـ VPN؟
  16. في في العرض (views) في Django تستطيع كتابة عبارة if statement بواسطة الشروط والتحقق منها في العرض نفسه، ومن ثم تمرير النتيجة إلى القالب (template) لعرض المحتوى المناسب بناءً على الشرط، وإليك مثالًا بسيطًا: في views.py: from django.shortcuts import render def my_view(request): is_authenticated = request.user.is_authenticated return render(request, 'my_template.html', {'is_authenticated': is_authenticated}) في القالب (my_template.html): {% if is_authenticated %} <p>مرحبًا بك، {{ request.user.username }}!</p> {% else %} <p>قم بتسجيل الدخول من فضلك.</p> {% endif %} قمت باستخدام request.user.is_authenticated للتحقق مما إذا كان المستخدم قد سجل الدخول أم لا في العرض. ثم تمرير قيمة is_authenticated إلى القالب عن طريق الدمج مع السياق (context) عند استدعاء دالة render. في القالب، واستخدام البنية if...else لعرض المحتوى المناسب بناءً على قيمة is_authenticated. ولاحظ أنه يجب عليك تعريف المسار المناسب في urls.py وربطه بالعرض (view) الخاص بك في Django.
  17. المشكلة تتعلق بنوع البيانات المتوقع في السطر الذي يحتوي على الخطأ، ويتعذر تحويل القيمة من نوع "int" إلى نوع "String" في سلسلة الحروف (String). وربما السبب هو محاولة استخدام القيمة المسترجعة من SharedPreferences على أنها سلسلة حروف (String) في السطر 27 في ملف "paniercontroller.dart"، ولكن القيمة المسترجعة عبارة عن رقم صحيح (int) وليس سلسلة حروف (String). حاول تجربة تحويل القيمة المسترجعة إلى سلسلة حروف (String) باستخدام دالة toString()، وذلك باستخدام الدالة toString() على القيمة المسترجعة من SharedPreferences قبل استخدامها في عملية التحويل. مثال: String? userId = sharedPreferences.getString('user_id').toString(); قم بتطبيق هذا التغيير في المكان المناسب وحاول تشغيل التطبيق مرة أخرى للتحقق مما إذا كان يزال الخطأ موجودًا أم لا. وذلك مجرد إقتراح ولم أقم بتجربة الكود، وأخبرني بالنتيجة.
  18. تم شرح كيفية رفع مشروع React على github pages في النقاشات التالية: قم بقرائتها وإتباع الخطوات وإذا واجهتك مشكلة ابحث عن الحل أولاً لتستفيد ثم ضع استفسارك هنا.
  19. 1- لنبدأ بحل كل رسالة تحذير وخطأ على حدى، ورسالة التحذير الأولى هي: wrning: You are importing createRoot from "react-dom" which is not supported. You should instead import it from "react-dom/client". p وهي تعني أنك تستخدم createRoot من react-dom وهو غير مدعوم في الإصدار الحالي من React وهو الإصدار 18و بدلاً من ذلك، يجب عليك استيراده من react-dom/client. 2- والتحذير الثاني لديك هو: warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot p ويعني أن استخدام ReactDOM.render لم يعد مدعومًا في React 18 ويجب استخدام createRoot بدلاً من ذلك، ويوضح أنه حتى تقوم بالتبديل إلى الواجهة البرمجية الجديدة، سيتصرف تطبيقك كما لو كان يعمل بناءً على React 17. حيث في React 18، تم إدخال تغييرات في طريقة تجهيز وتقديم التطبيق، وبدلاً من استخدام ReactDOM.render لتقديم التطبيق في نقطة الدخول الرئيسية، يجب استخدام createRoot لإنشاء نقطة جذرية وتقديم التطبيق من خلالها. 3- وأيضًا لديك مشكلة أخرى وهي تستخدم الكود التالي في ملفي App.jsx وindex.jsx: App.jsx createRoot(document.getElementById('root')).render(<App />); في ملف index.jsx ReactDOM.render( <BrowserRouter> <App /> </BrowserRouter>, document.getElementById('root') ); وهو يقوم بإنشاء نقطة جذرية باستخدام createRoot من react-dom ويقوم بتقديم مكون التطبيق <App /> من خلالها. أي يجب وضعه في مكان واحد فقط وهو index.jsx فهو نقطة الدخول لتطبيقك في webpack. 4- المشكلة الأخيرة هي أنك تقوم بتضمين المكون App داخل أكثر من Router حيث أنك في الملف App.jsx تضعه داخل Router والتي هي BrowserRouter وفي index.jsx تضعه داخل BrowserRouter أخرى. وذلك غير مسموح بالطبع وسيسبب لديك مشكلة في التطبيق. 5- لماذا قمت بإنشاء ملفي App.jsx وindex.jsx فكل ما تحتاجه هو index.jsx كملف رئيسي للمشروع. 6- كمعلومة جانبية أنت لست بحاجة إلى استيراد React في بداية أي مكون في إصدار React 18. وبناءًا على ما سبق عليك تعديل الكود في ملف index.jsx كما يلي: // react-dom/client الاستيراد من import { createRoot } from 'react-dom/client'; import './App.css'; import './index.css'; import reportWebVitals from './reportWebVitals'; import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import Home from './pages/home'; import 'bootstrap/dist/css/bootstrap.css'; import 'bootstrap/dist/js/bootstrap.min.js'; import '@fortawesome/fontawesome-free/css/all.css'; createRoot(document.getElementById('root')).render( // استخدم createRoot بدلاً من ReactDOM.render <Router> <Routes> <Route path='/' element={<Home />} /> </Routes> </Router> ); reportWebVitals(); أي قم بحذف ملف App.jsx واستخدم الكود السابق فقط في index.jsx
  20. سأوضح لك المصطلحات بالتفصيل وأمثلة لتوضيح الأفكار. الفرق بين الـ Parameters والـ Arguments Parameters: المتغيرات التي يتم تعريفها في تعريف الدالة وتستخدم لتمرير القيم إلى الدالة، وشير إلى المتغيرات التي يتعامل معها الدالة في داخلها. Arguments: القيم الفعلية التي يتم تمريرها إلى الدالة عند استدعائها، وتشير إلى القيم التي تمررها عند استخدام الدالة. مثال: لنفترض أن لدينا دالة بسيطة تسمى "add" تقوم بإجراء عملية جمع بين اثنين من الأرقام، حيث a و b هما parameters، أما الأرقام المحددة مثل 3 و 5 فهي arguments. function add(a, b) { // a و b هما parameters return a + b; } const result = add(3, 5); // 3 و 5 هما arguments console.log(result); // الناتج سيكون 8 الفرق بين الـ Declaration والـ Initialization Declaration: يتعلق بتعريف متغير أو دالة أو كائن بشكل عام، حيث يتم إعلان وجوده وتحديد نوعه واسمه، ولكن لا يتم تعيين قيمة محددة له في هذه المرحلة. Initialization: يتعلق بتعيين قيمة محددة لمتغير بعد تعريفه، أي تخصيص قيمة بداية للمتغير. مثال: في JavaScript، تستطيع إعلان المتغير باستخدام الكلمة الرئيسية var أو let أو const، ويمكنك تعيين القيمة باستخدام عامل التعيين =. let x; // هنا نقوم بالإعلان عن المتغير x x = 5; // هنا نقوم بتعيين قيمة 5 للمتغير x الـ Execution Context يشير إلى البيئة التي تتم فيها تنفيذ الكود، وتحتوي على المتغيرات المحلية والمعلومات الأخرى المتعلقة بالتنفيذ. يحتوي السياق على سجلات تتبع ترتيب تنفيذ الأوامر والمتغيرات المعرفة والقيم المحددة لها. مثال: عند استدعاء الدالة، يتم إنشاء Execution Context جديد يحتوي على المتغيرات المحلية والمعلومات اللازمة لتنفيذ الدالة. وعند انتهاء التنفيذ، يتم إزالة Execution Context ويعود التنفيذ إلى السياق السابق. function outer() { const x = 5; function inner() { console.log(x); } inner(); } outer(); // سيتم طباعة قيمة 5 في المثال السابق، الدالة الداخلية inner يمكنها الوصول إلى المتغير x المعرف في البيئة الخارجية (outer)، لأن Execution Context يحتفظ بالارتباط بين الدوال والقيم المرتبطة بها في نطاق الكود. الـ Lexical Environment يشير إلى المكان الذي يتم فيه تحديد القيم المرتبطة بالمتغيرات في الكود. يحتوي البيئة اللغوية على إعلانات المتغيرات والدوال والكائنات الأخرى، وتحدد كيفية الوصول إليها وكيفية تفاعلها مع بعضها البعض. مثال: في JavaScript، يتم تشكيل الـ Lexical Environment عند تحديد النطاقات اللغوية. أي عند البحث عن قيمة متغير، يتم البحث في Lexical Environment الحالي وفي البيئات الأبوية حتى يتم العثور على القيمة. function outer() { const x = 5; function inner() { console.log(x); } inner(); } outer(); // سيتم طباعة قيمة 5 هنا الدالة الداخلية inner يمكنها الوصول إلى المتغير x المعرف في البيئة اللغوية الخارجية (outer)، لأن Lexical Environment يحتفظ بالارتباط بين الدوال والقيم المرتبطة بها في نطاق الكود. شرح الدوال في JavaScript من موسوعة حسوب
  21. حاول تغيير ترتيب الدوال في ملف login.jsx: import { login } from "../../redux/actions/authActions.js"; const handleChange = (e) => { const { name, value } = e.target; setUserData({ ...userData, [name]: value }); }; const handlevalid = async (res) => { if (res.token) { setIsCorrect(true); } else { setIsCorrect(false); } }; const handleLogin = async (e) => { e.preventDefault(); setUserData({ email, password }); try { const res = await dispatch(login(userData)); // انتظر حتى انتهاء العملية console.log(res); // استخدم الاستجابة المتاحة هنا handlevalid(res); // قم بتمرير الاستجابة كمعامل للدالة console.log(auth); } catch (error) { // إدارة الأخطاء هنا } }; قمت بنقل الاستدعاء للدالة handlevalid() بعد استلام الاستجابة من login()، وتمرير الاستجابة كمعامل للدالة handlevalid() لكي تتمكن من استخدامها فيها. وبالتالي، يجب أن تحصل على طباعة صحيحة لـ auth من الضغطة الأولى على زر login. وإذا استمرت المشكلة، أرجو منك رفع مجلد المشروع بعد ضغطه لتفقد المشكلة.
  22. في CSS، تعتبر ":before" عنصر زائف وتستخدم لإضافة محتوى قبل عنصر محدد، بينما ":after" تستخدم لإضافة محتوى بعد عنصر محدد، وغالبًا تستخدم هاتين الخاصيتين لإضافة عناصر مرئية إلى عناصر HTML الموجودة. لكن في حالة عنصر الإدخال "input"، يعتبر استخدام ":before" غير صحيح ولا يعمل على نحو صحيح.، ذلك لأنه عنصر الإدخال "input" يعتبر عنصراً فارغاً لا يحتوي على محتوى داخلي. مما يعني أنه لا يمكنك استخدام ":before" لإضافة محتوى قبل عنصر "input" نفسه. وإذا كنت ترغب في إنشاء رمز البحث داخل عنصر الإدخال "input"، تستطيع استخدام العديد من الطرق لتحقيق ذلك. واحدة من هذه الطرق هي وضع عنصر فرعي مستقل للعنصر "input" واستخدام الخاصية "position: absolute" لتحديد موقع الرمز بالنسبة لعنصر الإدخال، كتعيين أيقونة لرمز البحث كخلفية للعنصر الفرعي وتنسيقه بواسطة CSS ليتناسب مع المظهر المطلوب. وسأوضح لك الكود اللازم لإنشاء رمز البحث داخل عنصر الإدخال "input" باستخدام خاصية "position: absolute": HTML: <div class="search-container"> <input type="text" class="search-input"> <span class="search-icon"></span> </div> CSS: .search-container { position: relative; } .search-icon { position: absolute; top: 50%; right: 10px; transform: translateY(-50%); width: 20px; height: 20px; background-image: url('path/to/search-icon.png'); background-size: cover; } .search-input { padding-right: 30px; } حيث قمت بإنشاء عنصر <div> لتكون حاوية لعنصر الإدخال "input" وعنصر الرمز "span". ثم بتعيين الخاصية "position: relative" للعنصر الحاوي .search-container ليمكن تحديد موقع العناصر الفرعية بالنسبة له. وتحديد الخاصية "position: absolute" للعنصر الفرعي .search-icon ليمكن تحديد موقعه بالنسبة للحاوية. ثم استخدمت الخاصيات top, right, transform لتحديد موقع الرمز في الزاوية العلوية اليمنى ووسط العنصر، قمت أيضًا بتعيين خلفية للرمز باستخدام خاصية "background-image" وتحديد حجمها باستخدام "background-size". أخيرًا، تعديل حجم عنصر الإدخال "input" بإضافة الحشو على الجانب الأيمن ليسمح بوجود مساحة كافية لعرض الرمز داخل العنصر. ولا تنسى استبدال 'path/to/search-icon.png' بمسار الصورة الخاصة بأيقونة البحث، أو تستطيع استخدام أيقونة من Font Awesome. وإليك مثال إذا أردت استخدام Font Awesome: HTML: <!DOCTYPE html> <html> <head> <!-- استيراد Font Awesome --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw==" crossorigin="anonymous" referrerpolicy="no-referrer" /> </head> <body> <div class="search-container"> <input type="text" class="search-input"> <span class="search-icon"><i class="fas fa-search"></i></span> </div> </body> </html> قمت بتحديد الأيقونة المستخدمة لرمز البحث باستخدام العنصر <i> ومنحها الفئات المناسبة .fas و .fa-search، حيث .fas تعني استخدام الأيقونات الخطية (Solid) و.fa-search تعني استخدام أيقونة البحث. CSS: .search-container { position: relative; } .search-icon { position: absolute; top: 50%; right: 10px; transform: translateY(-50%); width: 20px; height: 20px; color: #999; /* لتغيير لون الأيقونة */ } .search-input { padding-right: 30px; }
  23. لكي تتأكد من أن الدالة handlevalid() وطباعة console.log(auth) تعملان بعد انتهاء عملية login()، عليك باستخدام مفهوم Promises في JavaScript. أي عدل الكود كما يلي في ملف authAction.js: import { postDataApi } from "../../utils/fetchDataApi"; export const login = (data) => async (dispatch) => { try { const res = await postDataApi(`login`, data); localStorage.setItem('login', true); dispatch({ type: "AUTH", payload: { token: res.data.access_token, user: res.data.user } }); localStorage.setItem('login', true); console.log(res); return res; // يتم إرجاع الاستجابة لتصبح متاحة للدالة المستدعاة } catch (error) { // إدارة الأخطاء هنا } }; في ملف login.jsx: import { login } from "../../redux/actions/authActions.js"; const handleChange = (e) => { const { name, value } = e.target; setUserData({ ...userData, [name]: value }); }; const handlevalid = async () => { if (auth.token) { setIsCorrect(true); } else { setIsCorrect(false); } }; const handleLogin = async (e) => { e.preventDefault(); setUserData({ email, password }); try { const res = await dispatch(login(userData)); // انتظر حتى انتهاء العملية console.log(res); // استخدم الاستجابة المتاحة هنا handlevalid(); console.log(auth); } catch (error) { // إدارة الأخطاء هنا } }; مع هذه التغييرات، الآن الدالة handleLogin() ستنتظر انتهاء العملية في login() باستخدام الكلمة المفتاحية await وستحتفظ بالاستجابة في المتغير res. بعد ذلك، تستطيع استخدام الاستجابة في console.log(res) أو أي عملية أخرى قبل استدعاء handlevalid() وconsole.log(auth).
  24. حاول تجربة استخدام المتغير العالمي $_SERVER['HTTP_REFERER'] في صفحة page.php للتحقق من الموقع الذي يحاول الوصول إلى الصفحة عبر iframe. وتستطيع التحقق من قيمة المتغير ومقارنتها بعنوان الموقع المسموح به (domain2.com)، وإذا كانت مختلفة، يمكنك عرض رسالة "غير مسموح". وإليك مثال لكود PHP بإمكانك استخدامه في صفحة page.php: <?php $allowedDomain = 'http://domain2.com'; // التحقق من وجود قيمة referer ومقارنتها بالموقع المسموح به if (isset($_SERVER['HTTP_REFERER']) && strpos($_SERVER['HTTP_REFERER'], $allowedDomain) !== 0) { echo "غير مسموح"; exit; } // استمرار في عرض محتوى الصفحة ?> <!DOCTYPE html> <html> <head> <title>صفحة</title> </head> <body> <!-- محتوى الصفحة هنا --> </body> </html> ولاحظ أنه على الرغم من أن هذا الحل يعمل في معظم الحالات، إلا أنه يعتمد على قيمة $_SERVER['HTTP_REFERER'] التي يتم إرسالها من المستعرض، والتي قد تكون غير موثوقة في بعض الحالات. وربما من الأفضل استخدام حلول قائمة على الجانب الخادم، مثل .htaccess، إذا كنت ترغب في تعزيز الأمان.
  25. من الأفضل قراءة المستندات الخاصة بمكتبة Three.js وهي متوفرة بالعربية أيضًا من خلال الرابط التالي: https://threejs.org/docs/#manual/ar/introduction/Installation حيث أنها ستوفر لك الطريقة السليمة لاستخدام المكتبة. وبخصوص الكود الخاص بك لاحظي أنه في السكريبت لم يتم استدعاء GLTFLoader و DRACOLoader بشكل صحيح في الكود الخاص بك. فأنت قمت باستدعاء المكتبة باسم THREE وبالتالي يجب استيراد الدوال المرادة منها. والصحيح هو تعريف المتغيرات GLTFLoader و DRACOLoader واستخدامها فيما بعد، على النحو التالي: const loader = new THREE.GLTFLoader(); const draco = new THREE.DRACOLoader(); draco.setDecoderPath('/examples/jsm/libs/draco/'); loader.setDRACOLoader(draco); حاولي استخدام الكود التالي حيث قمت باستيراد المكتبات عن طريق CDN وكتابة HTML والسكريبت في صفحة واحدة لمعرفة أين يقع الخطأ بالضبط: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://cdn.jsdelivr.net/npm/three@0.131.2/build/three.js"></script> <script src="https://cdn.jsdelivr.net/npm/three@0.131.2/examples/js/loaders/GLTFLoader.js"></script> <title>3D</title> <style> body { margin: 0; overflow: hidden; } </style> </head> <body> <script> const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.z = 5; const renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); const loader = new THREE.GLTFLoader(); loader.load( 'path/to/your/home.glb', function (gltf) { scene.add(gltf.scene); }, undefined, function (error) { console.error('An error occurred while loading the model:', error); } ); function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate(); </script> </body> </html>
×
×
  • أضف...