একটি মিডিয়া স্ক্রোলার উপাদান তৈরি করা

টিভি, ফোন, ডেস্কটপ ইত্যাদির জন্য কীভাবে একটি প্রতিক্রিয়াশীল অনুভূমিক স্ক্রলভিউ তৈরি করা যায় তার একটি ভিত্তিগত ওভারভিউ।

এই পোস্টে আমি ওয়েবের জন্য অনুভূমিক স্ক্রোলিং অভিজ্ঞতা তৈরি করার উপায় সম্পর্কে চিন্তাভাবনা শেয়ার করতে চাই যা ন্যূনতম, প্রতিক্রিয়াশীল, অ্যাক্সেসযোগ্য এবং ব্রাউজার এবং প্ল্যাটফর্ম জুড়ে কাজ করে (যেমন টিভি!)। ডেমো চেষ্টা করুন.

ডেমো

আপনি যদি ভিডিও পছন্দ করেন তবে এখানে এই পোস্টটির একটি YouTube সংস্করণ রয়েছে:

ওভারভিউ

আমরা মিডিয়া বা পণ্যের থাম্বনেল হোস্ট করার জন্য একটি অনুভূমিক স্ক্রোল বিন্যাস তৈরি করব। উপাদানটি একটি নম্র <ul> তালিকা হিসাবে শুরু হয় কিন্তু CSS এর সাথে একটি সন্তোষজনক এবং মসৃণ স্ক্রোল অভিজ্ঞতায় রূপান্তরিত হয়, চিত্রগুলি প্রদর্শন করে এবং একটি গ্রিডে স্ন্যাপ করে। জাভাস্ক্রিপ্ট রোভিং-ইনডেক্স ইন্টারঅ্যাকশনের সুবিধার্থে যোগ করা হয়েছে, কীবোর্ড ব্যবহারকারীদের 100+ আইটেম অতিক্রম করা এড়িয়ে যেতে সাহায্য করে। এছাড়াও একটি পরীক্ষামূলক মিডিয়া ক্যোয়ারী, prefers-reduced-data , মিডিয়া স্ক্রলারটিকে একটি হালকা শিরোনাম স্ক্রলার অভিজ্ঞতায় পরিণত করতে ব্যবহৃত হয়৷

অ্যাক্সেসযোগ্য মার্কআপ দিয়ে শুরু করুন

একটি মিডিয়া স্ক্রোলার মাত্র কয়েকটি মূল উপাদান, আইটেম সহ একটি তালিকা দিয়ে তৈরি। একটি তালিকা, তার সহজতম আকারে, সারা বিশ্বে ভ্রমণ করতে পারে এবং স্পষ্টভাবে সকলের দ্বারা গ্রাস করা যেতে পারে। এই পৃষ্ঠায় অবতরণকারী একজন ব্যবহারকারী একটি তালিকা ব্রাউজ করতে পারেন এবং একটি আইটেম দেখতে একটি লিঙ্কে ক্লিক করতে পারেন৷ এটি আমাদের অ্যাক্সেসযোগ্য ভিত্তি।

একটি <ul> উপাদান সহ একটি তালিকা প্রদান করুন:

<ul class="horizontal-media-scroller">
  <li></li>
  <li></li>
  <li></li>
  ...
<ul>

একটি <a> উপাদানের সাথে তালিকা আইটেমগুলিকে ইন্টারেক্টিভ করুন:

<li>
  <a href="#">
    ...
  </a>
</li>

একটি ছবি এবং তার ক্যাপশনকে অর্থগতভাবে উপস্থাপন করতে একটি <figure> উপাদান ব্যবহার করুন:

<figure>
  <picture>
    <img alt="..." loading="lazy" src="https://picsum.photos/500/500?1">
  </picture>
  <figcaption>Legends</figcaption>
</figure>

<img>alt এবং loading বৈশিষ্ট্যগুলি লক্ষ্য করুন। একটি মিডিয়া স্ক্রোলারের জন্য Alt পাঠ্য হল থাম্বনেইল অতিরিক্ত প্রসঙ্গ আনতে সাহায্য করার জন্য একটি UX সুযোগ , বা চিত্রটি লোড না হলে ফলব্যাক পাঠ্য হিসাবে, বা এটি একটি স্ক্রিন রিডারের মতো সহায়ক প্রযুক্তির উপর নির্ভরশীল ব্যবহারকারীদের জন্য একটি কথ্য UI প্রদান করে৷ কমপ্লায়েন্ট অল্ট টেক্সটের জন্য পাঁচটি সুবর্ণ নিয়মের সাথে আরও জানুন।

