adaptlearning / adapt_authoring

A server-based user interface for authoring eLearning courses using the Adapt framework.
https://www.adaptlearning.org/
GNU General Public License v3.0
516 stars 284 forks source link

Automatic export of course as PWA #1815

Closed fabiobeoni closed 3 months ago

fabiobeoni commented 6 years ago

Feature Request

Affected Area

Course publishing

Requested Feature

Add an extra behavior to the course publishing so that the course building automatically generates a "wrapper" around the course app to make it available as a PWA.

Use Case

Learner wants to access the course in a disconnected scenario, the course powered by the PWA features-set can work offline and can be installed in the device as an app:

  1. learner access course home
  2. browser shows a message asking him if he wants the course to be installed in the device, and work offline first
  3. If user accepts, the browser installs the service worker who will download the full course for offline access
  4. once installed as app: course icon is visible on device home screen and can be launched as an app, internet connection is not needed anymore

    Current Workaround

    N.A.

    Additional Information

    None

canstudios-louisem commented 6 years ago

This is something that is normally handled by an LMS, not an authoring tool.

fabiobeoni commented 6 years ago

Hi @canstudios-louisem , thanks for the feedback.

I work with Moodle and such feature is not available yet, but I can immagine others LMS have it. Please also consider the use case of courses published without the support of an LMS. In my experience that's not a rare scenario. Especially when the course does not track the user by SCORM or xAPI, but it takes advantage of widely used analytics tools like G Analytics (both for aggregate stats and single user stats). Thanks! F.

taylortom commented 6 years ago

This sounds like something that could be written as an alternative tracking extension for the framework. Spoor overwrites the index file with an alternative I believe, could you do something similar here?

fabiobeoni commented 6 years ago

Hi @taylortom,

yes, small changes to the course index file may be needed.

To make the course work as a PWA you have to package it with some other metadata files, js service worker, icons + write some tags in the index file.

Changes to the index are really small, most of the work is about putting together all the needed resources and package them.

Somewhere in the AT UI, a new window to fill some metadata may be needed: for instance to type the name of the pwa app to display, once it is installed on device. Or to select some icons from the AT assets, to use it as app icon.

PWA spec also has a number of rules, the browser checks them before offering to the user the option to install the course as app. Page loading time is one of them.

Another rule is about the all app package size limit, when you want to enable full offline access. The size limit varies according to different browsers. So I think for courses having a-lot of media files, the AT might perform a size check, and offer the user the possibility to compress files, or exclude some file types from the offline caching.

I made another server side plugin (PR in progress) that works on course output as soon as it's published. From that experience, I think would be quite useful if the AT publishing process would fire events related to the publishing pipe: giving you the opportunity to add a step to the pipe, and processing logic to it. I'm thinking something like WordPress does with hooks, or ExpressJS with the pipe of middlewares.

I believe I can develop the feature, having some support from the core dev team about how to add a new UI window to the AT, maybe extra menu items.

Thanks, F.

lc-thomasberger commented 6 years ago

To me this looks more like a general Adapt Plugin rather then a feature that must be implemented by the AuthoringTool. Spoor packages it's own html files. Also Plugins can register UI Elements to add config data. I would try to implement it as a plugin first. If there are AT amends necessary we can try to solve them as plugin-agnostic as possible.

fabiobeoni commented 6 years ago

Hi Thomas,

I agree with you that most of "work" is in the client side: package files, manifest, service-worker etc.

By the way, some data to implement the PWA probably need to come from the server side. For instance, the list of all files and resources included in the course output. The list is needed to make the service-worker cache them on the client side, but from the client side alone you cannot get such list of files. That's just the first thing coming to my mind, but I'm quite sure there will be others.

