Overview

MFGettingStarted

THIS FUNCTION HAS BEEN REPLACED BY MfScreenHelp

MFGettingStarted is a simple help screen function that saves if the user wishes to view help on screen - either because they have not opted out or on demand, and shows the help based on which page is being shown

This class works alongside an html that contains a multi-part help content for use within a getting-started structure, with the ability to automatically pop up the content or to disable that when the user changes Show-on-first-usage (which is saved in the localStorage showGettingStarted-${pageName})

The class also requires the matching .css file to be included.

html
<script src='https://methodfish.com/Download/MFGettingStarted/files/latest/js/mf-getting-started.js'></script>
<link rel='stylesheet preload prefetch' as='style'href='https://methodfish.com/Download/MFGettingStarted/files/latest/css/mf-getting-started.css'>

The suggested usage for this is to create a php/server side function public function getHelpContent(string $page) which will read an xml structure saved in the suggested public_html/help folder and adjust it from a help-writer friendly format into a js/class friendly structure.

The xml (best saved as .html to assist in editing with your chosen editor) should contain some html to present the information, with the option to include <slides><slide>...</slide></slides> structure that then shows these with a friendly UX, showing the content and previous and next buttons;

server
/public_html/help/index.html
/public_html/help/images/....png
/public_html/help/images/....gif

<slide> blocks can also include images in the format of jpg/png/gif or animated gifs (created through tools such as ScreenToGif).

<slide> blocks can also include <overlay> elements that present text over the image at a certain time, and leave that text there for a set period, e.g.

<overlay from="100" duration="6000" className="bottom">Do something.....</overlay>

the from and duration attributes are in milliseconds, but can also support seconds (e.g. 2s) or minutes (e.g. 2m), or both (e.g. 2m2s)

The timer that the class uses is from the point that the image is presented on screen (so that larger files that might require more time to be loaded are accounted for).

An example getHelpContent() function, including adjusting specific text to specific formatting, may read:

php :: getHelpContent
public function getHelpContent(string $page) {
    // Read the help/xxxx.html which contains the html to be shown for the page
    // ..including slides with images that can have optional text overlays, e.g.:
    // <slide info="add a furniture or fixture shape">
    //        <img src='help/images/slide10.gif'>
    //        <overlay from="1000" duraton="2000">Step 1 blah blah</overlay>
    //        <overlay from="3s" duraton="2s">Step 2 blah blah blah</overlay>
    //        <overlay from="3m5s" duraton="1m">Step 3 blah blah blah</overlay>
    //        .
    //        .
    //</slide>

    $slash    = DIRECTORY_SEPARATOR;
    $filePath = config::homedir . $slash . "help$slash" . "$page.html";

    $xmlContent = file_get_contents($filePath);
    if ( config::localDeveloper ) {
       $xmlContent = str_replace("</slides>", "", $xmlContent);
       $xmlContent .= <<<EOT
        <slide info="debugging">
<li>You can enable a debug window using Shift+D</li>
</slide>
</slides>
EOT;
    }

    // Step 1: Convert <overlay ...> into <span class="gif-overlay-text ...">
    $xmlContent = preg_replace_callback(
                    '/<overlay\s+([^>]*)>(.*?)<\/overlay>/i',
                    function ($matches) {
                        preg_match('/from="(\d+)"/i', $matches[1], $fromMatches);
                        preg_match('/duration="(\d+)"/i', $matches[1], $durationMatches);
                        preg_match('/class="([^"]+)"/i', $matches[1], $classMatches);

                   $from     = $fromMatches[1] ?? '0';
                   $duration = $durationMatches[1] ?? '0';
                   $class    = isset($classMatches[1]) ? ' ' . htmlspecialchars($classMatches[1]) : '';

                    return "<span class='gif-overlay-text$class' from='{$from}' duration='{$duration}'>{$matches[2]}</span>";
                },
                $xmlContent
                );

    // Step 2: Wrap <img> and its following <span class="gif-overlay-text..."> siblings in <div class="gif-container">
    $xmlContent = preg_replace_callback(
                    '/(<img\s+[^>]*>)((?:\s*<span class=\'gif-overlay-text[^\']*\'[^>]*>.*?<\/span>)*)/i',
                    function ($matches) {
                        return "<div class='gif-container'>{$matches[1]}{$matches[2]}<div class='gif-timer'></div></div>";
                    },
                    $xmlContent
                );

    // Step 3: Convert other structural tags
    $htmlContent = preg_replace([
                    '/<slides>/i',
                    '/<\/slides>/i',
                    '/<slide([^>]*)>/i',
                    '/<\/slide>/i',
                    '/<img\s+src=["\']([^"\']+)["\']\s*>/i'  // Replace <img src=...> with lazy-load
                ], [
                    '<div class="slides">',
                    '</div>',
                    '<div class="slide hidden"$1>',
                    '</div>',
                    '<img src="images/hourglass.svg" data-src="$1">'
                ], $xmlContent);


    $htmlContent = str_replace("Cntrl+C", "Cntrl+<clickbutton>C</clickbutton>", $htmlContent);
    $htmlContent = str_replace("Cntrl+V", "Cntrl+<clickbutton>V</clickbutton>", $htmlContent);
    $htmlContent = str_replace("Cntrl+B", "Cntrl+<clickbutton>B</clickbutton>", $htmlContent);
    $htmlContent = str_replace("Shift+D", "Shift+<clickbutton>D</clickbutton>", $htmlContent);
    $keywords = ["Cntrl", "Shift", "F1", "Right Mouse Button", "Left Mouse Button", "Mouse Wheel"];
    foreach ($keywords as $word) {
        $pattern = '/\b' . preg_quote($word, '/') . '\b/';
        $htmlContent = preg_replace($pattern, "<clickbutton>$word</clickbutton>", $htmlContent);
    }

    $keywords = ["File menu", "Settings menu"];
    foreach ($keywords as $word) {
       $pattern = '/\b' . preg_quote($word, '/') . '\b/';
       $htmlContent = preg_replace($pattern, "<menuoption>$word</menuoption>", $htmlContent);
    }

    $keywords = ["ABC", "DEF", "XYZ"];
    foreach ($keywords as $word) {
       $pattern = '/\b' . preg_quote($word, '/') . '\b/';
       $htmlContent = preg_replace($pattern, "<rounded>$word</rounded>", $htmlContent);
    }
    if ( config::localDeveloper ) $htmlContent = str_replace("/help/images", config::siteURL."/help/images", $htmlContent);
    $htmlContent = str_replace("APPNAME", config::appNm, $htmlContent);

    // Remove the first "hidden" class to show first slide
    $htmlContent = preg_replace('/<div class="slide hidden"/', '<div class="slide"', $htmlContent, 1);

    return $htmlContent;
}