loading অ্যাট্রিবিউটটি এই ইমেজ সোর্সটিকে সংকেত দেওয়ার উপায় হিসাবে lazy কীওয়ার্ডটিকে গ্রহণ করে শুধুমাত্র যখন ইমেজটি ভিউপোর্টের মধ্যে থাকে তখনই আনা উচিত৷ এটি বৃহৎ তালিকার জন্য সত্যিই চমৎকার হতে পারে, কারণ ব্যবহারকারীরা শুধুমাত্র তাদের স্ক্রোল করা আইটেমগুলির জন্য ছবি ডাউনলোড করবে।

ব্যবহারকারীর রঙ স্কিম পছন্দ সমর্থন করুন

ব্রাউজারে সংকেত দিতে একটি <meta> ট্যাগ হিসাবে color-scheme ব্যবহার করুন যে আপনার পৃষ্ঠা হালকা এবং অন্ধকার উভয়ই ব্যবহারকারী-এজেন্ট স্টাইল চায়। এটি একটি বিনামূল্যের অন্ধকার মোড বা হালকা মোড, আপনি এটিকে কীভাবে দেখছেন তার উপর নির্ভর করে:

<meta name="color-scheme" content="dark light">

মেটা ট্যাগটি সম্ভাব্য প্রথম দিকের সংকেত প্রদান করে, যাতে ব্যবহারকারীর গাঢ় থিম পছন্দ থাকলে ব্রাউজারটি একটি গাঢ় ডিফল্ট ক্যানভাস রঙ নির্বাচন করতে পারে। এর মানে হল যে সাইটের পৃষ্ঠাগুলির মধ্যে নেভিগেশন লোডের মধ্যে একটি সাদা ক্যানভাস ব্যাকগ্রাউন্ড ফ্ল্যাশ করবে না। লোডের মধ্যে বিজোড় অন্ধকার থিম, চোখের উপর অনেক সুন্দর।

টমাস স্টেইনার থেকে https://web.dev/color-scheme/- এ আরও অনেক কিছু জানুন।

বিষয়বস্তু যোগ করুন

ul > li > a > figure > picture > img এর উপরের বিষয়বস্তুর কাঠামোর প্রেক্ষিতে, পরবর্তী কাজটি হল স্ক্রোল করার জন্য ছবি এবং শিরোনাম যোগ করা। আমি স্ট্যাটিক প্লেসহোল্ডার ইমেজ এবং টেক্সট সহ ডেমো প্যাক করেছি, কিন্তু আপনার প্রিয় ডেটা উৎস থেকে এটি পাওয়ার জন্য নির্দ্বিধায়।

CSS এর সাথে স্টাইল যোগ করুন

এখন সময় এসেছে CSS-এর এই জেনেরিক বিষয়বস্তুর তালিকা নেওয়ার এবং এটিকে একটি অভিজ্ঞতায় পরিণত করার। নেটফ্লিক্স, অ্যাপ স্টোর এবং আরও অনেক সাইট এবং অ্যাপ বিভাগ এবং বিকল্পগুলির সাথে ভিউপোর্ট প্যাক করতে অনুভূমিক স্ক্রোলিং এলাকা ব্যবহার করে।

স্ক্রলার লেআউট তৈরি করা হচ্ছে

লেআউটে বিষয়বস্তু কেটে ফেলা বা উপবৃত্তের সাহায্যে টেক্সট ট্রাঙ্কেশনের দিকে ঝুঁকে পড়া এড়ানো গুরুত্বপূর্ণ। অনেক টেলিভিশন সেটে এইরকম মিডিয়া স্ক্রোলার থাকে, তবে প্রায়শই উপবৃত্তাকার বিষয়বস্তু অবলম্বন করে। এই লেআউট না! এটি মিডিয়া বিষয়বস্তুকে কলামের আকারকে ওভাররাইড করতে দেয়, 1 লেআউটকে অনেক আকর্ষণীয় সমন্বয় পরিচালনা করার জন্য যথেষ্ট নমনীয় করে তোলে।

