কার্ড নেভিগেশন

বেশিরভাগ কার্ড-ভিত্তিক অ্যাড-অন একাধিক কার্ড ব্যবহার করে তৈরি করা হয় যা অ্যাড-অন ইন্টারফেসের বিভিন্ন 'পৃষ্ঠা' উপস্থাপন করে। একটি কার্যকর ব্যবহারকারীর অভিজ্ঞতা পেতে, আপনার অ্যাড-অনে কার্ডগুলির মধ্যে সহজ এবং স্বাভাবিক নেভিগেশন ব্যবহার করা উচিত।

মূলত Gmail অ্যাড-অনগুলিতে, UI-এর বিভিন্ন কার্ডের মধ্যে রূপান্তরগুলি জিমেইল দ্বারা প্রদর্শিত স্ট্যাকের উপরের কার্ড সহ একটি একক কার্ড স্ট্যাকে এবং থেকে কার্ডগুলিকে পুশ এবং পপ করার মাধ্যমে পরিচালিত হয়।

হোমপেজ কার্ড নেভিগেশন

Google Workspace অ্যাড-অন হোমপেজ এবং অ-প্রসঙ্গিক কার্ডের সাথে পরিচয় করিয়ে দেয়। প্রাসঙ্গিক এবং অ-প্রসঙ্গিক কার্ডগুলিকে মিটমাট করার জন্য, Google Workspace অ্যাড-অনগুলিতে প্রতিটির জন্য একটি অভ্যন্তরীণ কার্ড স্ট্যাক রয়েছে। যখন একটি হোস্টে একটি অ্যাড-অন খোলা হয়, তখন সংশ্লিষ্ট homepageTrigger স্ট্যাকের প্রথম হোমপেজ কার্ড তৈরি করতে ফায়ার করে (নীচের চিত্রে গাঢ় নীল "হোমপেজ" কার্ড)। যদি একটি homepageTrigger সংজ্ঞায়িত না করা হয়, একটি ডিফল্ট কার্ড তৈরি করা হয়, প্রদর্শিত হয় এবং নন-প্রসঙ্গগত স্ট্যাকের দিকে ঠেলে দেওয়া হয়। এই প্রথম কার্ডটি একটি রুট কার্ড।

আপনার অ্যাড-অন অতিরিক্ত অ-প্রসঙ্গিক কার্ড তৈরি করতে পারে এবং ব্যবহারকারী আপনার অ্যাড-অনের মাধ্যমে নেভিগেট করার সাথে সাথে তাদের স্ট্যাকের (ডায়াগ্রামে নীল "পুশড কার্ড") এ পুশ করতে পারে। অ্যাড-অন UI স্ট্যাকের উপরের কার্ডটি প্রদর্শন করে, তাই স্ট্যাকে নতুন কার্ড পুশ করলে ডিসপ্লে পরিবর্তন হয় এবং স্ট্যাকের থেকে পপিং কার্ডগুলি পূর্ববর্তী কার্ডগুলিতে প্রদর্শন ফিরিয়ে দেয়।

যদি আপনার অ্যাড-অনে একটি সংজ্ঞায়িত প্রাসঙ্গিক ট্রিগার থাকে, যখন ব্যবহারকারী সেই প্রসঙ্গে প্রবেশ করে তখন ট্রিগারটি ফায়ার হয়। ট্রিগার ফাংশন প্রাসঙ্গিক কার্ড তৈরি করে, কিন্তু নতুন কার্ডের DisplayStyle উপর ভিত্তি করে UI ডিসপ্লে আপডেট করা হয়:

  • যদি DisplayStyle REPLACE হয় (ডিফল্ট), প্রাসঙ্গিক কার্ড (ডায়াগ্রামে গাঢ় কমলা "প্রসঙ্গগত" কার্ড) বর্তমানে প্রদর্শিত কার্ড প্রতিস্থাপন করে। এটি কার্যকরভাবে অ-প্রসঙ্গিক কার্ড স্ট্যাকের উপরে একটি নতুন প্রাসঙ্গিক কার্ড স্ট্যাক শুরু করে এবং এই প্রাসঙ্গিক কার্ডটি প্রাসঙ্গিক স্ট্যাকের মূল কার্ড।
  • যদি DisplayStyle PEEK হয়, UI পরিবর্তে একটি উঁকি দেওয়া হেডার তৈরি করে যা অ্যাড-অন সাইডবারের নীচে প্রদর্শিত হয়, বর্তমান কার্ডকে ওভারলে করে। পিক শিরোনামটি নতুন কার্ডের শিরোনাম দেখায় এবং ব্যবহারকারীর বোতাম নিয়ন্ত্রণগুলি প্রদান করে যা তাদের সিদ্ধান্ত নিতে দেয় যে নতুন কার্ডটি দেখতে হবে কি না। যদি তারা ভিউ বোতামে ক্লিক করে, কার্ডটি বর্তমান কার্ডটি প্রতিস্থাপন করে (যেমন উপরে REPLACE এর সাথে বর্ণিত হয়েছে)।

