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.
- Host: GitHub
- URL: https://github.com/ibm-watson-data-lab/shopping-list
- Owner: ibm-watson-data-lab
- Created: 2017-08-04T16:54:15.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2018-01-26T16:24:59.000Z (over 7 years ago)
- Last Synced: 2024-11-19T15:45:36.722Z (6 months ago)
- Topics: demo-apps, desktop-apps, hybrid-apps, native-apps, offline-first, progressive-web-apps
- Homepage: https://ibm-watson-data-lab.github.io/shopping-list/
- Size: 1.82 MB
- Stars: 68
- Watchers: 15
- Forks: 20
- Open Issues: 80
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Shopping List
**Note:** This is a work in progress.
![]()
![]()
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
 
GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-vanillajs-pouchdb### Polymer and PouchDB
  
GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-polymer-pouchdb### React and PouchDB
  
GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-react-pouchdb### Preact and PouchDB
  
GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-preact-pouchdb### Vue.js and PouchDB
  
GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-vuejs-pouchdb### Ember.js and PouchDB
  
GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-emberjs-pouchdb### React Native and PouchDB
 
GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-react-native-pouchdb### React Native and Cloudant Sync
 
GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-react-native-cloudant-sync### Ionic and PouchDB
 
GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-ionic-pouchdb### Ionic and Cloudant Sync
 
GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-ionic-cloudant-sync### Cordova and PouchDB
 
GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-cordova-pouchdb### Cordova and Cloudant Sync
 
GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-cordova-cloudant-sync### Swift and Cloudant Sync
 
GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-swift-cloudant-sync### Kotlin and Cloudant Sync
 
GitHub Repository:
https://github.com/ibm-watson-data-lab/shopping-list-kotlin-cloudant-sync### Electron and PouchDB
 
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`