2 স্ক্রলিং সারি দেখানো হয়েছে। একটির কোন উপবৃত্তাকার নেই, যার অর্থ এটি লম্বা এবং প্রতিটি শিরোনাম সম্পূর্ণরূপে পাঠযোগ্য। অন্যটি ছোট এবং অনেক শিরোনাম দিয়ে কাটঅফ করা হয়েছে উপবৃত্তাকার

ধারকটি একটি কাস্টম সম্পত্তি হিসাবে ডিফল্ট আকার প্রদান করে কলামের আকারকে ওভাররাইড করার অনুমতি দেয়৷ এই গ্রিড লেআউটটি কলামের আকার সম্পর্কে মতামতযুক্ত, এটি শুধুমাত্র ব্যবধান এবং দিক পরিচালনা করছে:

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2); /* parent owned value for children to be relative to*/
  margin: 0;
}

কাস্টম সম্পত্তি তারপর <picture> উপাদান দ্বারা আমাদের বেস অনুপাত তৈরি করতে ব্যবহার করা হয়: একটি বাক্স:

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  & picture {
    inline-size: var(--size);
    block-size: var(--size);
  }
}

শুধুমাত্র আরও কয়েকটি ছোট শৈলীর সাহায্যে, মিডিয়া স্ক্রোলারের বেয়ারবোনগুলি সম্পূর্ণ করুন:

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  overflow-x: auto;
  overscroll-behavior-inline: contain;

  & > li {
    display: inline-block; /* removes the list-item bullet */
  }

  & picture {
    inline-size: var(--size);
    block-size: var(--size);
  }
}

overflow সেট করা <ul> কে তার তালিকার মাধ্যমে স্ক্রোলিং এবং কীবোর্ড নেভিগেশনের অনুমতি দেওয়ার জন্য সেট করে, তারপর প্রতিটি ডাইরেক্ট চাইল্ড <li> উপাদানটি একটি নতুন ডিসপ্লে ধরনের inline-block পেয়ে তার ::marker সরিয়ে দেয়।

যদিও ইমেজ এখনও প্রতিক্রিয়াশীল নয়, এবং তারা ভিতরে আছেন বাক্সের বাইরে ডান বিস্ফোরিত. কিছু আকার, ফিট এবং বর্ডার স্টাইল এবং যখন তারা অলসভাবে লোড হয় তার জন্য একটি ব্যাকগ্রাউন্ড গ্রেডিয়েন্ট দিয়ে তাদের নিয়ন্ত্রণ করুন:

img {
  /* smash into whatever box it's in */
  inline-size: 100%;
  block-size: 100%;

  /* don't squish but do cover the space */
  object-fit: cover;

  /* soften the edges */
  border-radius: 1ex;
  overflow: hidden;

  /* if empty, show a gradient placeholder */
  background-image:
    linear-gradient(
      to bottom,
      hsl(0 0% 40%),
      hsl(0 0% 20%)
    );
}

স্ক্রোল প্যাডিং

পৃষ্ঠার বিষয়বস্তুর সাথে সারিবদ্ধকরণ, প্লাস একটি প্রান্ত থেকে প্রান্ত স্ক্রোলিং পৃষ্ঠ এলাকা, একটি সুরেলা এবং ন্যূনতম উপাদানের জন্য গুরুত্বপূর্ণ।

এজ-টু-এজ স্ক্রোল লেআউটটি সম্পন্ন করতে যা আমাদের টাইপোগ্রাফি এবং লেআউট লাইনের সাথে সারিবদ্ধ, scroll-padding সাথে মেলে এমন padding ব্যবহার করুন:

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  overflow-x: auto;
  overscroll-behavior-inline: contain;

  padding-inline: var(--gap);
  scroll-padding-inline: var(--gap);
  padding-block: calc(var(--gap) / 2); /* make space for scrollbar and focus outline */
}