আপনি অতিরিক্ত প্রাসঙ্গিক কার্ড তৈরি করতে পারেন এবং সেগুলিকে স্ট্যাকের উপর ঠেলে দিতে পারেন (চিত্রে হলুদ "পুশড কার্ড")। কার্ড স্ট্যাক আপডেট করা অ্যাড-অন UI পরিবর্তন করে শীর্ষ-সবচেয়ে কার্ড প্রদর্শন করতে। ব্যবহারকারী একটি প্রসঙ্গ ছেড়ে দিলে, স্ট্যাকের প্রাসঙ্গিক কার্ডগুলি সরানো হয় এবং প্রদর্শনটি শীর্ষ-সবচেয়ে অ-প্রসঙ্গিক কার্ড বা হোমপেজে আপডেট হয়।

ব্যবহারকারী যদি এমন একটি প্রসঙ্গ প্রবেশ করে যার জন্য আপনার অ্যাড-অন একটি প্রাসঙ্গিক ট্রিগার সংজ্ঞায়িত করে না, কোন নতুন কার্ড তৈরি করা হয় না এবং বর্তমান কার্ডটি প্রদর্শিত থাকে।

নীচে বর্ণিত Navigation ক্রিয়াগুলি শুধুমাত্র একই প্রসঙ্গের কার্ডগুলিতে কাজ করে; উদাহরণস্বরূপ, একটি প্রাসঙ্গিক কার্ডের মধ্যে থেকে popToRoot() শুধুমাত্র অন্যান্য প্রাসঙ্গিক কার্ডগুলিকে পপ করে, এবং হোমপেজ কার্ডগুলিকে প্রভাবিত করবে না।

বিপরীতে, বোতামটি সর্বদা ব্যবহারকারীর জন্য আপনার প্রাসঙ্গিক কার্ড থেকে আপনার অ-প্রসঙ্গিক কার্ডগুলিতে নেভিগেট করার জন্য উপলব্ধ।

আপনি কার্ডের স্ট্যাকগুলি থেকে কার্ডগুলি যোগ করে বা সরিয়ে দিয়ে কার্ডগুলির মধ্যে রূপান্তর তৈরি করতে পারেন৷ Navigation ক্লাস স্ট্যাক থেকে কার্ড পুশ এবং পপ করার ফাংশন প্রদান করে। কার্যকর কার্ড নেভিগেশন তৈরি করতে, আপনি নেভিগেশন অ্যাকশন ব্যবহার করার জন্য আপনার উইজেটগুলি কনফিগার করেন। আপনি একই সাথে একাধিক কার্ড পুশ বা পপ করতে পারেন, কিন্তু অ্যাড-অন শুরু হলে স্ট্যাকের উপর প্রথমে পুশ করা প্রাথমিক হোমপেজ কার্ডটি আপনি সরাতে পারবেন না।

