An open API service indexing awesome lists of open source software.

https://github.com/ibm-watson-data-lab/shopping-list

A series of Offline First shopping list demo apps, each built using a different stack.
https://github.com/ibm-watson-data-lab/shopping-list

demo-apps desktop-apps hybrid-apps native-apps offline-first progressive-web-apps

Last synced: 6 days ago
JSON representation

A series of Offline First shopping list demo apps, each built using a different stack.

Awesome Lists containing this project

README

        

# Shopping List

**Note:** This is a work in progress.

Mockup 01        Mockup 02        Mockup 03

Shopping List is a series of Offline First demo apps, each built using a different stack. These demo apps cover Progressive Web Apps, hybrid mobile apps, native mobile apps, and desktop apps.

The Shopping List demo apps are brought to you by:

* [Va Barbosa](https://github.com/vabarbosa)
* [Glynn Bird](https://github.com/glynnbird)
* [Juan Camacho](https://github.com/jcamach2)
* [Teri Chadbourne](https://github.com/terichadbourne)
* [Bradley Holt](https://github.com/bradley-holt)
* [Nick Kasten](https://github.com/kastentx)
* [Maureen McElaney](https://github.com/mmcelaney)
* [Lorna Jane Mitchell](https://github.com/lornajane)
* [Raj Singh](https://github.com/rajrsingh)
* [Mark Sturdevant](https://github.com/markstur)
* [Patrick Titzler](https://github.com/ptitzler)
* [Mark Watson](https://github.com/markwatsonatx)

## Table of Contents

- [Purposes](#purposes)
- [Features](#features)
- [Implementations](#implementations)
- [Vanilla JS and PouchDB](#vanilla-js-and-pouchdb)
- [Polymer and PouchDB](#polymer-and-pouchdb)
- [React and PouchDB](#react-and-pouchdb)
- [Preact and PouchDB](#preact-and-pouchdb)
- [Vue.js and PouchDB](#vuejs-and-pouchdb)
- [Ember.js and PouchDB](#emberjs-and-pouchdb)
- [React Native and PouchDB](#react-native-and-pouchdb)
- [React Native and Cloudant Sync](#react-native-and-cloudant-sync)
- [Ionic and PouchDB](#ionic-and-pouchdb)
- [Ionic and Cloudant Sync](#ionic-and-cloudant-sync)
- [Cordova and PouchDB](#cordova-and-pouchdb)
- [Cordova and Cloudant Sync](#cordova-and-cloudant-sync)
- [Swift and Cloudant Sync](#swift-and-cloudant-sync)
- [Kotlin and Cloudant Sync](#kotlin-and-cloudant-sync)
- [Electron and PouchDB](#electron-and-pouchdb)
- [Interoperability](#interoperability)
- [Shopping List Example](#shopping-list-example)
- [Shopping List Item Example](#shopping-list-item-example)
- [Geolocation Context Example](#geolocation-context-example)
- [Domain Model Implementations](#domain-model-implementations)
- [JavaScript](#javascript)
- [Swift](#swift)
- [Kotlin](#kotlin)
- [Style Guides](#style-guides)
- [Templates](#templates)

## Purposes

These demo apps will each serve multiple purposes:

* Reference Implementations
* Live Demos
* Tutorials
* Workshops
* [Developer Journeys](https://developer.ibm.com/code/journey/)

## Features

Shopping List is a simple demo app, with a limited feature set. Here is a list of features written as user stories grouped by Epic:

* Planning
* As a \, I want to \ so that \.
* As a \, I want to \ so that \.
* As a \, I want to \ so that \.
* Shopping
* As a \, I want to \ so that \.
* As a \, I want to \ so that \.
* As a \, I want to \ so that \.
* As a \, I want to \ so that \.
* Offline First
* As a \, I want to \ so that \.
* As a \, I want to \ so that \.
* As a \, I want to \ so that \.
* Multi-User / Multi-Device
* As a \, I want to \ so that \.
* As an \, I want to \ so that \.
* As an \, I want to \ so that \.
* Geolocation
* As a \, I want to \ so that \.
* As a \, I want to \ so that \.
* As a \, I want to \ so that \.

## Implementations

### Vanilla JS and PouchDB

![Progressive Web App](img/pwa-logo.png)        ![PouchDB](img/pouchdb-logo.png)

GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-vanillajs-pouchdb

### Polymer and PouchDB

![Progressive Web App](img/pwa-logo.png)        ![Polymer](img/polymer-logo.png)        ![PouchDB](img/pouchdb-logo.png)

GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-polymer-pouchdb

### React and PouchDB

![Progressive Web App](img/pwa-logo.png)        ![React](img/react-logo.png)        ![PouchDB](img/pouchdb-logo.png)

GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-react-pouchdb

### Preact and PouchDB

![Progressive Web App](img/pwa-logo.png)        ![Preact](img/preact-logo.jpg)        ![PouchDB](img/pouchdb-logo.png)

GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-preact-pouchdb

### Vue.js and PouchDB

![Progressive Web App](img/pwa-logo.png)        ![Vue.js](img/vuejs-logo.png)        ![PouchDB](img/pouchdb-logo.png)

GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-vuejs-pouchdb

### Ember.js and PouchDB

![Progressive Web App](img/pwa-logo.png)        ![Ember.js](img/emberjs-logo.png)        ![PouchDB](img/pouchdb-logo.png)

GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-emberjs-pouchdb

### React Native and PouchDB

![React Native](img/react-native-logo.png)        ![PouchDB](img/pouchdb-logo.png)

GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-react-native-pouchdb

### React Native and Cloudant Sync

![React Native](img/react-native-logo.png)        ![Cloudant Sync](img/cloudant-sync-logo.png)

GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-react-native-cloudant-sync

### Ionic and PouchDB

![Ionic](img/ionic-logo.png)        ![PouchDB](img/pouchdb-logo.png)

GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-ionic-pouchdb

### Ionic and Cloudant Sync

![Ionic](img/ionic-logo.png)        ![Cloudant Sync](img/cloudant-sync-logo.png)

GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-ionic-cloudant-sync

### Cordova and PouchDB

![Cordova](img/cordova-logo.png)        ![PouchDB](img/pouchdb-logo.png)

GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-cordova-pouchdb

### Cordova and Cloudant Sync

![Cordova](img/cordova-logo.png)        ![Cloudant Sync](img/cloudant-sync-logo.png)

GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-cordova-cloudant-sync

### Swift and Cloudant Sync

![Swift](img/swift-logo.png)        ![Cloudant Sync](img/cloudant-sync-logo.png)

GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-swift-cloudant-sync

### Kotlin and Cloudant Sync

![Kotlin](img/kotlin-logo.png)        ![Cloudant Sync](img/cloudant-sync-logo.png)

GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-kotlin-cloudant-sync

### Electron and PouchDB

![Electron](img/electron-logo.png)        ![PouchDB](img/pouchdb-logo.png)

GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-electron-pouchdb

## Interoperability

Implementations of the Shopping List demo app share a data model. This allows the demo apps to be interoperable with one another. For example, a user could plan a shopping trip with a desktop app built using Electron and PouchDB. The same user could then use a native app built using Kotlin and Cloudant Sync while shopping for groceries. Much of the design of this data model is inspired by the [CouchDB Best Practices](https://ehealthafrica.github.io/couchdb-best-practices/) collection from eHealth Africa.

### Shopping List Example

```javascript
{
"_id": "list:cj6mj1zfj000001n1ugjfkj33",
"type": "list",
"version": 1,
"title": "Groceries",
"checked": false,
"place": {
"title": "Healthy Living",
"license": "Data © OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright",
"lat": "44.46282415",
"lon": "-73.1799710198028",
"address": {
"supermarket": "Healthy Living",
"road": "Dorset Street",
"city": "South Burlington",
"county": "Chittenden County",
"state": "Vermont",
"postcode": "05406",
"country": "United States of America",
"countryCode": "us"
}
},
"createdAt": "2017-08-21T18:40:00.000Z",
"updatedAt": "2017-08-21T18:40:00.000Z"
}
```

Notes:

* `_id`: Unique identifier for the document. Generated from the following values, separated by colons:
* Document type (`list`).
* [Collision-resistant ID (cuid)](https://usecuid.org/).
* `type`: Document type (will always have a value of `list` for a shopping list).
* `version`: Document schema version.
* `title`: User-generated title for the shopping list.
* `checked`: Has this shopping list been fully checked off?
* `place`: Associates the shopping list with a geolocation. Derived from OpenStreetMap's [Nominatim](http://wiki.openstreetmap.org/wiki/Nominatim) search tool. The example above is derived from the following search:
```
http://nominatim.openstreetmap.org/search/Healthy%20Living%20Vermont?format=json&addressdetails=1&namedetails=1
```
* `createdAt`: Date and time at which the document was created. Expressed as a simplified extended ISO format in zero UTC offset (which can be generated in JavaScript with `new Date().toISOString()`).
* `updatedAt`: Date and time at which the document was last updated. Expressed as a simplified extended ISO format in zero UTC offset.

### Shopping List Item Example

```javascript
{
"_id": "item:cj6mn7e36000001p9n14fgk6s",
"type": "item",
"version": 1,
"list": "list:cj6mj1zfj000001n1ugjfkj33",
"title": "Mangos",
"checked": false,
"createdAt": "2017-08-21T18:43:00.000Z",
"updatedAt": "2017-08-21T18:43:00.000Z"
}
```

Notes:

* `_id`: Unique identifier for the document. Generated from the following values, separated by colons:
* Document type (`item`).
* [Collision-resistant ID (cuid)](https://usecuid.org/).
* `type`: Document type (will always have a value of `item` for a shopping list item).
* `version`: Document schema version.
* `list`: The unique identifier of the parent shopping list
* `title`: User-generated title for the shopping list item.
* `checked`: Has this shopping list item been checked off?
* `createdAt`: Date and time at which the document was created. Expressed as a simplified extended ISO format in zero UTC offset (which can be generated in JavaScript with `new Date().toISOString()`).
* `updatedAt`: Date and time at which the document was last updated. Expressed as a simplified extended ISO format in zero UTC offset.

Here is an example of a [Mango](http://docs.couchdb.org/en/2.1.0/api/database/find.html) / [`pouchdb-find`](https://pouchdb.com/guides/mango-queries.html) / [Cloudant Query](https://console.bluemix.net/docs/services/Cloudant/api/cloudant_query.html) selector that fetches a single shopping list's items:

```javascript
{
"selector": {
"type": "item",
"list": "list:cj6mj1zfj000001n1ugjfkj33"
}
}
```

Note that the above query can also be used to get a count of items within a shopping list by simply using the `Array.length` property (or equivalent) and accounting for the shopping list document being included in the results. Since PouchDB just runs every reduce function in memory, there is no benefit to using a `_count` reduce function when using PouchDB. The Cloudant Sync libraries for iOS and Android do not support map/reduce (but do support Cloudant Query / Mango).

### Geolocation Context Example

A geolocation context is used to notify the user when the geolocation capability of their device has indicated that they are near a place associated with a shopping list. This provides the user with quick access to the shopping list for their current geographic context.

```javascript
{
"_id": "geo:drguywpyxp4t:cj6mn7e36000001p1q02dlz5q",
"type": "geo",
"list": "list:cj6mj1zfj000001n1ugjfkj33",
"version": 1,
"notified": false,
"createdAt": "2017-08-21T18:57:00.000Z",
"updatedAt": "2017-08-21T18:57:00.000Z"
}
```

Notes:

* `_id`: Unique identifier for the document. Generated from the following values, separated by colons:
* Document type (`geo`).
* Geohash of the `place.lat` and `place.lon` values from the associated shopping list at a precision of 12 (which can be generated in JavaScript using the [`latlon-geohash`](https://www.npmjs.com/package/latlon-geohash) module).
* [Collision-resistant ID (cuid)](https://usecuid.org/).
* `type`: Document type (will always have a value of `geo` for a geolocation context item).
* `list`: The unique identifier of the parent shopping list
* `version`: Document schema version.
* `notified`: Has a notification already been sent for this geolocation context? Note that the geolocation context document may be deleted after a notification has been sent and the corresponding shopping list has been fully checked off.
* `createdAt`: Date and time at which the document was created. Expressed as a simplified extended ISO format in zero UTC offset (which can be generated in JavaScript with `new Date().toISOString()`).
* `updatedAt`: Date and time at which the document was last updated. Expressed as a simplified extended ISO format in zero UTC offset.

Here is an example of a [Mango](http://docs.couchdb.org/en/2.1.0/api/database/find.html) / [`pouchdb-find`](https://pouchdb.com/guides/mango-queries.html) / [Cloudant Query](https://console.bluemix.net/docs/services/Cloudant/api/cloudant_query.html) selector that utilizes the built-in `_all_docs` view to query for geolocation contexts near the current geolocation coordinates of the device (the value `drguyw` below is the geohash of the user's location at a precision of 6, or ±0.61 km):

```javascript
{
"selector": {
"_id": {
"$gte": "geo:drguyw",
"$lte": "geo:drguyw\uffff"
}
}
}
```

## Domain Model Implementations

### JavaScript

GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-model-js

### Swift

GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-model-swift

### Kotlin

GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-model-kotlin

## Style Guides

General guidelines:

* Where possible, a consistent style is maintained between the different demo app implementations.
* Where there is a style that is common for a particular type of application we defer to that style.

Implementations:

* **Vanilla JS:** Material Design (using [MDC-Web](https://material.io/components/web/))
* **Polymer:** Material Design (using [Polymer App Toolbox](https://www.polymer-project.org/2.0/toolbox/))
* **React:** Material Design (using [Material-UI](http://www.material-ui.com/))
* **Preact:** Material Design (using [preact-material-components](https://github.com/prateekbh/preact-material-components))
* **Vue.js:** Material Design (using [Vue Material](http://vuematerial.io/))
* **Ember.js:** Material Design (using [MDC-Web](https://material.io/components/web/))
* **React Native:** iOS Design Themes or Material Design (depending on the target platform)
* **Ionic:** iOS Design Themes or Material Design (depending on the target platform)
* **Cordova:** iOS Design Themes or Material Design (depending on the target platform)
* **Swift:** iOS Design Themes
* **Kotlin:** Material Design
* **Electron:** Material Design (using [MDC-Web](https://material.io/components/web/))

## Templates

See the `templates` directory for templates that can be used for each demo app implementation. This includes the following files:

* `LICENSE`
* `README.md`