অনুভূমিক স্ক্রোল প্যাডিং বাগ ফিক্স উপরেরটি দেখায় যে একটি স্ক্রোল কন্টেইনার প্যাড করা কতটা সহজ হওয়া উচিত, তবে এটির সাথে অসামান্য সামঞ্জস্যপূর্ণ সমস্যা রয়েছে (যদিও Chromium 91+ এ সংশোধন করা হয়েছে!) ইতিহাসের একটি বিট জন্য এখানে দেখুন, কিন্তু সংক্ষিপ্ত সংস্করণ হল যে প্যাডিং সবসময় একটি স্ক্রোল দৃশ্যের জন্য হিসাব করা হয় না।

ক বাক্সটি শেষ তালিকা আইটেমের ইনলাইন-এন্ড সাইডে হাইলাইট করা হয়েছে, দেখানো হচ্ছে পছন্দসই প্রান্তিককরণ তৈরি করতে প্যাডিং এবং উপাদানের প্রস্থ সমান।

স্ক্রলারের শেষে প্যাডিং লাগানোর জন্য ব্রাউজারদের চালাতে আমি প্রতিটি তালিকার শেষ চিত্রটি লক্ষ্য করব এবং একটি ছদ্ম উপাদান যুক্ত করব যা পছন্দসই প্যাডিংয়ের পরিমাণ।

.horizontal-media-scroller > li:last-of-type figure {
  position: relative;

  &::after {
    content: "";
    position: absolute;

    inline-size: var(--gap);
    block-size: 100%;

    inset-block-start: 0;
    inset-inline-end: calc(var(--gap) * -1);
  }
}

যৌক্তিক বৈশিষ্ট্য ব্যবহার করে মিডিয়া স্ক্রোলারকে যেকোনো লেখার মোড এবং নথির দিকনির্দেশনায় কাজ করতে সক্ষম করে।

স্ক্রল স্ন্যাপিং

ওভারফ্লো সহ একটি স্ক্রলিং কন্টেনার CSS-এর একটি লাইনের সাথে একটি স্ন্যাপিং ভিউপোর্ট হয়ে উঠতে পারে, তারপরে বাচ্চাদের উপর থাকে যে তারা কীভাবে সেই ভিউপোর্টের সাথে সারিবদ্ধ করতে চায় তা নির্দিষ্ট করা।

.horizontal-media-scroller {
  --size: 150px;

  display: grid;
  grid-auto-flow: column;
  gap: calc(var(--gap) / 2);
  margin: 0;

  overflow-x: auto;
  overscroll-behavior-inline: contain;

  padding-inline: var(--gap);
  scroll-padding-inline: var(--gap);
  padding-block-end: calc(var(--gap) / 2);

  scroll-snap-type: inline mandatory;

  & figure {
    scroll-snap-align: start;
  }
}

ফোকাস

এই উপাদানটির জন্য অনুপ্রেরণা আসে টিভি, অ্যাপ স্টোর এবং আরও অনেক কিছুতে এর ব্যাপক জনপ্রিয়তা থেকে। অনেক ভিডিও গেম প্ল্যাটফর্ম তাদের প্রাথমিক হোম স্ক্রীন লেআউট হিসাবে এটির মতোই একটি মিডিয়া স্ক্রোলার ব্যবহার করে। ফোকাস এখানে একটি বিশাল UX মুহূর্ত, শুধুমাত্র একটি ছোট সংযোজন নয়। আপনার পালঙ্ক থেকে এই মিডিয়া স্ক্রোলারটি একটি রিমোট সহ কল্পনা করুন, সেই মিথস্ক্রিয়াটিকে কিছু ছোট বর্ধন দিন:

.horizontal-media-scroller a {
  outline-offset: 12px;

  &:focus {
    outline-offset: 7px;
  }

  @media (prefers-reduced-motion: no-preference) {
    & {
      transition: outline-offset .25s ease;
    }
  }
}

এটি ফোকাস আউটলাইন শৈলীকে বক্স থেকে 7px দূরে সেট করে, এটিকে কিছু সুন্দর স্থান দেয়। যদি ব্যবহারকারীর গতি হ্রাস করার জন্য কোন গতি পছন্দ না থাকে, তবে অফসেটটি স্থানান্তরিত হয়, ফোকাস ইভেন্টে সূক্ষ্ম গতি প্রদান করে।