একটি উইজেটের সাথে ব্যবহারকারীর ইন্টারঅ্যাকশনের প্রতিক্রিয়া হিসাবে একটি নতুন কার্ডে নেভিগেট করতে, এই পদক্ষেপগুলি অনুসরণ করুন:

  1. একটি Action অবজেক্ট তৈরি করুন এবং এটিকে আপনার সংজ্ঞায়িত একটি কলব্যাক ফাংশনের সাথে সংযুক্ত করুন।
  2. সেই উইজেটে Action সেট করতে উইজেটের উপযুক্ত উইজেট হ্যান্ডলার ফাংশনকে কল করুন।
  3. কলব্যাক ফাংশনটি প্রয়োগ করুন যা নেভিগেশন পরিচালনা করে। এই ফাংশনটিকে আর্গুমেন্ট হিসাবে একটি অ্যাকশন ইভেন্ট অবজেক্ট দেওয়া হয়েছে এবং নিম্নলিখিতগুলি করতে হবে:
    1. কার্ড পরিবর্তন সংজ্ঞায়িত করতে একটি Navigation অবজেক্ট তৈরি করুন। একটি একক Navigation অবজেক্টে একাধিক নেভিগেশন ধাপ থাকতে পারে, যেগুলি সেগুলি বস্তুতে যোগ করার ক্রমে পরিচালিত হয়।
    2. ActionResponseBuilder ক্লাস এবং Navigation অবজেক্ট ব্যবহার করে একটি ActionResponse অবজেক্ট তৈরি করুন।
    3. নির্মিত ActionResponse ফেরত দিন।

ন্যাভিগেশন নিয়ন্ত্রণ তৈরি করার সময়, আপনি নিম্নলিখিত Navigation অবজেক্ট ফাংশন ব্যবহার করেন:

ফাংশন বর্ণনা
Navigation.pushCard(Card) বর্তমান স্ট্যাকের উপর একটি কার্ড ঠেলে দেয়। এর জন্য প্রথমে কার্ডটি সম্পূর্ণভাবে তৈরি করা প্রয়োজন।
Navigation.popCard() স্ট্যাকের উপরে থেকে একটি কার্ড সরিয়ে দেয়। অ্যাড-অন হেডার সারিতে পিছনের তীরটিতে ক্লিক করার সমতুল্য। এটি রুট কার্ড অপসারণ করে না।
Navigation.popToRoot() রুট কার্ড ব্যতীত স্ট্যাক থেকে সমস্ত কার্ড সরিয়ে দেয়। মূলত সেই কার্ড স্ট্যাক রিসেট করে।
Navigation.popToNamedCard(String) স্ট্যাক থেকে কার্ড পপ করে যতক্ষণ না এটি প্রদত্ত নাম বা স্ট্যাকের রুট কার্ডের সাথে একটি কার্ডে পৌঁছায়। আপনি CardBuilder.setName(String) ফাংশন ব্যবহার করে কার্ডগুলিতে নাম বরাদ্দ করতে পারেন।
Navigation.updateCard(Card) বর্তমান কার্ডের একটি ইন-প্লেস প্রতিস্থাপন করে, UI-তে এটির প্রদর্শনকে রিফ্রেশ করে।

যদি কোনও ব্যবহারকারীর ইন্টারঅ্যাকশন বা ইভেন্টের ফলে একই প্রসঙ্গে কার্ডগুলি পুনরায় রেন্ডার করা হয়, তাহলে বিদ্যমান কার্ডগুলি প্রতিস্থাপন করতে Navigation.pushCard() , Navigation.popCard() , এবং Navigation.updateCard() পদ্ধতিগুলি ব্যবহার করুন৷ যদি কোনও ব্যবহারকারীর ইন্টারঅ্যাকশন বা ইভেন্টের ফলে কার্ডগুলিকে ভিন্ন প্রেক্ষাপটে রি-রেন্ডারিং করা হয়, তাহলে সেই প্রসঙ্গে আপনার অ্যাড-অন পুনরায় কার্যকর করতে ActionResponseBuilder.setStateChanged() ব্যবহার করুন।

নিম্নলিখিত নেভিগেশন উদাহরণ:

  • যদি একটি মিথস্ক্রিয়া বা ইভেন্ট বর্তমান কার্ডের অবস্থা পরিবর্তন করে (উদাহরণস্বরূপ, একটি টাস্ক তালিকায় একটি টাস্ক যোগ করা), updateCard() ব্যবহার করুন।
  • যদি একটি মিথস্ক্রিয়া বা ইভেন্ট আরও বিশদ প্রদান করে বা ব্যবহারকারীকে পরবর্তী পদক্ষেপের জন্য অনুরোধ করে (উদাহরণস্বরূপ, আরও বিশদ বিবরণ দেখতে একটি আইটেমের শিরোনামে ক্লিক করা, বা একটি নতুন ক্যালেন্ডার ইভেন্ট তৈরি করতে একটি বোতাম টিপে), তখন নতুন পৃষ্ঠাটি দেখানোর জন্য pushCard() ব্যবহার করুন ব্যাক-বোতাম ব্যবহার করে ব্যবহারকারীকে নতুন পৃষ্ঠা থেকে প্রস্থান করার অনুমতি দেয়।
  • যদি একটি মিথস্ক্রিয়া বা ইভেন্ট পূর্ববর্তী কার্ডে অবস্থার আপডেট করে (উদাহরণস্বরূপ, বিশদ দৃশ্যের সাথে একটি আইটেমের শিরোনাম আপডেট করা), পূর্ববর্তী আপডেট করতে popCard() , popCard() , pushCard(previous) এবং pushCard(current) এর মতো কিছু ব্যবহার করুন। কার্ড এবং বর্তমান কার্ড।