This is then triggered using a request from the UI:

js :: help trigger

const _gettingStarted = new MFGettingStarted(
   {hourglassSrc: 'images/my-custom-hourglass.svg'}
);
_gettingStarted.showPopup(function() {
                ajaxPost('actionGetHelp=Y&browser='+_gettingStarted.getDeviceType(), qs('#gs-help-content-container'));
            }, 'home');

and picked up from the script on server using:

php :: help response
if( isset($_POST['actionGetHelp'])) {
   $browser = $this->getPost("browser", "");
   $js = "_gettingStarted.transformOverlays();_gettingStarted.initNavigation(".(config::localDeveloper?"true":"false").", 'index');";
   echo $this->getAjaxResponse($js, $this->getHelpContent("index"));
   exit;
}

and an example index.html might read:

html :: help file
<h1>Welcome</h1>
<p>
    Welcome to the APPNAME, allowing you to ...
</p>
<p>You can use this on Windows ...</p>

<h1>Getting Started</h1>

<slides>
    <slide info='step 1'>
        <img src='/help/images/slide1.png'>
        <overlay from="100" duration="6000" class="bottom">Do something to ....</overlay>
        <li>Use the ... to ....</li>
    </slide>
    <slide info='step 2'>
        <img src='/help/images/slide2.png' >
        <li>Use the ... to ....</li>
    </slide>
    <slide info='step 3'>
        <img src='/help/images/slide3.gif'>
        <li>Use the ... to ....</li>
        <overlay from="100" duration="2500" class="bottom">do this <menuoption>menu A</menuoption> to ....</overlay>
        <overlay from="3s" duration="10s" class="top">Then do that....</overlay>
        <overlay from="1m0s" duration="20s" class="bottom">Then ...</overlay>
    </slide>
</slides>

Note here that css exists for li .menuoption, li .clickbutton and li .rounded as well as div.highligher and are recommended to be used in your html (and getHelpContent).


link Click to view a demo

square

About

License

Latest Release

betaNot released yet