রোভিং সূচক

গেমপ্যাড এবং কীবোর্ড ব্যবহারকারীদের স্ক্রোলিং বিষয়বস্তু এবং বিকল্পগুলির এই দীর্ঘ তালিকাগুলিতে বিশেষ মনোযোগ প্রয়োজন। এটি সমাধানের জন্য সাধারণ প্যাটার্নকে রোভিং ইনডেক্স বলা হয়। এটি যখন আইটেমগুলির একটি ধারক কীবোর্ড ফোকাস করা হয় কিন্তু শুধুমাত্র 1 শিশুকে একবারে ফোকাস ধরে রাখার অনুমতি দেওয়া হয়। এই একক ফোকাসযোগ্য আইটেমটি একটি সময়ের অভিজ্ঞতায় এমনভাবে ডিজাইন করা হয়েছে যাতে আইটেমগুলির সম্ভাব্য দীর্ঘ তালিকাকে বাইপাস করার অনুমতি দেওয়া হয়, শেষ পর্যন্ত 50+ বার ট্যাব চাপার বিপরীতে।

ডেমোর সেই প্রথম স্ক্রোলারে 300টি আইটেম আছে। পরবর্তী বিভাগে পৌঁছানোর জন্য তাদের সবাইকে অতিক্রম করার চেয়ে আমরা আরও ভাল করতে পারি।

এই অভিজ্ঞতা তৈরি করতে, জাভাস্ক্রিপ্টকে কীবোর্ড ইভেন্টগুলি পর্যবেক্ষণ করতে হবে এবং ইভেন্টগুলিকে ফোকাস করতে হবে। এই ব্যবহারকারীর অভিজ্ঞতা অর্জন করা সহজ করতে সাহায্য করার জন্য আমি npm-এ একটি ছোট ওপেন সোর্স লাইব্রেরি তৈরি করেছি। 3টি স্ক্রোলারের জন্য এটি কীভাবে ব্যবহার করবেন তা এখানে:

import {rovingIndex} from 'roving-ux';

rovingIndex({
  element: someElement
});

এই ডেমোটি স্ক্রলারদের জন্য নথিটি জিজ্ঞাসা করে এবং তাদের প্রত্যেকের জন্য rovingIndex() ফাংশনকে কল করে। রোভিং অভিজ্ঞতা পেতে rovingIndex() উপাদানটি পাস করুন, যেমন একটি তালিকা ধারক, এবং একটি টার্গেট কোয়েরি নির্বাচক, যদি ফোকাস লক্ষ্যগুলি সরাসরি বংশধর না হয়।

document.querySelectorAll('.horizontal-media-scroller')
  .forEach(scroller =>
    rovingIndex({
      element: scroller,
      target: 'a',
}))

এই প্রভাব সম্পর্কে আরও জানতে, ওপেন সোর্স লাইব্রেরি roving-ux দেখুন।

আকৃতি-অনুপাত

এই পোস্টটি লেখার সময়, aspect-ratio জন্য সমর্থন ফায়ারফক্সে একটি পতাকার পিছনে রয়েছে তবে ক্রোমিয়াম ব্রাউজার বা সেট টপ বক্সগুলিতে উপলব্ধ। যেহেতু মিডিয়া স্ক্রোলার গ্রিড লেআউট শুধুমাত্র দিকনির্দেশ এবং ব্যবধান নির্দিষ্ট করে, তাই সাইজিং মিডিয়া ক্যোয়ারীতে পরিবর্তন হতে পারে যা বৈশিষ্ট্য-অনুপাত সমর্থনের জন্য পরীক্ষা করে। আরও কিছু গতিশীল মিডিয়া স্ক্রোলারে প্রগতিশীল বর্ধন।

ক 4:4 আকৃতির অনুপাত সহ বক্সটি 16:9 ব্যবহৃত অন্যান্য ডিজাইন অনুপাতের পাশে দেখানো হয়েছে এবং 4:3