রিফ্রেশিং কার্ড

Google Workspace অ্যাড-অন ব্যবহারকারীদের আপনার ম্যানিফেস্টে নিবন্ধিত Apps স্ক্রিপ্ট ট্রিগার ফাংশন পুনরায় চালু করে আপনার কার্ড রিফ্রেশ করার ক্ষমতা দেয়। ব্যবহারকারীরা একটি অ্যাড-অন মেনু আইটেমের মাধ্যমে এই রিফ্রেশটি ট্রিগার করে:

Google Workspace অ্যাড-অন সাইডবার

আপনার অ্যাড-অনের ম্যানিফেস্ট ফাইলে (প্রসঙ্গিক এবং অ-প্রসঙ্গিক কার্ড স্ট্যাকগুলির 'মূল') উল্লেখ করা homepageTrigger বা contextualTrigger ট্রিগার ফাংশন দ্বারা তৈরি কার্ডগুলিতে এই ক্রিয়াটি স্বয়ংক্রিয়ভাবে যুক্ত হয়।

একাধিক কার্ড ফেরত দিচ্ছে

অ্যাড-অন কার্ডের উদাহরণ

হোমপেজ বা প্রাসঙ্গিক ট্রিগার ফাংশনগুলি একটি একক Card অবজেক্ট বা Card অবজেক্টের একটি অ্যারে তৈরি করতে এবং ফেরত দিতে ব্যবহৃত হয় যা অ্যাপ্লিকেশন UI প্রদর্শন করে।

যদি শুধুমাত্র একটি কার্ড থাকে, তবে এটি নন-প্রসঙ্গগত বা প্রাসঙ্গিক স্ট্যাকে রুট কার্ড হিসাবে যোগ করা হয় এবং হোস্ট অ্যাপ্লিকেশন UI এটি প্রদর্শন করে।

যদি প্রত্যাবর্তিত অ্যারেতে একাধিক বিল্ট Card অবজেক্ট থাকে, তবে হোস্ট অ্যাপ্লিকেশনটি পরিবর্তে একটি নতুন কার্ড প্রদর্শন করে, যাতে প্রতিটি কার্ডের হেডারের একটি তালিকা থাকে। ব্যবহারকারী যখন এই শিরোনামগুলির যে কোনও একটিতে ক্লিক করেন, তখন UI সংশ্লিষ্ট কার্ডটি প্রদর্শন করে।

ব্যবহারকারী যখন তালিকা থেকে একটি কার্ড নির্বাচন করেন, তখন সেই কার্ডটি বর্তমান স্ট্যাকের দিকে ঠেলে দেওয়া হয় এবং হোস্ট অ্যাপ্লিকেশন এটি প্রদর্শন করে। বোতাম ব্যবহারকারীকে কার্ড হেডার তালিকায় ফিরিয়ে দেয়।

এই 'ফ্ল্যাট' কার্ড বিন্যাসটি ভালভাবে কাজ করতে পারে যদি আপনার অ্যাড-অনের জন্য আপনার তৈরি করা কার্ডগুলির মধ্যে কোনও পরিবর্তনের প্রয়োজন না হয়। বেশিরভাগ ক্ষেত্রে, তবে, কার্ড ট্রানজিশনগুলিকে সরাসরি সংজ্ঞায়িত করা এবং আপনার হোমপেজ এবং প্রাসঙ্গিক ট্রিগার ফাংশনগুলিকে একটি একক কার্ড অবজেক্ট ফিরিয়ে দেওয়া ভাল অনুশীলন।

