হ্যালো!
আজ আমি আপনাকে দেখাব কিভাবে সার্ভার-চালিত UI-এর জন্য Flutter- এ একটি সুপার-ডুপার ইঞ্জিন তৈরি করা যায়, যা একটি সুপার-ডুপার CMS-এর অবিচ্ছেদ্য অংশ (এভাবেই এটির নির্মাতা, অর্থাৎ আমি, এটির অবস্থান)। আপনি, অবশ্যই, একটি ভিন্ন মতামত থাকতে পারে, এবং আমি মন্তব্যে এটি আলোচনা করতে খুশি হবে.
এই নিবন্ধটি সিরিজের দুটি (ইতিমধ্যে তিনটি) প্রথম। এই একটিতে, আমরা সরাসরি নুইকে দেখব, এবং পরেরটিতে - নুই কতটা গভীরভাবে Nanc CMS-এর সাথে একত্রিত হয়েছে, এবং এই এবং পরবর্তী নিবন্ধের মধ্যে নুই পারফরম্যান্স সম্পর্কে প্রচুর পরিমাণে তথ্য সহ আরও একটি থাকবে।
এই নিবন্ধে সার্ভার-চালিত UI, Nui (Nanc সার্ভার-চালিত UI) ক্ষমতা, প্রকল্পের ইতিহাস, স্বার্থপর স্বার্থ এবং ডক্টর স্ট্রেঞ্জ সম্পর্কে অনেক আকর্ষণীয় জিনিস থাকবে। ওহ হ্যাঁ, GitHub এবং pub.dev-এর লিঙ্কও থাকবে, তাই আপনি যদি এটি পছন্দ করেন এবং আপনার 1-2 মিনিট সময় ব্যয় করতে আপত্তি করবেন না - আমি আপনার তারকা এবং লাইক পেয়ে খুশি হব।
আমি ইতিমধ্যে Nanc সম্পর্কে একটি নিবন্ধ লিখেছি, কিন্তু তারপর থেকে, এক বছরেরও বেশি সময় পেরিয়ে গেছে এবং প্রকল্পটি সক্ষমতা এবং "সম্পূর্ণতার" দিক থেকে উল্লেখযোগ্যভাবে অগ্রসর হয়েছে এবং সবচেয়ে গুরুত্বপূর্ণ - এটি সমাপ্ত ডকুমেন্টেশন সহ মুক্তি পেয়েছে, এবং MIT-এর অধীনে লাইসেন্স.
এটি একটি সাধারণ-উদ্দেশ্য CMS যা এটির সাথে এর ব্যাকএন্ড টেনে আনে না। একই সময়ে, এটি প্রতিক্রিয়া অ্যাডমিনের মতো কিছু নয়, যেখানে কিছু তৈরি করতে আপনাকে প্রচুর কোড লিখতে হবে।
Nanc ব্যবহার শুরু করার জন্য, এটি যথেষ্ট:
তদুপরি, প্রথমটি সম্পূর্ণভাবে সিএমএসের ইন্টারফেসের মাধ্যমে করা যেতে পারে - অর্থাৎ, আপনি UI এর মাধ্যমে ডেটা কাঠামো পরিচালনা করতে পারেন। দ্বিতীয়টি বাদ দেওয়া যেতে পারে যদি:
এইভাবে, কিছু পরিস্থিতিতে, আপনার কোনো বিষয়বস্তু এবং ডেটা পরিচালনার জন্য একটি CMS পেতে আপনাকে কোডের একটি লাইন লিখতে হবে না। ভবিষ্যতে, এই পরিস্থিতিগুলির সংখ্যা বাড়বে, ধরা যাক - প্লাস গ্রাফকিউএল এবং রেস্টএপিআই। আপনার যদি ধারনা থাকে যে এর জন্য একটি SDK বাস্তবায়ন করা সম্ভব হবে - আমি মন্তব্যগুলিতে পরামর্শগুলি পড়ে খুশি হব।
Nanc সত্তার সাথে কাজ করে - ওরফে মডেল, যা ডেটা স্টোরেজ স্তর স্তরে একটি টেবিল (SQL) বা একটি নথি (No-SQL) হিসাবে উপস্থাপন করা যেতে পারে। প্রতিটি সত্তার ক্ষেত্র রয়েছে - SQL থেকে কলামের একটি উপস্থাপনা, অথবা No-SQL থেকে একই "ক্ষেত্র"।
সম্ভাব্য ক্ষেত্রের প্রকারগুলির মধ্যে একটি হল তথাকথিত "স্ক্রিন" প্রকার। অর্থাৎ, এই সম্পূর্ণ নিবন্ধটি CMS থেকে শুধুমাত্র একটি ক্ষেত্রের পাঠ্য। একই সময়ে, স্থাপত্যগতভাবে এটি এইরকম দেখায় - একটি সম্পূর্ণ আলাদা লাইব্রেরি রয়েছে ( আসলে বেশ কয়েকটি লাইব্রেরি ) , যা একসাথে Nui নামক সার্ভার-চালিত UI ইঞ্জিন প্রয়োগ করে। এই কার্যকারিতাটি সিএমএসে একত্রিত করা হয়েছে, যার উপরে অনেকগুলি অতিরিক্ত বৈশিষ্ট্য রোল করা হয়েছে৷
এর সাথে, আমি সূচনা অংশটি শেষ করি যা সরাসরি ন্যাঙ্ককে উত্সর্গ করা হয়েছে এবং নুই সম্পর্কে গল্প শুরু করি।
দাবিত্যাগ: সমস্ত কাকতালীয় ঘটনা আকস্মিক। এই গল্পটি কাল্পনিক। আমি এটা স্বপ্ন.
আমি এক সাথে একাধিক অ্যাপ্লিকেশনে একটি বড় কোম্পানিতে কাজ করেছি। তারা মূলত একই ছিল কিন্তু অনেক পার্থক্য ছিল.
তবে তাদের মধ্যে যা ছিল তা ছিল আমি আর্টিকেল ইঞ্জিন বলতে পারি। এটিতে বেশ কয়েকটি (5-10-15, আমি আর ঠিক মনে করতে পারছি না) হাজার হাজার লাইন বরং চূর্ণবিচূর্ণ কোডের সমন্বয়ে গঠিত যা ব্যাকএন্ড থেকে JSON কে প্রসেস করেছে। এই JSONগুলিকে শেষ পর্যন্ত UI-তে পরিণত করতে হয়েছিল, বা বরং, একটি মোবাইল অ্যাপ্লিকেশনে পড়ার জন্য একটি নিবন্ধে পরিণত করতে হয়েছিল৷
নিবন্ধগুলি অ্যাডমিন প্যানেল ব্যবহার করে তৈরি এবং সম্পাদনা করা হয়েছিল, এবং নতুন উপাদান যুক্ত করার প্রক্রিয়াটি খুব, অবিশ্বাস্যভাবে, অত্যন্ত বেদনাদায়ক এবং দীর্ঘ ছিল। এই ভয়াবহতা দেখে, আমি প্রথম অপ্টিমাইজেশন প্রস্তাব করার সিদ্ধান্ত নিয়েছি - দরিদ্র বিষয়বস্তু পরিচালকদের প্রতি করুণা করতে এবং তাদের জন্য ব্রাউজারে, অ্যাডমিন প্যানেলে রিয়েল-টাইমে নিবন্ধগুলির পূর্বরূপ দেখার কার্যকারিতা বাস্তবায়ন করতে।
বলেছেন এবং সম্পন্ন করেছেন। কিছু সময় পরে, অ্যাডমিন প্যানেলে অ্যাপ্লিকেশনটির একটি ছোট অংশ ঘুরছিল, যা পরিবর্তনের পূর্বরূপ দেখার সময় বিষয়বস্তু পরিচালকদের অনেক সময় বাঁচিয়েছিল। যদি, আগে, তাদের একটি গভীর লিঙ্ক তৈরি করতে হয়, এবং তারপরে প্রতিটি পরিবর্তনের জন্য dev বিল্ড খুলুন, এই লিঙ্কটি অনুসরণ করুন, ডাউনলোডের জন্য অপেক্ষা করুন এবং তারপরে সবকিছু পুনরাবৃত্তি করুন, এখন তারা কেবল নিবন্ধগুলি তৈরি করতে এবং এখুনি দেখতে পারে।
কিন্তু আমার চিন্তা সেখানে থামেনি - আমি এই ইঞ্জিনটি এবং অন্যান্য ডেভেলপারদের দ্বারা খুব বিরক্ত ছিলাম কারণ এটি নির্ধারণ করা সম্ভব ছিল যে তাদের এটিতে কিছু যোগ করতে হবে নাকি কেবল অজিয়ান আস্তাবলগুলি পরিষ্কার করতে হবে।
যদি এটি পরবর্তী হয়, তাহলে ডেভেলপার সবসময় মিটিংয়ে ভালো মেজাজে থাকতেন—যদিও গন্ধ... ক্যামেরা তা ক্যাপচার করতে পারে না।
যদি এটি পূর্বের হয়, তবে বিকাশকারী প্রায়শই অসুস্থ ছিলেন, ভূমিকম্পের মধ্যে থাকতেন, একটি ভাঙা কম্পিউটার, মাথাব্যথা, উল্কাপিণ্ডের প্রভাব, টার্মিনাল স্টেজ ডিপ্রেশন বা উদাসীনতার অতিরিক্ত মাত্রা ছিল।
ইঞ্জিনের কার্যকারিতা প্রসারিত করার জন্য অ্যাডমিন প্যানেলে অসংখ্য নতুন ক্ষেত্র যোগ করা প্রয়োজন যাতে বিষয়বস্তু পরিচালকরা নতুন বৈশিষ্ট্যগুলি ব্যবহার করতে পারে।
এই সব দেখে, আমি একটি অবিশ্বাস্য চিন্তা দ্বারা তাড়িত হয়েছিলাম: কেন এই সমস্যার একটি সাধারণ সমাধান তৈরি করবেন না? একটি সমাধান যা আমাদের প্রতিটা নতুন উপাদানের জন্য অ্যাডমিন প্যানেল এবং অ্যাপ্লিকেশনকে ক্রমাগত টুইক করা এবং প্রসারিত করা থেকে বিরত রাখবে। একবার এবং সব জন্য সমস্যা সমাধান হবে যে একটি সমাধান! এবং এখানে আসে...
আমি ভেবেছিলাম - "আমি এই সমস্যার সমাধান করতে পারি। আমি কোম্পানীকে কয়েক হাজার না হলেও দশ হাজার বাঁচাতে পারি; কিন্তু ধারণাটি কোম্পানির পক্ষে খুব মূল্যবান হতে পারে যে এটিকে উপহার হিসাবে দিতে পারে ।"
উপহার দ্বারা, আমি বলতে চাচ্ছি যে কোম্পানির জন্য সম্ভাব্য মূল্যের অনুপাতটি বিশালতার আদেশ দ্বারা কোম্পানি আমাকে বেতনের আকারে যা প্রদান করবে তার থেকে আলাদা। এটি এমন যে আপনি যদি প্রাথমিক পর্যায়ে একটি স্টার্টআপে কাজ করতে গিয়েছিলেন তবে কোনও বড় কোম্পানিতে আপনাকে যে বেতন দেওয়া হয় তার চেয়ে কম বেতনে এবং কোম্পানিতে শেয়ার ছাড়াই৷ এবং তারপরে স্টার্টআপটি একটি ইউনিকর্ন হয়ে যায় এবং তারা আপনাকে বলে - "আচ্ছা, বন্ধু, আমরা আপনাকে বেতন দিয়েছি।" এবং তারা সঠিক হবে!
আমি উপমা পছন্দ করি, কিন্তু আমাকে প্রায়ই বলা হয় যে সেগুলি আমার শক্তিশালী স্যুট নয়। মনে হচ্ছে আপনি একটি মাছ সমুদ্রে সাঁতার কাটতে পছন্দ করেন, কিন্তু আপনি একটি মিঠা পানির মাছ।
এবং তারপর - আমি আমার অবসর সময়ে ধারণার একটি প্রমাণ (পিওসি) তৈরি করার সিদ্ধান্ত নিয়েছি, যাতে এমন কিছু ধারণা দেওয়া হয় যা বাস্তবায়ন করা সম্ভব নাও হতে পারে।
মূল পরিকল্পনাটি ছিল মার্কডাউন রেন্ডার করার জন্য একটি বিদ্যমান রেডিমেড লাইব্রেরি ব্যবহার করা কিন্তু এর ক্ষমতাগুলিকে প্রসারিত করা যাতে এটি মার্কডাউন তালিকা থেকে শুধুমাত্র স্ট্যান্ডার্ড উপাদানগুলিই রেন্ডার করতে পারে না বরং আরও জটিল কিছুও তৈরি করতে পারে। নিবন্ধগুলি কেবল ছবি সহ পাঠ্য ছিল না। একটি সুন্দর ভিজ্যুয়াল ডিজাইন, অন্তর্নির্মিত অডিও প্লেয়ার এবং আরও অনেক কিছু ছিল।
আমি এই অনুমান পরীক্ষা করার জন্য শুক্রবার সন্ধ্যা থেকে সোমবার সকাল পর্যন্ত 40 ঘন্টা ব্যয় করেছি - এই লাইব্রেরিটি নতুন বৈশিষ্ট্যগুলির জন্য কতটা এক্সটেনসিবল, সাধারণভাবে সবকিছু কতটা ভাল কাজ করে এবং সবচেয়ে গুরুত্বপূর্ণ - এই সমাধানটি সিংহাসন থেকে কুখ্যাত ইঞ্জিনকে উৎখাত করতে পারে কিনা। হাইপোথিসিসটি নিশ্চিত করা হয়েছিল - লাইব্রেরিটিকে হাড়গুলিতে বিচ্ছিন্ন করার পরে এবং সামান্য প্যাচিংয়ের পরে, কীওয়ার্ড বা বিশেষ সিনট্যাক্স নির্মাণের মাধ্যমে কোনও UI উপাদান নিবন্ধন করা সম্ভব হয়েছিল, এই সমস্ত সহজেই প্রসারিত করা যেতে পারে, এবং সবচেয়ে গুরুত্বপূর্ণ - এটি সত্যিই নিবন্ধ ইঞ্জিনকে প্রতিস্থাপন করতে পারে। . আমি 15 ঘন্টার মধ্যে কোথাও এসেছি। বাকি 25 আমি POC চূড়ান্ত করতে ব্যয় করেছি।
ধারণাটি কেবল একটি ইঞ্জিনকে অন্য ইঞ্জিনের সাথে প্রতিস্থাপন করা নয় - না। ধারণা ছিল পুরো প্রক্রিয়া প্রতিস্থাপন! অ্যাডমিন প্যানেল আপনাকে কেবল নিবন্ধগুলি তৈরি করতে দেয় না তবে অ্যাপ্লিকেশনটিতে দৃশ্যমান বিষয়বস্তুও পরিচালনা করে। মূল ধারণাটি ছিল একটি সম্পূর্ণ প্রতিস্থাপন তৈরি করা যা একটি নির্দিষ্ট প্রকল্পের সাথে আবদ্ধ হবে না তবে এটি পরিচালনা করার অনুমতি দেবে। সবচেয়ে গুরুত্বপূর্ণ - এই প্রতিস্থাপনটি এই নিবন্ধগুলির জন্য একটি সুবিধাজনক সম্পাদক প্রদান করা উচিত যাতে সেগুলি তৈরি করা যায় এবং অবিলম্বে ফলাফল দেখতে পারে।
POC-এর জন্য, আমি ভেবেছিলাম শুধুমাত্র একজন সম্পাদক করাই যথেষ্ট। এটি এই মত কিছু দেখাচ্ছিল:
40 ঘন্টা পরে, আমার কাছে মার্কডাউনের অশান্ত মিশ্রণ এবং একগুচ্ছ কাস্টম XML ট্যাগ (উদাহরণস্বরূপ, <container>
), একটি প্রিভিউ যা এই কোড থেকে UI প্রদর্শন করে, এবং সবচেয়ে বড় চোখের ব্যাগ যা এই পৃথিবী কখনও দেখেনি। এটিও লক্ষণীয় যে ব্যবহৃত "কোড এডিটর" হল আরেকটি লাইব্রেরি যা সিনট্যাক্স হাইলাইট করতে সক্ষম, কিন্তু সমস্যা হল এটি মার্কডাউন হাইলাইট করতে পারে, এটি XML হাইলাইটও করতে পারে, কিন্তু একটি হজপজের হাইলাইটিং ক্রমাগত ভেঙে যায়। সুতরাং 40 ঘন্টার জন্য, আপনি একটি কাইমেরার বানর-কোডিংয়ের জন্য আরও কয়েকটি যোগ করতে পারেন যা একটি বোতলে উভয়ের হাইলাইটিং প্রদান করবে। প্রশ্ন করার সময় এসেছে- এরপর কী হলো?
পরবর্তী ডেমো ছিল. আমি কয়েকজন সিনিয়র ম্যানেজারকে একত্রিত করেছি, তাদের সমস্যা সমাধানের জন্য আমার দৃষ্টিভঙ্গি ব্যাখ্যা করেছি, বাস্তবে আমি এই দৃষ্টিভঙ্গিটি নিশ্চিত করেছি এবং দেখিয়েছি কী কাজ করে এবং কীভাবে, এবং এর কী সম্ভাবনা রয়েছে।
ছেলেরা কাজটি পছন্দ করেছে। এবং এটি ব্যবহার করার ইচ্ছা ছিল। কিন্তু একটা লোভও ছিল। আমার লোভ। আমি কি ঠিক সেইভাবে কোম্পানিকে দিতে পারতাম না? অবশ্যই না. কিন্তু আমি কোনটাই পরিকল্পনা করিনি। ডেমোটি ছিল একটি সাহসী পরিকল্পনার অংশ যেখানে আমি তাদের আমার নৈপুণ্য দিয়ে হতবাক করে দিয়েছিলাম, তারা কেবল প্রতিরোধ করতে পারেনি এবং এই অবিশ্বাস্য, একচেটিয়া, এবং আশ্চর্যজনক বিকাশ ব্যবহার করার জন্য যে কোনও শর্ত পূরণ করতে প্রস্তুত ছিল৷ আমি এই কাল্পনিক (!) গল্পের সমস্ত বিবরণ প্রকাশ করব না, তবে আমি কেবল বলব যে আমি অর্থ চেয়েছিলাম। টাকা এবং একটি ছুটি. একটি বেতনের এক মাসের ছুটি, সেইসাথে টাকা। কত টাকা এত গুরুত্বপূর্ণ নয়, এটি শুধুমাত্র গুরুত্বপূর্ণ যে পরিমাণটি আমার বেতন এবং 6 নম্বরের সাথে সম্পর্কযুক্ত।
কিন্তু আমি সম্পূর্ণ বেপরোয়া সাহসী ছিলাম না।
দোর্মাম্মু, আমি দর কষাকষি করতে এসেছি। এবং চুক্তিটি নিম্নরূপ ছিল - আমি আমার মোডে পুরো দুই সপ্তাহ কাজ করি ( 4 ঘন্টা ঘুমাচ্ছি, 20 ঘন্টা কাজ করি ), POC-কে "আমাদের অ্যাপের উদ্দেশ্যে ব্যবহার করা যেতে পারে" অবস্থায় শেষ করে, এবং এর সমান্তরালে, আমি বাস্তবায়ন করি অ্যাপ্লিকেশনটিতে একটি নতুন বৈশিষ্ট্য - একটি সম্পূর্ণ স্ক্রীন, এই অতি-বিষয়টি ব্যবহার করে (যার জন্য এই দুই সপ্তাহ মূলত বরাদ্দ করা হয়েছিল)। এবং দুই সপ্তাহের শেষে, আমরা আরেকটি ডেমো রাখি। শুধুমাত্র এই সময়েই আমরা আরও লোক সংগ্রহ করি, এমনকি কোম্পানির শীর্ষস্থানীয় ব্যবস্থাপনা, এবং তারা যা দেখে তা তাদের মুগ্ধ করে, এবং তারা এটি ব্যবহার করতে চায় - চুক্তিটি হয়ে গেছে, আমি আমার ইচ্ছাগুলি পাই এবং কোম্পানি একটি সুপার বন্দুক পায়। যদি তারা এর কিছুই না চায় - আমি এই দুই সপ্তাহ বিনামূল্যে কাজ করেছি তা মেনে নিতে প্রস্তুত।
ঠিক আছে, উরুবিসি ভ্রমণ, যা আমি ইতিমধ্যে আমার মাসব্যাপী ছুটির জন্য পরিকল্পনা করেছিলাম, দুর্ভাগ্যবশত, কখনও ঘটেনি। ম্যানেজার ছেলেরা এমন ধৃষ্টতায় রাজি হওয়ার সাহস করেনি। এবং আমি, মাটিতে আমার দৃষ্টি নিচু করে, "ক্লাসিক উপায়ে" একটি নতুন পর্দা ঝকঝকে করতে গিয়েছিলাম। কিন্তু এমন কোনো গল্প নেই যেখানে প্রধান চরিত্র ভাগ্যের কাছে পরাজিত হয়ে হাঁটু থেকে উঠে আবার তার পশুকে বশ করার চেষ্টা করে না।
যদিও না... মনে হচ্ছে এখানে আছে: 1 , 2 , 3 , 4 , 5 ।
এই সমস্ত সিনেমা দেখে আমি সিদ্ধান্ত নিলাম যে এটি একটি চিহ্ন ! এবং এটি এইভাবে আরও ভাল - সেখানে কিছু জিনিসপত্রের জন্য এমন একটি প্রতিশ্রুতিশীল বিকাশ বিক্রি করা দুঃখের বিষয় ( আমি কে মজা করছি??? ), এবং আমি আমার প্রকল্পটি আরও বিকাশ করতে থাকব। এবং আমি অব্যাহত. তবে সপ্তাহান্তে আর 40 ঘন্টা নয়, অপেক্ষাকৃত শান্ত গতিতে সপ্তাহে মাত্র 15-20 ঘন্টা।
৪র্থ দেয়াল ভাঙ্গা সহজ কাজ নয়। ঠিক যেমন আকর্ষণীয় শিরোনাম নিয়ে আসার চেষ্টা করা যা পাঠককে পড়া চালিয়ে যেতে এবং সংস্থার সাথে গল্পটি কীভাবে শেষ হবে তার জন্য অপেক্ষা করবে। দ্বিতীয় লেখায় গল্পটা শেষ করব। এবং এখন, মনে হচ্ছে, এটি বাস্তবায়ন, কার্যকরী ক্ষমতা এবং সেই সমস্ত কিছুতে স্যুইচ করার সময়, যা তত্ত্বগতভাবে, এই নিবন্ধটিকে প্রযুক্তিগত এবং হ্যাকারনুনকে আরও বড় করে তুলতে হবে!
আমরা প্রথম জিনিস সম্পর্কে কথা বলতে হবে সিনট্যাক্স. মূল হোজপজ-আইডিয়াটি POC-এর জন্য উপযুক্ত ছিল, কিন্তু অনুশীলন যেমন দেখা গেছে, মার্কডাউন তত সহজ নয়। এছাড়াও, কিছু নেটিভ মার্কডাউন উপাদানগুলিকে সম্পূর্ণরূপে ফ্লটারের সাথে একত্রিত করা সবসময় সামঞ্জস্যপূর্ণ নয়।
খুব প্রথম প্রশ্ন হল - ছবিটি কি হবে ![Description](Link)
নাকি <image>
?
যদি প্রথম এক - যেখানে আমি পরামিতি একটি গুচ্ছ ধাক্কা না?
যদি দ্বিতীয়টি - কেন, তাহলে, আমাদের কি প্রথমটি আছে?
দ্বিতীয় প্রশ্নটি পাঠ্য। স্টাইলিং পাঠ্যের জন্য ফ্লটারের সম্ভাবনা সীমাহীন। মার্কডাউনের সম্ভাবনাগুলি হল "তাই-তাই"৷ হ্যাঁ, আপনি টেক্সটটিকে বোল্ড বা তির্যকভাবে চিহ্নিত করতে পারেন এবং স্টাইলিংয়ের জন্য এই নির্মাণগুলি **
/ __
ব্যবহার করার চিন্তাও ছিল। তারপরে মাঝখানে <color="red">
টেক্সট </color>
ট্যাগগুলি ঝাঁকানোর চিন্তা ছিল, কিন্তু এটি এমন বাঁকানো এবং হামাগুড়ি যে চোখ থেকে রক্ত বড়ছে। নিজস্ব প্রান্তিক সিনট্যাক্স সহ কিছু ধরণের এইচটিএমএল পাওয়া মোটেও কাম্য নয়। এছাড়াও, ধারণাটি ছিল যে এই কোডটি প্রযুক্তিগত জ্ঞান ছাড়া পরিচালকরাও লিখতে পারে।
ধাপে ধাপে, আমি কাইমেরার অংশটি সরিয়ে দিয়েছি এবং একটি মার্কডাউন সুপার-মিউট্যান্ট পেয়েছি। অর্থাৎ, মার্কডাউন রেন্ডার করার জন্য আমরা একটি প্যাচড লাইব্রেরি পেয়েছি, কিন্তু কাস্টম ট্যাগ দিয়ে পূর্ণ এবং মার্কডাউন সমর্থন ছাড়াই। অর্থাৎ, যেন আমরা XML পেয়েছি।
আমি ভাবতে বসেছিলাম এবং অন্যান্য সাধারণ সিনট্যাক্সগুলি কী রয়েছে তা নিয়ে পরীক্ষা করতে বসেছিলাম। JSON হল স্ল্যাগ। একজন ব্যক্তিকে একটি কুটিল ফ্লাটার এডিটরে JSON লিখতে বাধ্য করা একজন পাগল পেয়ে যাচ্ছে যে আপনাকে হত্যা করতে চাইবে৷ এবং এটি কেবল এটি সম্পর্কে নয়, এটি আমার কাছে মনে হয় না যে JSON সাধারণভাবে একজন ব্যক্তির দ্বারা টাইপ করার জন্য উপযুক্ত, বিশেষত UI-এর জন্য - এটি ক্রমাগত ডানদিকে বাড়ছে, বাধ্যতামূলক ""
এর একটি গুচ্ছ, কোনও মন্তব্য নেই৷ YAML? ভাল হয়ত. কিন্তু কোডটিও পাশে ক্রল করবে। আকর্ষণীয় লিঙ্ক আছে, কিন্তু আপনি একা তাদের সাহায্যে অনেক কিছু অর্জন করতে পারবেন না. TOML? Pf-ff.
ঠিক আছে, আমি সব পরে এক্সএমএল স্থির. এটি আমার কাছে মনে হয়েছিল, এবং এখনও মনে হচ্ছে, এটি একটি বরং "ঘন" সিনট্যাক্স, UI এর জন্য খুব উপযুক্ত। সর্বোপরি, এইচটিএমএল লেআউট ডিজাইনার এখনও বিদ্যমান, এবং এখানে সবকিছু ওয়েবের তুলনায় আরও সহজ হবে ( সম্ভবত )।
এরপরে, প্রশ্ন উঠেছে - কিছু হাইলাইটিং/কোড সমাপ্তির সম্ভাবনা পেতে ভালো লাগবে। যৌক্তিক নির্মাণের পাশাপাশি {{ user.name }}
। তারপর আমি টুইগ, লিকুইড নিয়ে পরীক্ষা-নিরীক্ষা শুরু করলাম, অন্য কিছু টেমপ্লেট ইঞ্জিনের দিকে তাকালাম যা আমার আর মনে নেই। কিন্তু আমি অন্য সমস্যায় পড়েছিলাম - একটি স্ট্যান্ডার্ড ইঞ্জিনে যা পরিকল্পনা করা হয়েছিল তার কিছু অংশ বাস্তবায়ন করা বেশ সম্ভব, বলুন, টুইগ, তবে এটি অবশ্যই সবকিছু বাস্তবায়ন করতে কাজ করবে না। এবং হ্যাঁ, এটি ভাল যে স্বয়ংক্রিয়-সম্পূর্ণতা এবং হাইলাইটিং থাকবে, তবে তারা কেবল তখনই হস্তক্ষেপ করবে যদি আপনি স্ট্যান্ডার্ড টুইগ সিনট্যাক্সের উপরে আপনার নিজস্ব নতুন বৈশিষ্ট্যগুলি রোল করেন, যা ফ্লটারের জন্য প্রয়োজন হবে। ফলস্বরূপ, XML এর সাথে, সবকিছু খুব ভালভাবে পরিণত হয়েছিল, টুইগ / লিকুইডের সাথে পরীক্ষাগুলি কোনও অসামান্য ফলাফল দেয়নি এবং কিছু নির্দিষ্ট পয়েন্টে, আমি এমনকি কিছু বৈশিষ্ট্য বাস্তবায়নের অসম্ভবতার মধ্যে পড়েছিলাম। অতএব, পছন্দটি এখনও XML এর সাথে রয়ে গেছে। আমরা বৈশিষ্ট্যগুলি সম্পর্কে আরও কথা বলব, তবে আপাতত, আসুন স্বয়ংক্রিয়-সম্পূর্ণতা এবং হাইলাইটিংয়ের উপর ফোকাস করা যাক, যা Twig/Liquid-এ খুব লোভনীয় ছিল।
পরের জিনিসটি আমি বলতে চাই যে Flutter এর আঁকাবাঁকা টেক্সট ইনপুট আছে। তারা মোবাইল ফর্ম্যাটে ভাল কাজ করে। ডেস্কটপ বিন্যাসেও ভাল যখন এটি কিছু আসে, ভাল, সর্বোচ্চ 5-10 লাইন উচ্চতা। কিন্তু যখন এটি একটি পূর্ণাঙ্গ কোড এডিটরের কথা আসে, যেখানে এই সম্পাদকটি ফ্লটারে বাস্তবায়িত হয় - আপনি চোখের জল ছাড়া এটি দেখতে পারবেন না। ট্রেলোতে , যেখানে আমি সমস্ত কাজের ট্র্যাক রাখি এবং নোট এবং ধারনা লিখি, সেখানে এমন একটি "টাস্ক" রয়েছে:
আসলে, প্রোজেক্টে কাজ করার প্রায় শুরু থেকেই, আমি নুই কোড এডিটরকে আরও পর্যাপ্ত কিছু দিয়ে প্রতিস্থাপন করার ধারণা মাথায় রেখেছিলাম। ধরা যাক - ভিএস কোড থেকে ওপেন সোর্স অংশের সাথে একটি ওয়েব ভিউ এম্বেড করুন। কিন্তু এখন পর্যন্ত, আমার হাত এটিতে পৌঁছায়নি, পাশাপাশি, এই সম্পাদকের বক্রতার সমস্যার একটি ক্রুচি কিন্তু এখনও কার্যকরী সমাধান আমার মাথায় এসেছিল - পরিবর্তে আপনার নিজস্ব উন্নয়ন পরিবেশ ব্যবহার করুন।
এটি নিম্নরূপ অর্জন করা হয় - UI-কোড (XML) দিয়ে একটি ফাইল তৈরি করুন, আদর্শভাবে এক্সটেনশন .html
/ .twig
সহ, একই ফাইলটি CMS- ওয়েব/ডেস্কটপ/স্থানীয়/ স্থাপনার মাধ্যমে খুলুন - এটা কোন ব্যাপার না। এবং একই ফাইলটি যেকোনো IDE-এর মাধ্যমে খুলুন, এমনকি VS Code-এর ওয়েব সংস্করণের মাধ্যমেও। এবং voila - আপনি আপনার প্রিয় টুলে এই ফাইলটি সম্পাদনা করতে পারেন, এবং ব্রাউজারে বা যে কোন জায়গায় একটি রিয়েল-টাইম প্রিভিউ পেতে পারেন৷
এই ধরনের একটি দৃশ্যে, আপনি এমনকি সম্পূর্ণ স্বয়ংক্রিয় সমাপ্তির উপর স্ক্রু করতে পারেন। ভিএস কোডে, কাস্টম এইচটিএমএল ট্যাগের মাধ্যমে এটি বাস্তবায়নের সম্ভাবনা রয়েছে। যাইহোক, আমি ভিএস কোড ব্যবহার করি না, আমার পছন্দ হল ইন্টেলিজ আইডিইএ এবং এই আইডিই-এর জন্য আর কোনও সহজ সমাধান নেই (ভাল, অন্তত সেখানে ছিল না, বা অন্তত আমি এটি খুঁজে পাইনি)। তবে আরও একটি সাধারণ সমাধান রয়েছে যা সেখানে এবং সেখানে উভয়ই কাজ করবে - এক্সএমএল স্কিমা ডেফিনিশন (এক্সএসডি)। আমি এই দানবটি খুঁজে বের করার চেষ্টা করার জন্য প্রায় 3 সন্ধ্যা কাটিয়েছি, কিন্তু সাফল্য কখনই আসেনি, এবং শেষ পর্যন্ত, আমি এই বিষয়টি পরিত্যাগ করেছি, এটি আরও ভাল সময়ের জন্য রেখেছি।
এটিও আকর্ষণীয় যে শেষ পর্যন্ত, পরীক্ষা-নিরীক্ষা, আপডেটের অনেক পুনরাবৃত্তির পরে, আসুন বলি, এক্সএমএলকে উইজেটে রূপান্তর করার জন্য দায়ী ইঞ্জিন, আমরা এমন একটি সমাধান পেয়েছি যার জন্য ভাষাটি বিশেষভাবে গুরুত্বপূর্ণ নয়। ঠিক আপনার UI এর গঠন সম্পর্কে তথ্যের বাহক হিসাবে, পছন্দটি অবশেষে XML-এর উপর পড়ে, কিন্তু একই সময়ে, আপনি নিরাপদে এটি JSON, এবং এমনকি একটি বাইনারি ফর্ম - সংকলিত Protobuf ভোজন করতে পারেন। এবং এটি আমাদের পরবর্তী বিষয়ে নিয়ে আসে।
এই বাক্যে, এই নিবন্ধটির আকার হবে 3218 শব্দ। যখন আমি এই বিভাগটি লিখতে শুরু করি, গুণগতভাবে সবকিছু করতে - নুই এবং নিয়মিত ফ্লাটার রেন্ডার করার পারফরম্যান্সের তুলনা করে প্রচুর পরীক্ষার ক্ষেত্রে লেখার প্রয়োজন ছিল। যেহেতু আমি ইতিমধ্যেই একটি ডেমো স্ক্রিন প্রয়োগ করেছি, সম্পূর্ণরূপে Nui-তে তৈরি করা হয়েছে:
নেটিভভাবে পর্দার একটি সঠিক মিল তৈরি করা প্রয়োজন ছিল (অবশ্যই ফ্লটার প্রসঙ্গে)। ফলস্বরূপ, এটি 3 সপ্তাহেরও বেশি সময় নিয়েছে, একই জিনিসটি আবার লিখতে, পরীক্ষার প্রক্রিয়াটি উন্নত করতে এবং আরও বেশি আকর্ষণীয় নম্বর পেতে। এবং একা এই বিভাগের আকার 3500 শব্দ অতিক্রম করেছে. অতএব, আমি এই ধারণাটি নিয়ে এসেছি যে একটি পৃথক নিবন্ধ লেখার অর্থ হয় যা সম্পূর্ণরূপে এবং সম্পূর্ণরূপে নুই-এর কার্যকারিতার প্রতি নিবেদিত হবে, একটি নির্দিষ্ট ক্ষেত্রে, এবং আপনি ব্যবহার করার সিদ্ধান্ত নিলে আপনাকে যে অতিরিক্ত মূল্য দিতে হবে। একটি পদ্ধতি হিসাবে সার্ভার-চালিত UI।
তবে আমি একটি ছোট স্পয়লার তৈরি করব: কর্মক্ষমতা মূল্যায়নের জন্য দুটি প্রধান পরিস্থিতি ছিল যা আমি বিবেচনা করেছি - প্রাথমিক রেন্ডারিংয়ের সময় । আপনি যদি সার্ভার-চালিত UI-তে পুরো স্ক্রীনটি বাস্তবায়ন করার সিদ্ধান্ত নেন তবে এটি গুরুত্বপূর্ণ, এবং এই স্ক্রিনটি আপনার অ্যাপ্লিকেশনের কোথাও খুলবে।
তাই যদি এই স্ক্রিনটি খুব ভারী হয়, তাহলে এমনকি একটি নেটিভ ফ্লাটার স্ক্রিন রেন্ডার হতে অনেক সময় নেবে, তাই এই ধরনের স্ক্রীনে স্যুইচ করার সময়, বিশেষ করে যদি এই রূপান্তরটি একটি অ্যানিমেশনের সাথে থাকে, ল্যাগগুলি দৃশ্যমান হবে৷ দ্বিতীয় দৃশ্যটি হল ফ্রেম টাইম (FPS) গতিশীল UI পরিবর্তন সহ । ডেটা পরিবর্তিত হয়েছে - আপনাকে কিছু উপাদান পুনরায় আঁকতে হবে। প্রশ্ন হল এটি রেন্ডারিং সময়কে কতটা প্রভাবিত করবে, এটি এতটা প্রভাবিত করবে কিনা যে স্ক্রিন আপডেট করা হলে ব্যবহারকারী ল্যাগ দেখতে পাবেন। এবং এখানে আরেকটি স্পয়লার রয়েছে - বেশিরভাগ ক্ষেত্রে, আপনি বলতে পারবেন না যে আপনি যে স্ক্রীনটি দেখছেন তা সম্পূর্ণরূপে Nui-তে প্রয়োগ করা হয়েছে। আপনি যদি একটি নুই উইজেটকে একটি নিয়মিত, নেটিভ ফ্লাটার স্ক্রিনে এম্বেড করেন (বলুন, স্ক্রিনের কিছু এলাকা যা অ্যাপ্লিকেশনে খুব গতিশীলভাবে পরিবর্তন করা উচিত) - আপনি এটিকে চিনতে সক্ষম হবেন না নিশ্চিত। কর্মক্ষমতা মধ্যে ড্রপ, অবশ্যই আছে. কিন্তু এগুলি এমন যে তারা 120FPS এর ফ্রেম রেটেও FPS-কে প্রভাবিত করে না - অর্থাৎ, একটি ফ্রেমের সময় প্রায় কখনই 8ms
অতিক্রম করবে না। এটি দ্বিতীয় দৃশ্যের জন্য সত্য। প্রথমটির জন্য - এটি সমস্ত পর্দার জটিলতার স্তরের উপর নির্ভর করে। কিন্তু এখানেও, পার্থক্যটি এমন হবে যে এটি উপলব্ধিকে প্রভাবিত করবে না এবং ব্যবহারকারীর স্মার্টফোনের জন্য আপনার অ্যাপ্লিকেশনটিকে একটি মানদণ্ডে পরিণত করবে না।
নীচে Pixel 7a থেকে তিনটি স্ক্রিন রেকর্ডিং রয়েছে (টেনসর G2, স্ক্রীন রিফ্রেশ রেট 90 ফ্রেমে সেট করা হয়েছিল (এই ডিভাইসের জন্য সর্বাধিক), ভিডিও রেকর্ডিং রেট 60 ফ্রেম প্রতি সেকেন্ডে (রেকর্ডিং সেটিংসের জন্য সর্বাধিক)। প্রতি 500 মিসে, উপাদানগুলির অবস্থান তালিকাটি র্যান্ডমাইজ করা হয়েছে, যে ডেটা থেকে প্রথম 3টি কার্ড তৈরি করা হয়েছে এবং আরও 500ms পরে, অর্ডার স্ট্যাটাসটি পরেরটিতে স্যুইচ করা হয়েছে আপনি কি অনুমান করতে পারবেন যে এই স্ক্রীনগুলির মধ্যে কোনটি সম্পূর্ণরূপে নুইতে প্রয়োগ করা হয়েছে?
PS চিত্রগুলির লোডিং সময় বাস্তবায়নের উপর নির্ভর করে না যেহেতু এই স্ক্রিনে, যে কোনও বাস্তবায়নের সাথে, প্রচুর Svg চিত্র রয়েছে - সমস্ত আইকন, সেইসাথে ব্র্যান্ড লোগো। সমস্ত svg (সাথে নিয়মিত ছবিগুলি) হোস্টিং হিসাবে গিটহাবে সংরক্ষণ করা হয়, তাই তারা বেশ ধীরে ধীরে লোড হতে পারে, যা কিছু পরীক্ষায় দেখা যায়।
YouTube:
নুই তৈরি করার সময়, আমি নিম্নলিখিত ধারণাটি মেনে চলেছি - এমন একটি টুল তৈরি করা প্রয়োজন যে, প্রথমত, ফ্লাটার বিকাশকারীরা এটিকে নিয়মিত ফ্লাটার অ্যাপ্লিকেশন তৈরি করার মতোই সহজ মনে করবে। অতএব, সমস্ত উপাদানের নামকরণের পদ্ধতিটি সহজ ছিল - ফ্লাটারে যেভাবে নামকরণ করা হয়েছে সেভাবে তাদের নামকরণ করা।
একই উইজেট পরামিতিগুলির ক্ষেত্রে প্রযোজ্য - স্কেলারগুলি, যেমন String
, int
, double
, enum
, ইত্যাদি, যা একটি প্যারামিটার হিসাবে, নিজেদের কনফিগার করা হয় না৷ Nui-এর মধ্যে এই ধরনের প্যারামিটারকে আর্গুমেন্ট বলা হয়। এবং জটিল শ্রেণির পরামিতিগুলিতে, যেমন Container
উইজেটে decoration
, যাকে বলা হয় সম্পত্তি । এই নিয়মটি পরম নয় যেহেতু কিছু বৈশিষ্ট্য খুব ভার্বস, তাই তাদের নাম সরলীকৃত করা হয়েছে। এছাড়াও, কিছু উইজেটের জন্য, উপলব্ধ পরামিতির তালিকা প্রসারিত করা হয়েছে। উদাহরণস্বরূপ - একটি বর্গাকার SizedBox
বা Container
তৈরি করতে, আপনি দুটি অভিন্ন width
+ height
পরিবর্তে শুধুমাত্র একটি কাস্টম আর্গুমেন্ট size
পাস করতে পারেন।
আমি বাস্তবায়িত উইজেটগুলির একটি সম্পূর্ণ তালিকা দেব না, কারণ তাদের মধ্যে বেশ কয়েকটি রয়েছে (এই মুহূর্তে 53)। সংক্ষেপে - আপনি প্রায় যেকোনো UI বাস্তবায়ন করতে পারেন যার জন্য নীতিগতভাবে একটি পদ্ধতি হিসাবে সার্ভার-চালিত UI ব্যবহার করা বোধগম্য হবে। Slivers
সাথে যুক্ত জটিল স্ক্রোলিং প্রভাব সহ।
এছাড়াও, উপাদানগুলির বিষয়ে, আপনাকে ক্লাউড এক্সএমএল-কোডটি পাস করতে হবে এমন এন্ট্রি পয়েন্ট বা উইজেটটি লক্ষ্য করার মতো। এই মুহুর্তে এরকম দুটি উইজেট রয়েছে - NuiListWidget
এবং NuiStackWidget
।
প্রথমটি, নকশা দ্বারা, যদি আপনি পুরো পর্দা বাস্তবায়নের প্রয়োজন হয় ব্যবহার করা উচিত। হুডের নীচে, এটি একটি CustomScrollView
যাতে সমস্ত উইজেট রয়েছে যা মূল মার্কআপ কোড থেকে পার্স করা হবে৷ তদুপরি, পার্সিং, কেউ বলতে পারে, "বুদ্ধিমান": যেহেতু CustomScrollView
এর বিষয়বস্তু slivers
হওয়া উচিত, তাহলে একটি সম্ভাব্য সমাধান হবে SliverToBoxAdapter
স্ট্রীমের প্রতিটি উইজেট মোড়ানো, কিন্তু এটি একটি অত্যন্ত নেতিবাচক প্রভাব ফেলবে কর্মক্ষমতা উপর অতএব, উইজেটগুলি তাদের পিতামাতার মধ্যে নিম্নরূপ এমবেড করা হয়েছে - প্রথমটি থেকে শুরু করে, আমরা একটি প্রকৃত sliver
সাথে দেখা না হওয়া পর্যন্ত আমরা তালিকার নিচে চলে যাই। যত তাড়াতাড়ি আমরা একটি sliver
সাথে দেখা করি - আমরা আগের সমস্ত উইজেটগুলিকে SliverList
যুক্ত করি এবং এটিকে মূল CustomScrollView
যুক্ত করি৷ এইভাবে, সম্পূর্ণ UI রেন্ডার করার কর্মক্ষমতা যতটা সম্ভব বেশি হবে, যেহেতু slivers
সংখ্যা ন্যূনতম হবে। CustomScrollView
প্রচুর slivers
থাকা খারাপ কেন? উত্তর এখানে আছে.
দ্বিতীয় উইজেট - NuiStackWidget
একটি পূর্ণ স্ক্রীন হিসাবেও ব্যবহার করা যেতে পারে - এই ক্ষেত্রে, এটি মনে রাখা মূল্যবান যে আপনি যা তৈরি করবেন তা একই ক্রমে Stack
মধ্যে এমবেড করা হবে। এবং এটি স্পষ্টভাবে slivers
ব্যবহার করার জন্যও প্রয়োজনীয় হবে - অর্থাৎ, আপনি যদি slivers
একটি তালিকা চান - আপনাকে CustomScrollView
যোগ করতে হবে এবং এটির ভিতরে তালিকাটি ইতিমধ্যেই প্রয়োগ করা হয়েছে৷
দ্বিতীয় দৃশ্যকল্প হল একটি ছোট উইজেটের বাস্তবায়ন যা নেটিভ উপাদানগুলিতে এম্বেড করা যেতে পারে। বলে রাখি- সার্ভারের উদ্যোগে সম্পূর্ণ কাস্টমাইজযোগ্য হবে এমন একটি পণ্য কার্ড তৈরি করা। এটি একটি খুব আকর্ষণীয় দৃশ্য বলে মনে হচ্ছে যেখানে আপনি Nui ব্যবহার করে উপাদান লাইব্রেরির সমস্ত উপাদান বাস্তবায়ন করতে পারেন এবং সেগুলিকে নিয়মিত উইজেট হিসাবে ব্যবহার করতে পারেন। একই সময়ে, অ্যাপ্লিকেশন আপডেট না করেই তাদের সম্পূর্ণরূপে পরিবর্তন করার সুযোগ থাকবে।
এটি লক্ষণীয় যে NuiListWidget
একটি স্থানীয় উইজেট হিসাবেও ব্যবহার করা যেতে পারে, এবং পুরো স্ক্রীনে নয়, তবে এই উইজেটের জন্য, আপনাকে উপযুক্ত বিধিনিষেধ প্রয়োগ করতে হবে, যেমন মূল উইজেটের জন্য একটি সুস্পষ্ট উচ্চতা সেট করা।
ফ্লটার ব্যবহার করে তৈরি করা হলে counter app
কেমন দেখাবে তা এখানে রয়েছে:
import 'package:flutter/material.dart'; import 'package:nui/nui.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Nui App', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const MyHomePage(title: 'Nui Demo App'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({ required this.title, super.key, }); final String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text(widget.title), ), body: Center( child: NuiStackWidget( renderers: const [], imageErrorBuilder: null, imageFrameBuilder: null, imageLoadingBuilder: null, binary: null, nodes: null, xmlContent: ''' <center> <column mainAxisSize="min"> <text size="18" align="center"> You have pushed the button\nthis many times: </text> <text size="32"> {{ page.counter }} </text> </column> </center> ''', pageData: { 'counter': _counter, }, ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: const Icon(Icons.add), ), ); } }
এবং এখানে আরেকটি উদাহরণ, শুধুমাত্র সম্পূর্ণরূপে নুইতে (যুক্তি সহ):
import 'package:flutter/material.dart'; import 'package:nui/nui.dart'; void main() { runApp(const MyApp()); } final DataStorage globalDataStorage = DataStorage(data: {'counter': 0}); final EventHandler counterHandler = EventHandler( test: (BuildContext context, Event event) => event.event == 'increment', handler: (BuildContext context, Event event) => globalDataStorage.updateValue( 'counter', (globalDataStorage.getTypedValue<int>(query: 'counter') ?? 0) + 1, ), ); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return DataStorageProvider( dataStorage: globalDataStorage, child: EventDelegate( handlers: [ counterHandler, ], child: MaterialApp( title: 'Nui App', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const MyHomePage(title: 'Nui Counter'), ), ), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({ required this.title, super.key, }); final String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, title: Text(widget.title), ), body: Center( child: NuiStackWidget( renderers: const [], imageErrorBuilder: null, imageFrameBuilder: null, imageLoadingBuilder: null, binary: null, nodes: null, xmlContent: ''' <center> <column mainAxisSize="min"> <text size="18" align="center"> You have pushed the button\nthis many times: </text> <dataBuilder buildWhen="counter"> <text size="32"> {{ data.counter }} </text> </dataBuilder> </column> </center> <positioned right="16" bottom="16"> <physicalModel elevation="8" shadowColor="FF000000" clip="antiAliasWithSaveLayer"> <prop:borderRadius all="16"/> <material type="button" color="EBDEFF"> <prop:borderRadius all="16"/> <inkWell onPressed="increment"> <prop:borderRadius all="16"/> <tooltip text="Increment"> <sizedBox size="56"> <center> <icon icon="mdi_plus" color="21103E"/> </center> </sizedBox> </tooltip> </inkWell> </material> </physicalModel> </positioned> ''', pageData: {}, ), ), ); } }
আলাদা UI কোড যাতে হাইলাইটিং থাকে:
<center> <column mainAxisSize="min"> <text size="18" align="center"> You have pushed the button\nthis many times: </text> <dataBuilder buildWhen="counter"> <text size="32"> {{ data.counter }} </text> </dataBuilder> </column> </center> <positioned right="16" bottom="16"> <physicalModel elevation="8" shadowColor="black" clip="antiAliasWithSaveLayer"> <prop:borderRadius all="16"/> <material type="button" color="EBDEFF"> <prop:borderRadius all="16"/> <inkWell onPressed="increment"> <prop:borderRadius all="16"/> <tooltip text="Increment"> <sizedBox size="56"> <center> <icon icon="mdi_plus" color="21103E"/> </center> </sizedBox> </tooltip> </inkWell> </material> </physicalModel> </positioned>
এছাড়াও ইন্টারেক্টিভ এবং ব্যাপক ডকুমেন্টেশন রয়েছে যা প্রতিটি উইজেটে কী কী আর্গুমেন্ট এবং বৈশিষ্ট্য রয়েছে, সেইসাথে তাদের সম্ভাব্য সমস্ত মান সম্পর্কে বিস্তারিত তথ্য দেখায়। প্রতিটি বৈশিষ্ট্যের জন্য, যেটিতে আর্গুমেন্ট এবং অন্যান্য বৈশিষ্ট্য উভয়ই থাকতে পারে, সেখানে সমস্ত উপলব্ধ মানগুলির সম্পূর্ণ প্রদর্শন সহ ডকুমেন্টেশনও রয়েছে৷ এটি ছাড়াও, প্রতিটি উপাদানে একটি ইন্টারেক্টিভ উদাহরণ রয়েছে যাতে আপনি এই উইজেটটির বাস্তবায়ন লাইভ দেখতে পারেন এবং আপনার পছন্দ মতো পরিবর্তন করে এটির সাথে খেলতে পারেন।
Nui খুব শক্তভাবে Nanc CMS এ একত্রিত করা হয়েছে। Nui ব্যবহার করার জন্য আপনাকে Nanc ব্যবহার করতে হবে না, কিন্তু Nanc ব্যবহার করা আপনাকে সুবিধা দিতে পারে, যথা - একই ইন্টারেক্টিভ ডকুমেন্টেশন, সেইসাথে প্লেগ্রাউন্ড, যেখানে আপনি রিয়েল-টাইমে লেআউটের ফলাফল দেখতে পারেন, ডেটা নিয়ে খেলতে পারেন যে এটি ব্যবহার করা হবে. তাছাড়া, আপনার নিজস্ব CMS-এর স্থানীয় বিল্ড তৈরি করার প্রয়োজন নেই, আপনি প্রকাশিত ডেমোর সাহায্যে বেশ পরিচালনা করতে পারেন, যেখানে আপনি আপনার প্রয়োজনীয় সবকিছু করতে পারেন।
আপনি লিঙ্কটি অনুসরণ করে এবং তারপর Page Interface / Screen
ক্ষেত্রে ক্লিক করে এটি করতে পারেন। খোলা পর্দা একটি খেলার মাঠ হিসাবে ব্যবহার করা যেতে পারে, এবং সিঙ্ক বোতামে ক্লিক করে, আপনি উৎস সহ একটি ফাইলের মাধ্যমে আপনার IDE এর সাথে Nanc সিঙ্ক্রোনাইজ করতে পারেন, এবং সাহায্য বোতামে ক্লিক করে সমস্ত ডকুমেন্টেশন উপলব্ধ।
PS এই জটিলতাগুলি বিদ্যমান কারণ আমি কখনই Nanc-এর উপাদানগুলির উপর ডকুমেন্টেশন সহ একটি সুস্পষ্ট পৃথক পৃষ্ঠা তৈরি করার সময় পাইনি, সেইসাথে এই পৃষ্ঠায় একটি সরাসরি লিঙ্ক সন্নিবেশ করার অক্ষমতা।
XML থেকে উইজেটগুলিতে একটি সাধারণ ম্যাপার তৈরি করা খুব অর্থহীন হবে৷ এটি অবশ্যই কার্যকর হতে পারে, তবে ব্যবহারের ক্ষেত্রে অনেক কম হবে। একই জিনিস নয় - সম্পূর্ণরূপে ইন্টারেক্টিভ উপাদান এবং স্ক্রিন যেগুলির সাথে আপনি ইন্টারঅ্যাক্ট করতে পারেন, যেগুলি আপনি গ্রানুলারলি আপডেট করতে পারেন (অর্থাৎ, একবারে নয় - তবে এমন অংশগুলিতে যা আপডেট করা দরকার)। এছাড়াও, এই UI ডেটার প্রয়োজন। যা, সার্ভার-চালিত UI বাক্যাংশে S অক্ষরের উপস্থিতি বিবেচনা করে, সার্ভারের লেআউটে সরাসরি প্রতিস্থাপিত করা যেতে পারে, তবে আপনি এটি আরও সুন্দরভাবে করতে পারেন। এবং UI-তে প্রতিটি পরিবর্তনের জন্য ব্যাকএন্ড থেকে লেআউটের একটি নতুন অংশ টেনে আনবেন না (Nui এমন একটি টাইম মেশিন নয় যা jQuery-এর সর্বোত্তম অনুশীলনগুলিকে ফ্লাটারে নিয়ে আসে)।
লজিক দিয়ে শুরু করা যাক: ভেরিয়েবল এবং কম্পিউটেড এক্সপ্রেশন লেআউটে প্রতিস্থাপিত হতে পারে। ধরা যাক একটি উইজেটকে <container color="{{ page.background }}">
হিসাবে সংজ্ঞায়িত করা হয়েছে background
ভেরিয়েবলে সংরক্ষিত "প্যারেন্ট কনটেক্সট" এ পাঠানো ডেটা থেকে সরাসরি এর রঙ বের করবে। এবং <aspectRatio ratio="{{ 3 / 4}}">
তার বংশধরদের জন্য অনুপাতের অনুপাতের মান সেট করবে। বিল্ট-ইন ফাংশন, তুলনা এবং আরও অনেক কিছু রয়েছে যা কিছু যুক্তি দিয়ে UI তৈরি করতে ব্যবহার করা যেতে পারে।
দ্বিতীয় পয়েন্ট টেমপ্লেটিং হয় . আপনি <template id="your_component_name"/>
ট্যাগ ব্যবহার করে সরাসরি UI কোডে আপনার নিজের উইজেটটি সংজ্ঞায়িত করতে পারেন। একই সময়ে, এই টেমপ্লেটের সমস্ত অভ্যন্তরীণ উপাদানগুলির এই টেমপ্লেটে পাস করা আর্গুমেন্টগুলিতে অ্যাক্সেস থাকবে, যা কাস্টম উপাদানগুলির নমনীয় প্যারামিটারাইজেশনের অনুমতি দেবে এবং তারপর <component id="your_component_name"/>
ট্যাগ ব্যবহার করে সেগুলি পুনরায় ব্যবহার করবে৷ টেমপ্লেটের অভ্যন্তরে, আপনি শুধুমাত্র গুণাবলীই নয়, অন্যান্য ট্যাগ/উইজেটগুলিও পাস করতে পারেন, যা যেকোনো জটিলতার পুনর্ব্যবহারযোগ্য উপাদান তৈরি করা সম্ভব করে।
পয়েন্ট তিন - "লুপগুলির জন্য"। নুইতে, একটি বিল্ট-ইন <for>
ট্যাগ রয়েছে যা আপনাকে একই (বা একাধিক) উপাদান একাধিকবার রেন্ডার করতে পুনরাবৃত্তি ব্যবহার করতে দেয়। এটি সুবিধাজনক যখন ডেটার একটি সেট থাকে যা থেকে আপনাকে উইজেটের একটি তালিকা/সারি/কলাম তৈরি করতে হবে।
চতুর্থ - শর্তাধীন রেন্ডারিং। লেআউট স্তরে, <show>
ট্যাগটি প্রয়োগ করা হয় (এটিকে <if>
বলার জন্য একটি ধারণা ছিল), যা আপনাকে নেস্টেড উপাদানগুলি আঁকতে দেয়, বা বিভিন্ন পরিস্থিতিতে সেগুলিকে গাছের মধ্যে এম্বেড করতে দেয় না।
পয়েন্ট পাঁচ - কর্ম। কিছু উপাদান যা ব্যবহারকারী ইন্টারঅ্যাক্ট করতে পারে ইভেন্ট পাঠাতে পারে । যা আপনি আপনার পছন্দ মতো সম্পূর্ণ নিয়ন্ত্রণ করতে পারেন। ধরা যাক, <inkWell onPressed="something">
- এই ধরনের ঘোষণার সাথে, এই উইজেটটি ক্লিকযোগ্য হয়ে ওঠে, এবং আপনার অ্যাপ্লিকেশন, বা বরং, কিছু EventHandler
, এই ইভেন্টটি পরিচালনা করতে এবং কিছু করতে সক্ষম হবে৷ ধারণাটি হ'ল যুক্তি সম্পর্কিত সমস্ত কিছু সরাসরি প্রয়োগে প্রয়োগ করা উচিত, তবে আপনি যে কোনও কিছু বাস্তবায়ন করতে পারেন। কিছু জেনেরিক হ্যান্ডলার তৈরি করুন যেগুলি অ্যাকশনের গ্রুপগুলি পরিচালনা করতে পারে, যেমন "স্ক্রিনে যান" / "কল পদ্ধতি" / "বিশ্লেষণ ইভেন্ট পাঠান"। পাশাপাশি ডাইনামিক কোড বাস্তবায়নের পরিকল্পনা রয়েছে, তবে এখানে সূক্ষ্মতা রয়েছে। ডার্টের জন্য, নির্বিচারে কোড চালানোর উপায় রয়েছে, তবে এটি কার্যকারিতাকে প্রভাবিত করে এবং এছাড়াও, অ্যাপ্লিকেশন কোডের সাথে এই কোডটির আন্তঃকার্যযোগ্যতা কমই 100%। অর্থাৎ, এই গতিশীল কোডে যুক্তি তৈরি করে, আপনি ক্রমাগত কিছু সীমাবদ্ধতার সম্মুখীন হবেন। অতএব, এই প্রক্রিয়াটি সত্যিই প্রযোজ্য এবং দরকারী হওয়ার জন্য খুব সাবধানে কাজ করা দরকার।
ষষ্ঠ পয়েন্ট হল স্থানীয় UI আপডেট। এটা সম্ভব হয়েছে <dataBuilder>
ট্যাগের জন্য ধন্যবাদ। এই ট্যাগ (হুডের নীচে ব্লক) একটি নির্দিষ্ট ক্ষেত্রের দিকে "দেখতে" পারে এবং যখন এটি পরিবর্তিত হয়, তখন এটি তার সাবট্রিকে পুনরায় আঁকবে৷
প্রাথমিকভাবে, আমি ডেটার জন্য দুটি স্টোরের পথ অনুসরণ করেছি - উপরে উল্লিখিত "অভিভাবক প্রসঙ্গ"। সেইসাথে "ডেটা" - ডেটা যা সরাসরি UI-তে সংজ্ঞায়িত করা যেতে পারে, <data>
ট্যাগ ব্যবহার করে। সত্যি কথা বলতে, UI-তে ডেটা সংরক্ষণ এবং স্থানান্তর করার দুটি উপায় বাস্তবায়ন করার কেন প্রয়োজন ছিল তা আমি এখন যুক্তি মনে করতে পারছি না, তবে আমি এই ধরনের সিদ্ধান্তের জন্য নিজেকে কঠোরভাবে সমালোচনা করতে পারি না।
তারা নিম্নরূপ কাজ করে - "অভিভাবক প্রসঙ্গ" হল Map<String, dynamic>
টাইপের একটি বস্তু, যা সরাসরি NuiListWidget
/ NuiStackWidget
উইজেটগুলিতে পাঠানো হয়। উপসর্গ page
দ্বারা এই ডেটাতে অ্যাক্সেস সম্ভব:
<someWidget value="{{ page.your.field }}"/>
আপনি অ্যারে সহ যেকোনও গভীরতা- {{ page.some.array.0.users.35.age }}
উল্লেখ করতে পারেন। যদি এমন কোন কী/মান না থাকে, তাহলে আপনি null
পাবেন। <for>
ব্যবহার করে তালিকাগুলি পুনরাবৃত্তি করা যেতে পারে।
দ্বিতীয় উপায় - "ডেটা" একটি বিশ্বব্যাপী ডেটা স্টোর। অনুশীলনে, এটি একটি নির্দিষ্ট Bloc
যা গাছে NuiListWidget
/ NuiStackWidget
এর চেয়ে উঁচুতে অবস্থিত। একই সময়ে, কোনো কিছুই স্থানীয় শৈলীতে তাদের ব্যবহার সংগঠিত করতে বাধা দেয় না, DataStorageProvider
এর মাধ্যমে আপনার DataStorage
এর নিজস্ব উদাহরণ পাস করে।
একই সময়ে, প্রথম পদ্ধতিটি প্রতিক্রিয়াশীল নয় - অর্থাৎ, যখন page
ডেটা পরিবর্তিত হয়, তখন কোনও UI নিজেকে আপডেট করবে না। যেহেতু এটি আসলে, আপনার StatelessWidget
আর্গুমেন্ট। যদি page
জন্য ডেটা উৎস হয়, বলুন, আপনার নিজস্ব ব্লক, যা Nui...Widget
কে মানগুলির একটি সেট দেবে - তাহলে, একটি নিয়মিত StatelessWidget
এর মতো, এটি সম্পূর্ণরূপে নতুন ডেটা দিয়ে পুনরায় আঁকা হবে।
ডেটা নিয়ে কাজ করার দ্বিতীয় উপায় হল প্রতিক্রিয়াশীল। আপনি যদি DataStorage
এ ডেটা পরিবর্তন করেন, এই ক্লাসের API ব্যবহার করে - updateValue
পদ্ধতি, তাহলে এটি ব্লক ক্লাসের emit
পদ্ধতিকে কল করবে এবং যদি আপনার UI - <dataBuilder>
ট্যাগে এই ডেটার সক্রিয় শ্রোতা থাকে, তাহলে তাদের বিষয়বস্তু সেই অনুযায়ী পরিবর্তন করা হবে, কিন্তু বাকি UI স্পর্শ করা হবে না।
এইভাবে, আমরা দুটি সম্ভাব্য ডেটা উত্স পাই - একটি খুব সাধারণ page
এবং একটি প্রতিক্রিয়াশীল data
৷ এই উত্সগুলিতে ডেটা আপডেট করার যুক্তি এবং এই আপডেটগুলিতে UI এর প্রতিক্রিয়া ব্যতীত, তাদের মধ্যে কোনও পার্থক্য নেই।
আমি ইচ্ছাকৃতভাবে কাজের সমস্ত সূক্ষ্মতা এবং দিকগুলি বর্ণনা করিনি, যেহেতু এটি ইতিমধ্যে বিদ্যমান ডকুমেন্টেশনের একটি অনুলিপি হিসাবে পরিণত হবে। অতএব, আপনি যদি চেষ্টা করতে বা আরও শিখতে আগ্রহী হন - অনুগ্রহ করে এখানে স্বাগতম। যদি কাজের কোনো দিক পরিষ্কার না হয় বা ডকুমেন্টেশন কিছু কভার না করে, তাহলে সমস্যাটি নির্দেশ করে আপনার বার্তা দ্বারা আমি খুশি হব:
আমি সংক্ষেপে কিছু বৈশিষ্ট্যের তালিকা করব যা এই নিবন্ধে কভার করা হয়নি, কিন্তু আপনার জন্য উপলব্ধ:
তাদের জন্য ঠিক একই ইন্টারেক্টিভ ডকুমেন্টেশন তৈরি করার ক্ষমতা সহ আপনার নিজস্ব ট্যাগ/কম্পোনেন্ট তৈরি করা, লাইভ প্রিভিউ সহ তাদের আর্গুমেন্ট এবং বৈশিষ্ট্যগুলির মতো। এইভাবে, উদাহরণস্বরূপ, SVG ইমেজ রেন্ডার করার জন্য উপাদান প্রয়োগ করা হয়। এটিকে ইঞ্জিনের মূলে ঠেলে দেওয়ার কোনও মানে নেই, কারণ প্রত্যেকেরই এটির প্রয়োজন হয় না, তবে একটি এক্সটেনশন হিসাবে শুধুমাত্র একটি পরিবর্তনশীল পাস করে ব্যবহারের জন্য উপলব্ধ - সহজ এবং সহজ৷ সরাসরি -বাস্তবায়নের একটি উদাহরণ ।
আইকনগুলির একটি বিশাল অন্তর্নির্মিত লাইব্রেরি যা আপনার নিজের যোগ করে প্রসারিত করা যেতে পারে (এখানে আমি অসামঞ্জস্যপূর্ণ বলে প্রমাণিত হয়েছি, এবং "ঝাঁকিয়েছি", যুক্তিটি ছিল যতটা সম্ভব আইকনগুলি অবিলম্বে ব্যবহারের জন্য উপলব্ধ করা এবং এর প্রয়োজন ছিল না। নতুন আইকন ব্যবহার করতে অ্যাপ্লিকেশন আপডেট করুন)। বাক্সের বাইরে উপলব্ধ: fluentui_system_icons , material_design_icons_flutter এবং remixicon । আপনি Nanc , Page Interface / Screen -> Icons
ব্যবহার করে সমস্ত উপলব্ধ আইকন দেখতে পারেন
বাক্সের বাইরে গুগল ফন্ট সহ কাস্টম ফন্ট
XML কে JSON/protobuf-এ রূপান্তর করা এবং UI এর জন্য "উৎস" হিসাবে ব্যবহার করা
এই সমস্ত এবং আরও অনেক কিছু ডকুমেন্টেশনে অধ্যয়ন করা যেতে পারে।
মূল জিনিসটি হ'ল যুক্তির সাথে গতিশীলভাবে কোড চালানোর সম্ভাবনা খুঁজে বের করা। এটি একটি খুব দুর্দান্ত বৈশিষ্ট্য যা আপনাকে নুইয়ের ক্ষমতাগুলিকে খুব গুরুত্ব সহকারে প্রসারিত করতে দেয়। এছাড়াও, আপনি স্ট্যান্ডার্ড ফ্লাটার লাইব্রেরি থেকে বাকী খুব কমই ব্যবহৃত, কিন্তু কখনও কখনও খুব গুরুত্বপূর্ণ উইজেট যোগ করতে পারেন (এবং উচিত)। এক্সএসডিকে আয়ত্ত করতে, যাতে সমস্ত ট্যাগের স্বয়ংক্রিয়-সম্পূর্ণতা IDE-তে উপস্থিত হয় (ট্যাগ ডকুমেন্টেশন থেকে সরাসরি এই স্কিমটি তৈরি করার একটি ধারণা রয়েছে, তারপর এটি কাস্টম উইজেটের জন্য তৈরি করা সহজ হবে এবং এটি সর্বদা আপ-টু থাকবে -তারিখ, এবং ডার্টে একটি জেনারেটেড ডিএসএল তৈরি করার একটি ধারণাও রয়েছে, যা পরে XML/Json/Protobuf-এ রূপান্তরিত হতে পারে)। ঠিক আছে, এবং অতিরিক্ত পারফরম্যান্স অপ্টিমাইজেশান - এটি এখন খারাপ নয়, খুব খারাপ নয়, তবে এটি আরও ভাল হতে পারে, এমনকি নেটিভ ফ্লটারের কাছাকাছি।
আমার কাছে এতটুকুই। পরের প্রবন্ধে, আমি Nui-এর পারফরম্যান্স সম্পর্কে বিশদভাবে বলব, কিভাবে আমি টেস্ট কেস তৈরি করেছি, কত ডজন রেক এই প্রক্রিয়ার মধ্য দিয়ে হেঁটেছি এবং কোন পরিস্থিতিতে কোন সংখ্যা পাওয়া যেতে পারে।
আপনি যদি Nui চেষ্টা করতে বা এটি আরও ভালভাবে জানতে আগ্রহী হন - অনুগ্রহ করে ডকুমেন্টেশন ডেস্কে যান। এছাড়াও, যদি এটি কঠিন না হয়, তাহলে অনুগ্রহ করে GitHub- এ একটি তারকা এবং pub.dev- এ একটি লাইক দিন - এটি আপনার পক্ষে কঠিন নয়, তবে আমার জন্য, এই বিশাল নৌকায় একাকী রোয়ার - এটি অবিশ্বাস্যভাবে দরকারী।