I fully agree to implement the server side logic as plugin to do not impact the core, I really like that way. I tried to do the same by developing the Adobe Animate CC integration for Adapt AT (https://github.com/adaptlearning/adapt_authoring/pull/1821), who also works 100% on course output (as we would probably need to implement the PWA). I developed the Adobe Animate integration as a server-side "Output Plugin" (as described in Adapt Wiki), but at the end I found that I would not succeed without making some changes to the core code. Likely, I modified just 3 lines of it (https://github.com/adaptlearning/adapt_authoring/pull/1821/files#diff-df68ee67d4821734092e7178fd97957a 247 to 249), the rest of new logic is confined in the new server side plugin.

Let's say, in general if you like the idea to have a course output that can be installed as an app on user device (mobile especially) without involving to build a real app with native tech... I think we could find a way to do it and limit as much as possible any potential impact on other core features/code.

I think there will be an interest on PWAs, I know companies in Italy that provide courses wrapped with-in hybrid mobile apps (Cordova/Ionic/ etc) without never releasing courses on LMS. In such scenarios, having a course export PWA-compliant would drastically reduce the need to build a wrapper app. Personally I find it appealing :)

What's your opinion about it?

Thanks! F.

canstudios-louisem commented 6 years ago

Could you explain the sort of things you would need and cant get by just looking at the json and other files you get in the source download?

fabiobeoni commented 6 years ago

OK I will try, as much as I can...

Quickly and just for now, the metadata below is required in the index file of the course (or any other HTML page):

<link rel="manifest" href="manifest.json">

So I think you would need to print it server-side.

The manifest.json file is specific to PWA, and includes the following (sample taken from a test I made):

{
    "version":"1.0.0",
    "short_name": "PWA App",
    "name": "Progressive Web Application Starter Kit",
    "icons": [
        {
            "src": "images/icon-512x512.png",
            "type": "image/png",
            "sizes": "512x512"
        },
        {
            "src": "images/icon-192x192.png",
            "type": "image/png",
            "sizes": "192x192"
        }
    ],
    "start_url": "pwaMain.html?launcher=true",
    "background_color": "#FFFFFE",
    "theme_color": "#3E82F7",
    "display": "standalone"
}

I think the AT user would like to select the icons (from Assets), theme color, provide the text to put in the App name and label on device monitor, etc..

Give me some time, I will try to be exhaustive and answer your question ;)

Thanks, F.

lc-thomasberger commented 6 years ago

Hello Fabio,

I also think that PWA will play a mojor role for webapps and of course also in the e-Learning business. So I really appreciate your work on this topic with Adapt.

My concern is just that everything we put in core will affect all other users. If we have to many different output options it will confuse some users.

If you need a change in the course build chain, I would start with an implementation in the Framework. For instance a sub grunt task that ties into the general build. If it is composable it can easily be reused and other features can build on it.

However, getting a list of the used assets can be achieved in different ways. You may check the db or look in the generated content using a AuthoringTool Server plugin. However, I would use the schema definition to identify the json attributes that use a Asset:image to load a image file. I did something similar with the text export for the grunt:translate tasks. This parsing can be done entirely on the client. All you need to do on the backend is save the file and inject it into the bundle.

I hope you understand that we don't want to block you from adding features. We just need to be careful what we add to the core to make Adapt a better tool for all of us.

Thanks

Thomas

fabiobeoni commented 6 years ago

Hi @lc-thomasberger , first of all thanks for your time on this feature proposal.

I get your point, as I said above I am in favor of developing new features without affecting the Core. Let me say, I see here a limit that the front-end doesn't have: installing/removing plugins. Server-side plugins are "planned" and also implemented (auth / content / filestorage), but there is no way from the Adapt AT user interface to install/uninstall server side plugins. From this perspective, it's much more difficult to design new features and take them out of Core.

I appreciate your suggestion to approach the pwa feature from the adapt_framework, and play with Grunt, but honestly I'm not so keen on working on something that would be used only by people with coding background.

Since my last message, I tried to design a "PWA wrapper" to be included into the AT output (the course .zip package), looking to put the extra feature in new files (JS/HTML) without affecting the AT Core.

Short structure sample:

./MyCourse/ + index.html (standard course main file) + [ ... ] (all other regular folders/files of a course)

Then we would need at least:

+ offline.html (entry point of the pwa, hosts a progress bar about pre-loading and caching course assets) + service-worker.js (managing preloading/caching and offline serving files) + cacheConfig.json (list of files to be cached - this can be generated only on the server side) + manifest.json (pwa required manifest, describes how the pwa works on device - this can be generated only on the server side)

How I see this could work:

  1. Standard access to the course on a LMS would go directly to index.html as it is the course entry point. No changes to the standard user experience.

  2. User interested in off-line access: the course is hosted in a normal web site ( or LMS with public access). The site offers the possibility to take the course offline (extra "access" button somewhere in the page presenting the course). When the user selects the offline option goes to offline.html, the file hosts the logic to install the course as an app in the user device. When ready, browser is redirected to regular index.html

[Sample from a site offering similar options] screenshot from 2018-02-14 15-53-29

There are some data required by the manifest.json file to install the course:

  1. short_name: name displayed on installed app icon,
  2. name: name displayed while the app starts,
  3. icons: at-least one icon to set the app icon on user device.

Making the sample I realized that I can get name and short_name from the course.json, and icons from course assets folder (if the AT user takes care of including at-least one icon into the course, otherwise I could use a default one).

Now, putting these extra pwa files side-by-side with the standard course might be achieved within the scope of a server side output plugin, maybe without affecting the AT Core.

By the way I understand the need of keeping things clean, easy and maintainable for everybody. So if you guys think that this feature would not be appreciated from the final user, or you would drive the developing effort on other features, I am OK with that.

Thanks again for sharing your opinions.

taylortom commented 6 years ago

Thanks for your thoughts on this @fabiobeoni!

The next big chunk of work that I'm going to be doing is to re-architect the node server component of the application, with the main aim being to make it more accessible to non-core developers, and to allow new features to be written in a self-contained/modular way.

While I'm not convinced this specific PWA plugin is something that will make it into core (in fact we're looking at possibly moving some core functionality into separate plugins to allow more flexibility), I'd like to work with you to make sure that it will be possible to do things like this easily with the new architecture.

fabiobeoni commented 6 years ago

Hi @taylortom , thanks for answer.

I must say that I find the current architecture well organized and easy to approach, then of course every app has is own down-sides, code/architecture can always be improved. Moving some core logic to modules is for sure a good way to make the app more resilient.

Recently I had a look to Google Course Builder that works in such way, almost all functionalities are encapsulated in modules. Including main features like course creation (I love looking how big players do software).

If you want to have a look, the project is easy to navigate and understand (even if you don't know Python... I don't): https://github.com/google/coursebuilder-core/tree/master/coursebuilder
Also, I found quite interesting the suggestion expressed in the documentation about how to create a module that overrides core features. They basically work with "hooks" (similarly to WordPress I suppose): https://edu.google.com/openonline/course-builder/docs/1.11/for-course-builder-developers/specific-sub-tasks/create-custom-modules.html

If you think I can help you guys on rewriting the node server, I would really like that. My only concern is about how much time you would expect from my contribution.

Thanks, Fabio.

derhuebiii commented 6 years ago

Hi all, has there been any progress? Any git to test/participate? Thanks, Tim

EmSixTeen commented 3 months ago

We've been looking for this for a long time. Googling just always seems to lead back here, so just adding on the voices to say that this is still desired functionality.

taylortom commented 3 months ago

This is something that should already be possible to build via a framework plugin - custom plugin scripts have been available for several years now to allow things like generating manifests (see https://github.com/adaptlearning/adapt_framework/issues/1741).

This isn't a feature that will be added to this repository as this codebase will soon be superseded by the in-development v1 product and thus new features are no longer being considered.

This could be considered for v1, but would preferably be a community developed addition, rather than something maintained by the open-source project, as there is currently no appetite for this feature within the open-source team.