উদাহরণ

এখানে একটি উদাহরণ রয়েছে যা দেখায় যে কীভাবে নেভিগেশন বোতামগুলির সাথে বেশ কয়েকটি কার্ড তৈরি করতে হয় যা তাদের মধ্যে লাফ দেয়। createNavigationCard() দ্বারা প্রত্যাবর্তিত কার্ডটিকে একটি নির্দিষ্ট প্রসঙ্গের মধ্যে বা বাইরে পুশ করে এই কার্ডগুলি প্রাসঙ্গিক বা নন-প্রসঙ্গগত স্ট্যাকে যোগ করা যেতে পারে।

  /**
   *  Create the top-level card, with buttons leading to each of three
   *  'children' cards, as well as buttons to backtrack and return to the
   *  root card of the stack.
   *  @return {Card}
   */
  function createNavigationCard() {
    // Create a button set with actions to navigate to 3 different
    // 'children' cards.
    var buttonSet = CardService.newButtonSet();
    for(var i = 1; i <= 3; i++) {
      buttonSet.addButton(createToCardButton(i));
    }

    // Build the card with all the buttons (two rows)
    var card = CardService.newCardBuilder()
        .setHeader(CardService.newCardHeader().setTitle('Navigation'))
        .addSection(CardService.newCardSection()
            .addWidget(buttonSet)
            .addWidget(buildPreviousAndRootButtonSet()));
    return card.build();
  }

  /**
   *  Create a button that navigates to the specified child card.
   *  @return {TextButton}
   */
  function createToCardButton(id) {
    var action = CardService.newAction()
        .setFunctionName('gotoChildCard')
        .setParameters({'id': id.toString()});
    var button = CardService.newTextButton()
        .setText('Card ' + id)
        .setOnClickAction(action);
    return button;
  }

  /**
   *  Create a ButtonSet with two buttons: one that backtracks to the
   *  last card and another that returns to the original (root) card.
   *  @return {ButtonSet}
   */
  function buildPreviousAndRootButtonSet() {
    var previousButton = CardService.newTextButton()
        .setText('Back')
        .setOnClickAction(CardService.newAction()
            .setFunctionName('gotoPreviousCard'));
    var toRootButton = CardService.newTextButton()
        .setText('To Root')
        .setOnClickAction(CardService.newAction()
            .setFunctionName('gotoRootCard'));

    // Return a new ButtonSet containing these two buttons.
    return CardService.newButtonSet()
        .addButton(previousButton)
        .addButton(toRootButton);
  }

  /**
   *  Create a child card, with buttons leading to each of the other
   *  child cards, and then navigate to it.
   *  @param {Object} e object containing the id of the card to build.
   *  @return {ActionResponse}
   */
  function gotoChildCard(e) {
    var id = parseInt(e.parameters.id);  // Current card ID
    var id2 = (id==3) ? 1 : id + 1;      // 2nd card ID
    var id3 = (id==1) ? 3 : id - 1;      // 3rd card ID
    var title = 'CARD ' + id;

    // Create buttons that go to the other two child cards.
    var buttonSet = CardService.newButtonSet()
      .addButton(createToCardButton(id2))
      .addButton(createToCardButton(id3));

    // Build the child card.
    var card = CardService.newCardBuilder()
        .setHeader(CardService.newCardHeader().setTitle(title))
        .addSection(CardService.newCardSection()
            .addWidget(buttonSet)
            .addWidget(buildPreviousAndRootButtonSet()))
        .build();

    // Create a Navigation object to push the card onto the stack.
    // Return a built ActionResponse that uses the navigation object.
    var nav = CardService.newNavigation().pushCard(card);
    return CardService.newActionResponseBuilder()
        .setNavigation(nav)
        .build();
  }

  /**
   *  Pop a card from the stack.
   *  @return {ActionResponse}
   */
  function gotoPreviousCard() {
    var nav = CardService.newNavigation().popCard();
    return CardService.newActionResponseBuilder()
        .setNavigation(nav)
        .build();
  }

  /**
   *  Return to the initial add-on card.
   *  @return {ActionResponse}
   */
  function gotoRootCard() {
    var nav = CardService.newNavigation().popToRoot();
    return CardService.newActionResponseBuilder()
        .setNavigation(nav)
        .build();
  }