@supports (aspect-ratio: 1) {
  .horizontal-media-scroller figure > picture {
    inline-size: auto; /* for a block-size driven ratio */
    aspect-ratio: 1; /* boxes by default */

    @nest section:nth-child(2) & {
      aspect-ratio: 16/9;
    }

    @nest section:nth-child(3) & {
      /* double the size of the others */
      block-size: calc(var(--size) * 2);
      aspect-ratio: 4/3;

      /* adjust size to fit more items into the viewport */
      @media (width <= 480px) {
        block-size: calc(var(--size) * 1.5);
      }
    }
  }
}

যদি ব্রাউজারটি aspect-ratio সিনট্যাক্স সমর্থন করে, মিডিয়া স্ক্রোলার ছবিগুলি aspect-ratio আকারে আপগ্রেড করা হয়। ড্রাফ্ট নেস্টিং সিনট্যাক্স ব্যবহার করে, প্রতিটি ছবি প্রথম, দ্বিতীয় বা তৃতীয় সারি কিনা তার উপর নির্ভর করে তার আকৃতির অনুপাত পরিবর্তন করে। নেস্ট সিনট্যাক্স অন্যান্য সাইজিং লজিকের সাথে ঠিক সেখানে কিছু ছোট ভিউপোর্ট অ্যাডজাস্টমেন্ট সেট করার অনুমতি দেয়।

সেই CSS এর সাথে, যেহেতু বৈশিষ্ট্যটি আরও ব্রাউজার ইঞ্জিনে উপলব্ধ, পরিচালনা করা সহজ কিন্তু আরও দৃষ্টিকটু আকর্ষণীয় লেআউট রেন্ডার হবে।

কম ডেটা পছন্দ করে

যদিও এই পরবর্তী কৌশলটি শুধুমাত্র ক্যানারিতে একটি পতাকার পিছনে উপলব্ধ, আমি শেয়ার করতে চেয়েছিলাম কিভাবে আমি CSS-এর কয়েকটি লাইন দিয়ে যথেষ্ট পরিমাণ পৃষ্ঠা লোডের সময় এবং ডেটা ব্যবহার বাঁচাতে পারি। লেভেল 5 থেকে prefers-reduced-data media query জিজ্ঞাসা করার অনুমতি দেয় যে ডিভাইসটি ডেটা সেভার মোডের মতো কোনো হ্রাসকৃত ডেটা অবস্থায় আছে কিনা। যদি এটি হয়, আমি নথি পরিবর্তন করতে পারি, এবং এই ক্ষেত্রে, ছবিগুলি লুকাতে পারি৷

ALT_TEXT_HERE

figure {
  @media (prefers-reduced-data: reduce) {
    & {
      min-inline-size: var(--size);

      & > picture {
        display: none;
      }
    }
  }
}

বিষয়বস্তু এখনও নেভিগেবল কিন্তু ভারী ছবি ডাউনলোড হচ্ছে খরচ ছাড়া. prefers-reduced-data CSS যোগ করার আগে এখানে সাইটটি রয়েছে:

(7 অনুরোধ, 131ms এ 100kb সম্পদ)

ALT_TEXT_HERE

prefers-reduced-data CSS যোগ করার পরে সাইটের পারফরম্যান্স এখানে:

ALT_TEXT_HERE

(71 অনুরোধ, 1.07 সেকেন্ডে 1.2mb সম্পদ)

64টি কম অনুরোধ, যেটি এই ব্রাউজার ট্যাবের ভিউপোর্টের মধ্যে ~60টি ছবি (একটি প্রশস্ত স্ক্রীন ডিসপ্লেতে নেওয়া পরীক্ষা) হবে, একটি পেজ লোড ~80%, এবং 10% ডাটা ওয়্যার দিয়ে। বেশ শক্তিশালী সিএসএস।

উপসংহার

এখন আপনি জানেন যে আমি কীভাবে এটি করেছি, আপনি কীভাবে করবেন?! 🙂

আসুন আমাদের পদ্ধতির বৈচিত্র্য আনুন এবং ওয়েবে তৈরি করার সমস্ত উপায় শিখি। একটি কোডপেন তৈরি করুন বা আপনার নিজের ডেমো হোস্ট করুন, এটি দিয়ে আমাকে টুইট করুন এবং আমি এটিকে নীচের কমিউনিটি রিমিক্স বিভাগে যোগ করব৷

উৎস

কমিউনিটি রিমিক্স

এখানে এখনো দেখার কিছু নেই!