diff --git a/onsenui2/.gitignore b/onsenui2/.gitignore new file mode 100644 index 00000000..2009598a --- /dev/null +++ b/onsenui2/.gitignore @@ -0,0 +1,32 @@ +# Logs +logs +*.log +npm-debug.log* + +# Dependency directory +node_modules + +# Optional npm cache directory +.npm + +# Optional REPL history +.node_repl_history + +### OSX ### +*.DS_Store +.AppleDouble +.LSOverride + +# Thumbnails +._* + +### NPM scripts ### +www/assets/angular +www/assets/localforage +www/assets/onsenui +www/assets/lodash + +### cordova ### +/platforms +/plugins +/hooks diff --git a/onsenui2/.npmignore b/onsenui2/.npmignore new file mode 100644 index 00000000..0d900251 --- /dev/null +++ b/onsenui2/.npmignore @@ -0,0 +1,2 @@ +# Mac +.DS_Store diff --git a/onsenui2/README.md b/onsenui2/README.md new file mode 100644 index 00000000..77457f2e --- /dev/null +++ b/onsenui2/README.md @@ -0,0 +1,52 @@ +# Onsen UI 2 implementation with Angular 1 +Visit [Onsen UI page](https://onsen.io/) + +##Introduction + +Onsen UI provides UI framework and tools for creating fast and beautiful HTML5 hybrid mobile apps based on PhoneGap/Cordova. Having common core with no framework dependencies, app development with Onsen UI is easy with any of the ever-changing JavaScript frameworks. + +##Building the Application +First follow [Apache Cordova](https://cordova.apache.org/#getstarted) or [PhoneGap](http://docs.phonegap.com/getting-started/1-install-phonegap/cli/) install instrucctions. + +Then install the needed NPM packages: + +``` +$ npm install +``` + +And setup project: + +``` +$ npm run setup +``` + +###Add your chosen platform + +``` +$ phonegap platform add android +$ phonegap platform add ios +``` + +###Develop + +``` +$ phonegap serve +``` + +###Build + +``` +$ phonegap build android +$ phonegap build ios +``` + +##Application Structure ++ `package.json` ++ `config.xml` - Cordova/PhoneGap configuration file ++ `\www` + + `index.html` - Entry HTML for app. + + `\res` - icons and splashscreens used by the app. + + `\services` - Services to handle the communication to the Nestoria APIs and persist recent searches and favourites. + + `\pages` - Includes a folder for each app page (view and logic). + + `\assets` - Vendor and Custom JavaScript and styles. + diff --git a/onsenui2/config.xml b/onsenui2/config.xml new file mode 100644 index 00000000..f00d15f8 --- /dev/null +++ b/onsenui2/config.xml @@ -0,0 +1,87 @@ + + + PropertyCross + + PropertyCross Implementation With Onsen UI 2 - Angular 1 + + Leonel Viera + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/onsenui2/npm-shrinkwrap.json b/onsenui2/npm-shrinkwrap.json new file mode 100644 index 00000000..8fd56d97 --- /dev/null +++ b/onsenui2/npm-shrinkwrap.json @@ -0,0 +1,664 @@ +{ + "name": "propertycross-onsenui2-implementation", + "version": "4.0.2", + "dependencies": { + "acorn": { + "version": "1.2.2", + "from": "acorn@>=1.0.3 <2.0.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-1.2.2.tgz" + }, + "amdefine": { + "version": "1.0.0", + "from": "amdefine@>=0.0.4", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.0.tgz" + }, + "angular": { + "version": "1.5.8", + "from": "angular@1.5.8", + "resolved": "https://registry.npmjs.org/angular/-/angular-1.5.8.tgz" + }, + "ansi-regex": { + "version": "2.0.0", + "from": "ansi-regex@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "from": "ansi-styles@>=2.2.1 <3.0.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "dev": true + }, + "array-filter": { + "version": "0.0.1", + "from": "array-filter@>=0.0.0 <0.1.0", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "dev": true + }, + "array-map": { + "version": "0.0.0", + "from": "array-map@>=0.0.0 <0.1.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "dev": true + }, + "array-reduce": { + "version": "0.0.0", + "from": "array-reduce@>=0.0.0 <0.1.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "dev": true + }, + "ast-types": { + "version": "0.8.15", + "from": "ast-types@0.8.15", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.8.15.tgz" + }, + "balanced-match": { + "version": "0.4.2", + "from": "balanced-match@>=0.4.1 <0.5.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", + "dev": true + }, + "base62": { + "version": "0.1.1", + "from": "base62@0.1.1", + "resolved": "https://registry.npmjs.org/base62/-/base62-0.1.1.tgz" + }, + "brace-expansion": { + "version": "1.1.6", + "from": "brace-expansion@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.6.tgz", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "from": "builtin-modules@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "from": "chalk@>=1.1.3 <2.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "from": "concat-map@0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "dev": true + }, + "copyfiles": { + "version": "1.0.0", + "from": "copyfiles@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/copyfiles/-/copyfiles-1.0.0.tgz", + "dev": true, + "dependencies": { + "isarray": { + "version": "1.0.0", + "from": "isarray@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "dev": true + }, + "readable-stream": { + "version": "2.0.6", + "from": "readable-stream@>=2.0.0 <2.1.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "dev": true, + "dependencies": { + "process-nextick-args": { + "version": "1.0.7", + "from": "process-nextick-args@>=1.0.6 <1.1.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "from": "util-deprecate@>=1.0.1 <1.1.0", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "dev": true + } + } + }, + "through2": { + "version": "2.0.1", + "from": "through2@>=2.0.1 <3.0.0", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.1.tgz", + "dev": true + } + } + }, + "core-util-is": { + "version": "1.0.2", + "from": "core-util-is@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" + }, + "cross-spawn": { + "version": "4.0.2", + "from": "cross-spawn@>=4.0.0 <5.0.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", + "dev": true + }, + "define-properties": { + "version": "1.1.2", + "from": "define-properties@>=1.1.2 <2.0.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "dev": true + }, + "duplexer": { + "version": "0.1.1", + "from": "duplexer@>=0.1.1 <0.2.0", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "dev": true + }, + "error-ex": { + "version": "1.3.0", + "from": "error-ex@>=1.2.0 <2.0.0", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.0.tgz", + "dev": true + }, + "es-abstract": { + "version": "1.6.1", + "from": "es-abstract@>=1.4.3 <2.0.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.6.1.tgz", + "dev": true + }, + "es-to-primitive": { + "version": "1.1.1", + "from": "es-to-primitive@>=1.1.1 <2.0.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "dev": true + }, + "es3ify": { + "version": "0.1.4", + "from": "es3ify@>=0.1.3 <0.2.0", + "resolved": "https://registry.npmjs.org/es3ify/-/es3ify-0.1.4.tgz" + }, + "escape-string-regexp": { + "version": "1.0.5", + "from": "escape-string-regexp@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "dev": true + }, + "esmangle-evaluator": { + "version": "1.0.1", + "from": "esmangle-evaluator@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/esmangle-evaluator/-/esmangle-evaluator-1.0.1.tgz" + }, + "esprima-fb": { + "version": "3001.1.0-dev-harmony-fb", + "from": "esprima-fb@>=3001.1.0-dev-harmony-fb <3001.2.0", + "resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-3001.0001.0000-dev-harmony-fb.tgz" + }, + "event-stream": { + "version": "3.3.4", + "from": "event-stream@>=3.3.0 <3.4.0", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "dev": true + }, + "falafel": { + "version": "1.2.0", + "from": "falafel@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/falafel/-/falafel-1.2.0.tgz" + }, + "find-up": { + "version": "1.1.2", + "from": "find-up@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "dev": true + }, + "foreach": { + "version": "2.0.5", + "from": "foreach@>=2.0.5 <3.0.0", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz" + }, + "from": { + "version": "0.1.3", + "from": "from@>=0.0.0 <1.0.0", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.3.tgz", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "from": "fs.realpath@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "dev": true + }, + "function-bind": { + "version": "1.1.0", + "from": "function-bind@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz", + "dev": true + }, + "glob": { + "version": "7.1.1", + "from": "glob@>=7.0.5 <8.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "dev": true + }, + "graceful-fs": { + "version": "4.1.9", + "from": "graceful-fs@>=4.1.2 <5.0.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.9.tgz", + "dev": true + }, + "has-ansi": { + "version": "2.0.0", + "from": "has-ansi@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "dev": true + }, + "hosted-git-info": { + "version": "2.1.5", + "from": "hosted-git-info@>=2.1.4 <3.0.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.1.5.tgz", + "dev": true + }, + "immediate": { + "version": "3.0.6", + "from": "immediate@>=3.0.5 <3.1.0", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz" + }, + "inflight": { + "version": "1.0.6", + "from": "inflight@>=1.0.4 <2.0.0", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "dev": true + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@>=2.0.1 <2.1.0", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "inline-process-browser": { + "version": "1.0.0", + "from": "inline-process-browser@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/inline-process-browser/-/inline-process-browser-1.0.0.tgz" + }, + "is-arrayish": { + "version": "0.2.1", + "from": "is-arrayish@>=0.2.1 <0.3.0", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "from": "is-builtin-module@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "dev": true + }, + "is-callable": { + "version": "1.1.3", + "from": "is-callable@>=1.1.3 <2.0.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "from": "is-date-object@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "dev": true + }, + "is-regex": { + "version": "1.0.3", + "from": "is-regex@>=1.0.3 <2.0.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.3.tgz", + "dev": true + }, + "is-symbol": { + "version": "1.0.1", + "from": "is-symbol@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "from": "is-utf8@>=0.2.0 <0.3.0", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "from": "isarray@0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "isexe": { + "version": "1.1.2", + "from": "isexe@>=1.1.1 <2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-1.1.2.tgz", + "dev": true + }, + "jsonify": { + "version": "0.0.0", + "from": "jsonify@>=0.0.0 <0.1.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "dev": true + }, + "jstransform": { + "version": "3.0.0", + "from": "jstransform@>=3.0.0 <3.1.0", + "resolved": "https://registry.npmjs.org/jstransform/-/jstransform-3.0.0.tgz" + }, + "lie": { + "version": "3.0.2", + "from": "lie@3.0.2", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.0.2.tgz" + }, + "load-json-file": { + "version": "1.1.0", + "from": "load-json-file@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "dev": true + }, + "localforage": { + "version": "1.4.3", + "from": "localforage@1.4.3", + "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.4.3.tgz" + }, + "lodash": { + "version": "4.16.4", + "from": "lodash@4.16.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.16.4.tgz" + }, + "lru-cache": { + "version": "4.0.1", + "from": "lru-cache@>=4.0.1 <5.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.1.tgz", + "dev": true + }, + "ltcdr": { + "version": "2.2.1", + "from": "ltcdr@>=2.2.1 <3.0.0", + "resolved": "https://registry.npmjs.org/ltcdr/-/ltcdr-2.2.1.tgz", + "dev": true + }, + "map-stream": { + "version": "0.1.0", + "from": "map-stream@>=0.1.0 <0.2.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "dev": true + }, + "minimatch": { + "version": "3.0.3", + "from": "minimatch@>=3.0.2 <4.0.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", + "dev": true + }, + "minimist": { + "version": "0.0.8", + "from": "minimist@0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "from": "mkdirp@>=0.5.1 <0.6.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "dev": true + }, + "noms": { + "version": "0.0.0", + "from": "noms@0.0.0", + "resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz", + "dev": true + }, + "normalize-package-data": { + "version": "2.3.5", + "from": "normalize-package-data@>=2.3.2 <3.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.5.tgz", + "dev": true + }, + "npm-run-all": { + "version": "2.3.0", + "from": "npm-run-all@>=2.3.0 <3.0.0", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-2.3.0.tgz", + "dev": true + }, + "object-assign": { + "version": "4.1.0", + "from": "object-assign@>=4.0.1 <5.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", + "dev": true + }, + "object-keys": { + "version": "1.0.9", + "from": "object-keys@>=1.0.6 <2.0.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.9.tgz" + }, + "once": { + "version": "1.4.0", + "from": "once@>=1.3.0 <2.0.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "dev": true + }, + "onsenui": { + "version": "2.0.3", + "from": "onsenui@2.0.3", + "resolved": "https://registry.npmjs.org/onsenui/-/onsenui-2.0.3.tgz" + }, + "parse-json": { + "version": "2.2.0", + "from": "parse-json@>=2.2.0 <3.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "dev": true + }, + "path-exists": { + "version": "2.1.0", + "from": "path-exists@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "from": "path-is-absolute@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "from": "path-type@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "dev": true + }, + "pause-stream": { + "version": "0.0.11", + "from": "pause-stream@0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "dev": true + }, + "pify": { + "version": "2.3.0", + "from": "pify@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "from": "pinkie@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "from": "pinkie-promise@>=2.0.1 <3.0.0", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "dev": true + }, + "private": { + "version": "0.1.6", + "from": "private@>=0.1.5 <0.2.0", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.6.tgz" + }, + "ps-tree": { + "version": "1.1.0", + "from": "ps-tree@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.0.tgz", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "from": "pseudomap@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "dev": true + }, + "read-pkg": { + "version": "1.1.0", + "from": "read-pkg@>=1.1.0 <2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "dev": true + }, + "read-pkg-up": { + "version": "1.0.1", + "from": "read-pkg-up@>=1.0.1 <2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "from": "readable-stream@>=1.0.33-1 <1.1.0-0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz" + }, + "recast": { + "version": "0.10.43", + "from": "recast@>=0.10.1 <0.11.0", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.10.43.tgz", + "dependencies": { + "esprima-fb": { + "version": "15001.1001.0-dev-harmony-fb", + "from": "esprima-fb@>=15001.1001.0-dev-harmony-fb <15001.1002.0", + "resolved": "https://registry.npmjs.org/esprima-fb/-/esprima-fb-15001.1001.0-dev-harmony-fb.tgz" + }, + "source-map": { + "version": "0.5.6", + "from": "source-map@>=0.5.0 <0.6.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz" + } + } + }, + "rimraf": { + "version": "2.5.4", + "from": "rimraf@>=2.5.4 <3.0.0", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", + "dev": true + }, + "semver": { + "version": "5.3.0", + "from": "semver@>=2.0.0 <3.0.0||>=3.0.0 <4.0.0||>=4.0.0 <5.0.0||>=5.0.0 <6.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "dev": true + }, + "shell-quote": { + "version": "1.6.1", + "from": "shell-quote@>=1.6.1 <2.0.0", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "dev": true + }, + "source-map": { + "version": "0.1.31", + "from": "source-map@0.1.31", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.31.tgz" + }, + "spdx-correct": { + "version": "1.0.2", + "from": "spdx-correct@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "dev": true + }, + "spdx-expression-parse": { + "version": "1.0.4", + "from": "spdx-expression-parse@>=1.0.0 <1.1.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "dev": true + }, + "spdx-license-ids": { + "version": "1.2.2", + "from": "spdx-license-ids@>=1.0.2 <2.0.0", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "dev": true + }, + "split": { + "version": "0.3.3", + "from": "split@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "dev": true + }, + "stream-combiner": { + "version": "0.0.4", + "from": "stream-combiner@>=0.0.4 <0.1.0", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@>=0.10.0 <0.11.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "string.prototype.padend": { + "version": "3.0.0", + "from": "string.prototype.padend@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "from": "strip-ansi@>=3.0.0 <4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "dev": true + }, + "strip-bom": { + "version": "2.0.0", + "from": "strip-bom@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "from": "supports-color@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "dev": true + }, + "through": { + "version": "2.3.8", + "from": "through@>=2.3.4 <2.4.0", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + }, + "through2": { + "version": "0.6.5", + "from": "through2@>=0.6.5 <0.7.0", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz" + }, + "unreachable-branch-transform": { + "version": "0.3.0", + "from": "unreachable-branch-transform@>=0.3.0 <0.4.0", + "resolved": "https://registry.npmjs.org/unreachable-branch-transform/-/unreachable-branch-transform-0.3.0.tgz" + }, + "validate-npm-package-license": { + "version": "3.0.1", + "from": "validate-npm-package-license@>=3.0.1 <4.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "dev": true + }, + "which": { + "version": "1.2.11", + "from": "which@>=1.2.9 <2.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.2.11.tgz", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "from": "wrappy@>=1.0.0 <2.0.0", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "from": "xtend@>=4.0.0 <4.1.0-0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz" + }, + "yallist": { + "version": "2.0.0", + "from": "yallist@>=2.0.0 <3.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.0.0.tgz", + "dev": true + } + } +} diff --git a/onsenui2/package.json b/onsenui2/package.json new file mode 100644 index 00000000..0cf41250 --- /dev/null +++ b/onsenui2/package.json @@ -0,0 +1,39 @@ +{ + "name": "propertycross-onsenui2-implementation", + "version": "1.0.0", + "description": "An implementation of PropertyCross using onsen ui 2", + "repository": { + "type": "git", + "url": "https://github.com/vieraleonel/onsenui2-propertycross-impl" + }, + "author": "Viera Leonel", + "license": "SEE LICENCE IN LICENSE", + "keywords": [ + "cordova", + "propertycross", + "phonegap", + "framework7", + "mobile", + "hybrid" +], + "homepage": "https://github.com/vieraleonel/onsenui2-propertycross-impl", + "dependencies": { + "angular": "^1.5.6", + "localforage": "^1.4.2", + "lodash": "^4.13.1", + "onsenui": "^2.0.3" + }, + "devDependencies": { + "copyfiles": "^1.0.0", + "npm-run-all": "^2.3.0", + "rimraf": "^2.5.4" + }, + "scripts": { + "setup:localforage": "copyfiles -f ./node_modules/localforage/dist/* ./www/assets/localforage", + "setup:lodash": "copyfiles -f ./node_modules/lodash/lodash.min.js ./www/assets/lodash", + "setup:angular": "copyfiles -f ./node_modules/angular/angular-csp.css ./node_modules/angular/angular.min.js ./node_modules/angular/angular.min.js.map ./www/assets/angular", + "setup:onsenui": "copyfiles -u 1 './node_modules/onsenui/css/**' './node_modules/onsenui/js/**' ./www/assets", + "setup": "npm-run-all --parallel 'setup:localforage' 'setup:lodash' 'setup:angular' 'setup:onsenui'", + "clean": "rimraf ./www/assets/localforage ./www/assets/lodash ./www/assets/angular ./www/assets/onsenui" + } +} diff --git a/onsenui2/www/assets/css/styles.css b/onsenui2/www/assets/css/styles.css new file mode 100644 index 00000000..458824a7 --- /dev/null +++ b/onsenui2/www/assets/css/styles.css @@ -0,0 +1,66 @@ +/* Navbar */ +.navigation-bar .right { + padding-right: 10px; +} + +body.material .navbar-blue { + background-color: #387ef5; +} + +/* Search input */ +body.ios #search-properties-container { + background-color: white; + border-top: 1px solid #d2cece; + border-bottom: 1px solid #d2cece; +} + +#search-properties-container { + margin: 15px 0 15px 0; +} + +#search-properties-container ons-input { + width:100% +} + +body.ios #search-properties-container input { + height: 50px; +} + +/* Badges */ +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: 700; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: middle; + background-color: #777; + border-radius: 10px; +} + +/* Buttons */ +body.material .btn-blue { + background-color: #387ef5; +} + +body.ios .btn-green { + background-color: #4cd964; +} + +/* Favs */ +body.material .fav-pink { + background-color: #E91E63; +} + +/* Errors */ +body.ios .text-error { + color: #ff3b30; +} + +body.material .text-error { + color: #d50000; +} \ No newline at end of file diff --git a/onsenui2/www/assets/js/constants.js b/onsenui2/www/assets/js/constants.js new file mode 100644 index 00000000..b5aa86b9 --- /dev/null +++ b/onsenui2/www/assets/js/constants.js @@ -0,0 +1,24 @@ +/** + * Global constants + * @return {[type]} [description] + */ +(function() { + 'use strict'; + + app.constant('PROPERTY_API', { + baseUrl: 'http://api.nestoria.co.uk/api?country=uk&pretty=0&action=search_listings&encoding=json&listing_type=buy', + error: { + messages: { + ZERO_PROPERTIES: 'There were no properties found for the given location.', + GENERIC_ERROR: 'An error occurred while searching. Please check your network connection and try again.', + LOCATION_DISABLED: 'The use of location is currently disabled.', + LOCATION_UNAVAILABLE: 'Unable to detect current location. Please ensure location is turned on in your phone settings and try again.' + } + }, + status: { + SUCCESS: 1, + AMBIGUOUS: 2, + ERROR: 0 + } + }); +})(window.app); \ No newline at end of file diff --git a/onsenui2/www/icon.png b/onsenui2/www/icon.png new file mode 100644 index 00000000..2cb89282 Binary files /dev/null and b/onsenui2/www/icon.png differ diff --git a/onsenui2/www/index.html b/onsenui2/www/index.html new file mode 100755 index 00000000..08a60e94 --- /dev/null +++ b/onsenui2/www/index.html @@ -0,0 +1,73 @@ + + + + + + + + + + + + + PropertyCross + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/onsenui2/www/pages/favourites/favourites.controller.js b/onsenui2/www/pages/favourites/favourites.controller.js new file mode 100644 index 00000000..e366fbea --- /dev/null +++ b/onsenui2/www/pages/favourites/favourites.controller.js @@ -0,0 +1,49 @@ +(function(app){ + 'use strict'; + + // add controller to app + app.controller('FavouritesPageController', FavouritesPageController); + + // controller dependencies + FavouritesPageController.$inject = ['FavouritesService', '$timeout', '$window'] + + // controller + function FavouritesPageController(FavouritesService, $timeout, $window) { + var vm = this; + + // properties + vm.faves = []; + + // methods + vm.goToPropertyDetails = goToPropertyDetails; + + // startup method + activate(); + //////////////////////// + + /** + * Startup method. Get favourites from service + */ + function activate() { + FavouritesService.getAll() + .then(function(faves) { + // workarount to force $digest cycle + $timeout(function() { vm.faves = faves;}, 0) + }); + } + + /** + * Navigates to property details page with selected favourite + * + * @param Object property Selected property + */ + function goToPropertyDetails(property) { + // navi is global from onsen-navigator + $window.navi.pushPage('pages/property-details/property-details.html', { + data: { + selectedProperty: property + } + }); + } + } // function FavouritesPageController +})(window.app); \ No newline at end of file diff --git a/onsenui2/www/pages/favourites/favourites.html b/onsenui2/www/pages/favourites/favourites.html new file mode 100644 index 00000000..eb3ffffd --- /dev/null +++ b/onsenui2/www/pages/favourites/favourites.html @@ -0,0 +1,27 @@ + + +
+ Back +
+
Favourites
+
+ + + + +

You have not added any properties to your favourites

+
+
+ + + +
+ +
+
+ {{ ::property.price_formatted }} + {{ ::property.title }} +
+
+
+
diff --git a/onsenui2/www/pages/home/home.controller.js b/onsenui2/www/pages/home/home.controller.js new file mode 100644 index 00000000..d7a38f8c --- /dev/null +++ b/onsenui2/www/pages/home/home.controller.js @@ -0,0 +1,185 @@ +(function(app){ + 'use strict'; + + // add controller to app + app.controller('HomePageController', HomePageController); + + // controller dependencies + HomePageController.$inject = ['PROPERTY_API', 'PropertiesService', 'RecentSearchesService', '$window', '$timeout'] + + // controller + function HomePageController(PROPERTY_API, PropertiesService, RecentSearchesService, $window, $timeout) { + var vm = this; + + // properties + vm.searchTerm = ''; + vm.loading = false; + vm.recentSearches = []; + vm.state = 1; + vm.errorMessage = ''; + vm.locations = []; + + // methods + vm.searchByTerm = searchByTerm; + vm.searchByPosition = searchByPosition; + vm.doSearchWith = doSearchWith; + vm.goToFaves = goToFaves; + + // startup method + activate(); + //////////////////////// + + /** + * Startup method + */ + function activate() { + // listener for getting recent searches every time home page is shown + $window.document + .addEventListener('show', function(event){ + if (event.srcElement.id === 'home-page') { + getRecentSearches(); + } + }); + } + + /** + * Get recent searches form storage + */ + function getRecentSearches() { + RecentSearchesService.get() + .then(function(data) { + // workarount to force $digest cycle + $timeout(function() {vm.recentSearches = data;}, 0) + }); + } + + /** + * Toggle Loading modal visibility + */ + function toggleModal() { + $window.document + .getElementById('home-modal') + .toggle(); + } + + /** + * Performs a search by term + */ + function searchByTerm() { + toggleModal(); + + // do search + PropertiesService.searchByTerm(vm.searchTerm) + .then(function(data) { + processResponse(data); + }) + .catch(function(){ + showErrorState({message: 'Other error'}); + }); + } + + /** + * Process Successfull data response from service + * + * @param Object data Returned service response + */ + function processResponse(data) { + if (data.status === PROPERTY_API.status.SUCCESS) { + showResultsPage(data); + } + else if (data.status === PROPERTY_API.status.AMBIGUOUS) { + showLocationsState(data); + } + else { // error + showErrorState(data); + } + } + + /** + * Performs a search by current position + */ + function searchByPosition() { + vm.searchTerm = ''; + + toggleModal(); + + PropertiesService.searchByPosition() + .then(function(data){ + processResponse(data); + }) + .catch(function(error){ + showErrorState(error); + }); + } + + /** + * Navigates to results page + * + * @param Object data + */ + function showResultsPage(data) { + vm.state = 1; + vm.locations = []; + vm.errorMessage = ''; + + // if search was by term, stores it in recent searches + if (vm.searchTerm !== '') { + RecentSearchesService.store({ + term: vm.searchTerm, + results: data.results + }); + } + + $window.navi + .pushPage('pages/results/results.html') + .then(function(){ + toggleModal(); + }); + } + + /** + * Shows user a list to select a location + * + * @param Object data + */ + function showLocationsState(data) { + vm.state = 2; // ambiguous + vm.locations = data.locations; + + toggleModal(); + } + + /** + * Shows user a message for an error situation + * + * @param Object data + */ + function showErrorState(data) { + vm.state = 0; // error + vm.errorMessage = data.message; + + toggleModal(); + } + + /** + * Perform a term based search with de selected location (from location state) + * + * @param Object location + */ + function doSearchWith(location) { + vm.state = 1; + vm.locations = []; + vm.errorMessage = ''; + vm.searchTerm = location; + + searchByTerm(); + } + + /** + * Navigates to favourites pages + */ + function goToFaves() { + $window.navi.pushPage('pages/favourites/favourites.html'); + } + } // function HomePageController +})(window.app); \ No newline at end of file diff --git a/onsenui2/www/pages/home/home.html b/onsenui2/www/pages/home/home.html new file mode 100644 index 00000000..ef100514 --- /dev/null +++ b/onsenui2/www/pages/home/home.html @@ -0,0 +1,64 @@ + + +
PropertyCross
+
Faves
+
+ + + + +

Use the form below to search for houses to buy. You can search by place-name, postcode, or click 'My location', to search in your current location!

+
+
+ + + + + + + + + + + + + + + + Go + + + + My location + + + + + + + {{ vm.errorMessage }} + + + + + Recent searches: + +
+ {{ search.term }} +
+
+ {{ search.results }} +
+
+
+ + + Please select a location below: + + {{ location.title }} + + + +
diff --git a/onsenui2/www/pages/property-details/property-details.controller.js b/onsenui2/www/pages/property-details/property-details.controller.js new file mode 100644 index 00000000..26421240 --- /dev/null +++ b/onsenui2/www/pages/property-details/property-details.controller.js @@ -0,0 +1,81 @@ +(function(app){ + 'use strict'; + + // add controller to app + app.controller('PropertyDetailsPageController', PropertyDetailsPageController); + + // controller dependencies + PropertyDetailsPageController.$inject = ['PropertiesService', 'FavouritesService', '$timeout', '$window'] + + // controller + function PropertyDetailsPageController(PropertiesService, FavouritesService, $timeout, $window) { + var vm = this; + + // properties + vm.property = {}; + + // methods + vm.toggleFav = toggleFav; + + // startup method + activate(); + //////////////////////// + + /** + * Startup method. Get property from + */ + function activate() { + // navi is global from onsen-navigator + vm.property = prepareProperty($window.navi.topPage.data.selectedProperty); + } + + /** + * Transforms property title and check for favourite state + * + * @param Object property + * @return Object Prepared property + */ + function prepareProperty(property) { + property.title = formatTitle(property.title); + + FavouritesService.isFav(property) + .then(function(isFav) { + // workarount to force $digest cycle + $timeout(function() {vm.property.isFav = isFav;}, 0) + }); + + return property; + } + + /** + * Take only first and second title parts + * + * @param string title + * @return string Formatted title + */ + function formatTitle(title) { + var splitTitle = title.split(','); + + if (splitTitle.length > 1) { + title = splitTitle[0] + ', ' + splitTitle[1]; + } else { + title = splitTitle[0]; + } + + return title; + } + + /** + * Toggles fav state + */ + function toggleFav() { + if (vm.property.isFav) { + FavouritesService.remove(vm.property); + } else { + FavouritesService.store(vm.property); + } + + vm.property.isFav = !vm.property.isFav; + } + } +})(window.app); \ No newline at end of file diff --git a/onsenui2/www/pages/property-details/property-details.html b/onsenui2/www/pages/property-details/property-details.html new file mode 100644 index 00000000..e5f0bfdd --- /dev/null +++ b/onsenui2/www/pages/property-details/property-details.html @@ -0,0 +1,44 @@ + + +
+ Back +
+
Property Details
+ +
+ + + + +
+
+ + + + +

{{ ::vm.property.price_formatted }}

+

{{ ::vm.property.title }}

+
+
+ + + + + + + + + + + +

{{ ::vm.property.bedroom_number }} beeds, {{ ::vm.property.bathroom_number }} bathrooms

+

{{ ::vm.property.summary }}

+
+
+ + + + + + +
diff --git a/onsenui2/www/pages/results/results.controller.js b/onsenui2/www/pages/results/results.controller.js new file mode 100644 index 00000000..65571b8c --- /dev/null +++ b/onsenui2/www/pages/results/results.controller.js @@ -0,0 +1,85 @@ +(function(app){ + 'use strict'; + + // add controller to app + app.controller('ResultsPageController', ResultsPageController); + + // controller dependencies + ResultsPageController.$inject = ['PropertiesService', '$window'] + + // controller + function ResultsPageController(PropertiesService, $window) { + var vm = this; + + // properties + vm.queryData = {}; + vm.loadMore = {}; + + // methods + vm.getMoreProperties = getMoreProperties; + vm.goToPropertyDetails = goToPropertyDetails; + + // startup method + activate(); + //////////////////////// + + /** + * startup method. Get queried results and sets Load More state + */ + function activate() { + vm.queryData = PropertiesService.getLastQueryResults(); + + vm.loadMore = { + loading: false, + label: 'Load more ...', + canLoad: vm.queryData.page < vm.queryData.pages + }; + } + + /** + * Toggle Load More state + */ + function toggleLoadMore() { + if (vm.loadMore.loading) { + vm.loadMore.loading = false; + vm.loadMore.label = 'Load more ...'; + } else { + vm.loadMore.loading = true; + vm.loadMore.label = 'Loading ...'; + } + + vm.loadMore.canLoad = vm.queryData.page < vm.queryData.pages; + } + + /** + * Navigates to Property details page with selected property + * + * @param Object property + */ + function goToPropertyDetails(property) { + // navi is global from onsen-navigator + $window.navi.pushPage('pages/property-details/property-details.html', { + data: { + selectedProperty: property + } + }); + } + + /** + * get more results from last query + */ + function getMoreProperties() { + toggleLoadMore(); + + PropertiesService.loadMore() + .then(function(){ + toggleLoadMore(); + vm.queryData = PropertiesService.getLastQueryResults(); + }). + catch(function(error){ + toggleLoadMore(); + alert(error.message) + }); + } + } +})(window.app); \ No newline at end of file diff --git a/onsenui2/www/pages/results/results.html b/onsenui2/www/pages/results/results.html new file mode 100644 index 00000000..4a9d3e2f --- /dev/null +++ b/onsenui2/www/pages/results/results.html @@ -0,0 +1,29 @@ + + +
+ Back +
+
{{ vm.queryData.showing }} of {{ ::vm.queryData.results }} results
+
+ + + +
+ +
+
+ {{ ::property.price_formatted }} + {{ ::property.title }} +
+
+ +
+ +
+
+ {{ vm.loadMore.label }} + Results for {{ ::vm.queryData.searchTerm }}, showing {{ vm.queryData.showing }} of {{ ::vm.queryData.results }} properties +
+
+
+
diff --git a/onsenui2/www/res/.pgbomit b/onsenui2/www/res/.pgbomit new file mode 100644 index 00000000..e69de29b diff --git a/onsenui2/www/res/icon/android/drawable-hdpi-icon.png b/onsenui2/www/res/icon/android/drawable-hdpi-icon.png new file mode 100644 index 00000000..0f97f196 Binary files /dev/null and b/onsenui2/www/res/icon/android/drawable-hdpi-icon.png differ diff --git a/onsenui2/www/res/icon/android/drawable-ldpi-icon.png b/onsenui2/www/res/icon/android/drawable-ldpi-icon.png new file mode 100644 index 00000000..5e0b217e Binary files /dev/null and b/onsenui2/www/res/icon/android/drawable-ldpi-icon.png differ diff --git a/onsenui2/www/res/icon/android/drawable-mdpi-icon.png b/onsenui2/www/res/icon/android/drawable-mdpi-icon.png new file mode 100644 index 00000000..27cf9853 Binary files /dev/null and b/onsenui2/www/res/icon/android/drawable-mdpi-icon.png differ diff --git a/onsenui2/www/res/icon/android/drawable-xhdpi-icon.png b/onsenui2/www/res/icon/android/drawable-xhdpi-icon.png new file mode 100644 index 00000000..918c4ab9 Binary files /dev/null and b/onsenui2/www/res/icon/android/drawable-xhdpi-icon.png differ diff --git a/onsenui2/www/res/icon/android/drawable-xxhdpi-icon.png b/onsenui2/www/res/icon/android/drawable-xxhdpi-icon.png new file mode 100644 index 00000000..5ab972c5 Binary files /dev/null and b/onsenui2/www/res/icon/android/drawable-xxhdpi-icon.png differ diff --git a/onsenui2/www/res/icon/android/drawable-xxxhdpi-icon.png b/onsenui2/www/res/icon/android/drawable-xxxhdpi-icon.png new file mode 100644 index 00000000..75f7fbf5 Binary files /dev/null and b/onsenui2/www/res/icon/android/drawable-xxxhdpi-icon.png differ diff --git a/onsenui2/www/res/icon/ios/icon-40.png b/onsenui2/www/res/icon/ios/icon-40.png new file mode 100644 index 00000000..c772f33d Binary files /dev/null and b/onsenui2/www/res/icon/ios/icon-40.png differ diff --git a/onsenui2/www/res/icon/ios/icon-40@2x.png b/onsenui2/www/res/icon/ios/icon-40@2x.png new file mode 100644 index 00000000..81e0776f Binary files /dev/null and b/onsenui2/www/res/icon/ios/icon-40@2x.png differ diff --git a/onsenui2/www/res/icon/ios/icon-50.png b/onsenui2/www/res/icon/ios/icon-50.png new file mode 100644 index 00000000..fdd150c5 Binary files /dev/null and b/onsenui2/www/res/icon/ios/icon-50.png differ diff --git a/onsenui2/www/res/icon/ios/icon-50@2x.png b/onsenui2/www/res/icon/ios/icon-50@2x.png new file mode 100644 index 00000000..fa10febc Binary files /dev/null and b/onsenui2/www/res/icon/ios/icon-50@2x.png differ diff --git a/onsenui2/www/res/icon/ios/icon-60.png b/onsenui2/www/res/icon/ios/icon-60.png new file mode 100644 index 00000000..884ee0c6 Binary files /dev/null and b/onsenui2/www/res/icon/ios/icon-60.png differ diff --git a/onsenui2/www/res/icon/ios/icon-60@2x.png b/onsenui2/www/res/icon/ios/icon-60@2x.png new file mode 100644 index 00000000..884ee0c6 Binary files /dev/null and b/onsenui2/www/res/icon/ios/icon-60@2x.png differ diff --git a/onsenui2/www/res/icon/ios/icon-60@3x.png b/onsenui2/www/res/icon/ios/icon-60@3x.png new file mode 100644 index 00000000..f8feee58 Binary files /dev/null and b/onsenui2/www/res/icon/ios/icon-60@3x.png differ diff --git a/onsenui2/www/res/icon/ios/icon-72.png b/onsenui2/www/res/icon/ios/icon-72.png new file mode 100644 index 00000000..0f97f196 Binary files /dev/null and b/onsenui2/www/res/icon/ios/icon-72.png differ diff --git a/onsenui2/www/res/icon/ios/icon-72@2x.png b/onsenui2/www/res/icon/ios/icon-72@2x.png new file mode 100644 index 00000000..5ab972c5 Binary files /dev/null and b/onsenui2/www/res/icon/ios/icon-72@2x.png differ diff --git a/onsenui2/www/res/icon/ios/icon-76.png b/onsenui2/www/res/icon/ios/icon-76.png new file mode 100644 index 00000000..352c0f64 Binary files /dev/null and b/onsenui2/www/res/icon/ios/icon-76.png differ diff --git a/onsenui2/www/res/icon/ios/icon-76@2x.png b/onsenui2/www/res/icon/ios/icon-76@2x.png new file mode 100644 index 00000000..f9c77f3d Binary files /dev/null and b/onsenui2/www/res/icon/ios/icon-76@2x.png differ diff --git a/onsenui2/www/res/icon/ios/icon-small.png b/onsenui2/www/res/icon/ios/icon-small.png new file mode 100644 index 00000000..0fe3536a Binary files /dev/null and b/onsenui2/www/res/icon/ios/icon-small.png differ diff --git a/onsenui2/www/res/icon/ios/icon-small@2x.png b/onsenui2/www/res/icon/ios/icon-small@2x.png new file mode 100644 index 00000000..cec63e0d Binary files /dev/null and b/onsenui2/www/res/icon/ios/icon-small@2x.png differ diff --git a/onsenui2/www/res/icon/ios/icon-small@3x.png b/onsenui2/www/res/icon/ios/icon-small@3x.png new file mode 100644 index 00000000..b5ba8a72 Binary files /dev/null and b/onsenui2/www/res/icon/ios/icon-small@3x.png differ diff --git a/onsenui2/www/res/icon/ios/icon.png b/onsenui2/www/res/icon/ios/icon.png new file mode 100644 index 00000000..2cb89282 Binary files /dev/null and b/onsenui2/www/res/icon/ios/icon.png differ diff --git a/onsenui2/www/res/icon/ios/icon@2x.png b/onsenui2/www/res/icon/ios/icon@2x.png new file mode 100644 index 00000000..224a0cf0 Binary files /dev/null and b/onsenui2/www/res/icon/ios/icon@2x.png differ diff --git a/onsenui2/www/res/screen/android/drawable-land-hdpi-screen.png b/onsenui2/www/res/screen/android/drawable-land-hdpi-screen.png new file mode 100644 index 00000000..d1849f31 Binary files /dev/null and b/onsenui2/www/res/screen/android/drawable-land-hdpi-screen.png differ diff --git a/onsenui2/www/res/screen/android/drawable-land-ldpi-screen.png b/onsenui2/www/res/screen/android/drawable-land-ldpi-screen.png new file mode 100644 index 00000000..59e16da8 Binary files /dev/null and b/onsenui2/www/res/screen/android/drawable-land-ldpi-screen.png differ diff --git a/onsenui2/www/res/screen/android/drawable-land-mdpi-screen.png b/onsenui2/www/res/screen/android/drawable-land-mdpi-screen.png new file mode 100644 index 00000000..9b66b68c Binary files /dev/null and b/onsenui2/www/res/screen/android/drawable-land-mdpi-screen.png differ diff --git a/onsenui2/www/res/screen/android/drawable-land-xhdpi-screen.png b/onsenui2/www/res/screen/android/drawable-land-xhdpi-screen.png new file mode 100644 index 00000000..7daceb7d Binary files /dev/null and b/onsenui2/www/res/screen/android/drawable-land-xhdpi-screen.png differ diff --git a/onsenui2/www/res/screen/android/drawable-land-xxhdpi-screen.png b/onsenui2/www/res/screen/android/drawable-land-xxhdpi-screen.png new file mode 100644 index 00000000..0d540e8b Binary files /dev/null and b/onsenui2/www/res/screen/android/drawable-land-xxhdpi-screen.png differ diff --git a/onsenui2/www/res/screen/android/drawable-land-xxxhdpi-screen.png b/onsenui2/www/res/screen/android/drawable-land-xxxhdpi-screen.png new file mode 100644 index 00000000..8f83bf21 Binary files /dev/null and b/onsenui2/www/res/screen/android/drawable-land-xxxhdpi-screen.png differ diff --git a/onsenui2/www/res/screen/android/drawable-port-hdpi-screen.png b/onsenui2/www/res/screen/android/drawable-port-hdpi-screen.png new file mode 100644 index 00000000..095af24c Binary files /dev/null and b/onsenui2/www/res/screen/android/drawable-port-hdpi-screen.png differ diff --git a/onsenui2/www/res/screen/android/drawable-port-ldpi-screen.png b/onsenui2/www/res/screen/android/drawable-port-ldpi-screen.png new file mode 100644 index 00000000..fef955ac Binary files /dev/null and b/onsenui2/www/res/screen/android/drawable-port-ldpi-screen.png differ diff --git a/onsenui2/www/res/screen/android/drawable-port-mdpi-screen.png b/onsenui2/www/res/screen/android/drawable-port-mdpi-screen.png new file mode 100644 index 00000000..29cfe72c Binary files /dev/null and b/onsenui2/www/res/screen/android/drawable-port-mdpi-screen.png differ diff --git a/onsenui2/www/res/screen/android/drawable-port-xhdpi-screen.png b/onsenui2/www/res/screen/android/drawable-port-xhdpi-screen.png new file mode 100644 index 00000000..83e1d234 Binary files /dev/null and b/onsenui2/www/res/screen/android/drawable-port-xhdpi-screen.png differ diff --git a/onsenui2/www/res/screen/android/drawable-port-xxhdpi-screen.png b/onsenui2/www/res/screen/android/drawable-port-xxhdpi-screen.png new file mode 100644 index 00000000..f0251fc5 Binary files /dev/null and b/onsenui2/www/res/screen/android/drawable-port-xxhdpi-screen.png differ diff --git a/onsenui2/www/res/screen/android/drawable-port-xxxhdpi-screen.png b/onsenui2/www/res/screen/android/drawable-port-xxxhdpi-screen.png new file mode 100644 index 00000000..cb2fc340 Binary files /dev/null and b/onsenui2/www/res/screen/android/drawable-port-xxxhdpi-screen.png differ diff --git a/onsenui2/www/res/screen/ios/Default-568h@2x~iphone.png b/onsenui2/www/res/screen/ios/Default-568h@2x~iphone.png new file mode 100644 index 00000000..3b05e95e Binary files /dev/null and b/onsenui2/www/res/screen/ios/Default-568h@2x~iphone.png differ diff --git a/onsenui2/www/res/screen/ios/Default-667h.png b/onsenui2/www/res/screen/ios/Default-667h.png new file mode 100644 index 00000000..7b30b52e Binary files /dev/null and b/onsenui2/www/res/screen/ios/Default-667h.png differ diff --git a/onsenui2/www/res/screen/ios/Default-736h.png b/onsenui2/www/res/screen/ios/Default-736h.png new file mode 100644 index 00000000..8468d689 Binary files /dev/null and b/onsenui2/www/res/screen/ios/Default-736h.png differ diff --git a/onsenui2/www/res/screen/ios/Default-Landscape-736h.png b/onsenui2/www/res/screen/ios/Default-Landscape-736h.png new file mode 100644 index 00000000..5d7c7aa4 Binary files /dev/null and b/onsenui2/www/res/screen/ios/Default-Landscape-736h.png differ diff --git a/onsenui2/www/res/screen/ios/Default-Landscape@2x~ipad.png b/onsenui2/www/res/screen/ios/Default-Landscape@2x~ipad.png new file mode 100644 index 00000000..a4528764 Binary files /dev/null and b/onsenui2/www/res/screen/ios/Default-Landscape@2x~ipad.png differ diff --git a/onsenui2/www/res/screen/ios/Default-Landscape~ipad.png b/onsenui2/www/res/screen/ios/Default-Landscape~ipad.png new file mode 100644 index 00000000..652b5652 Binary files /dev/null and b/onsenui2/www/res/screen/ios/Default-Landscape~ipad.png differ diff --git a/onsenui2/www/res/screen/ios/Default-Portrait@2x~ipad.png b/onsenui2/www/res/screen/ios/Default-Portrait@2x~ipad.png new file mode 100644 index 00000000..6be05a54 Binary files /dev/null and b/onsenui2/www/res/screen/ios/Default-Portrait@2x~ipad.png differ diff --git a/onsenui2/www/res/screen/ios/Default-Portrait~ipad.png b/onsenui2/www/res/screen/ios/Default-Portrait~ipad.png new file mode 100644 index 00000000..0d0cd48c Binary files /dev/null and b/onsenui2/www/res/screen/ios/Default-Portrait~ipad.png differ diff --git a/onsenui2/www/res/screen/ios/Default@2x~iphone.png b/onsenui2/www/res/screen/ios/Default@2x~iphone.png new file mode 100644 index 00000000..47af72ce Binary files /dev/null and b/onsenui2/www/res/screen/ios/Default@2x~iphone.png differ diff --git a/onsenui2/www/res/screen/ios/Default~iphone.png b/onsenui2/www/res/screen/ios/Default~iphone.png new file mode 100644 index 00000000..29cfe72c Binary files /dev/null and b/onsenui2/www/res/screen/ios/Default~iphone.png differ diff --git a/onsenui2/www/services/favourites.service.js b/onsenui2/www/services/favourites.service.js new file mode 100644 index 00000000..b04751df --- /dev/null +++ b/onsenui2/www/services/favourites.service.js @@ -0,0 +1,142 @@ +/** + * Service for storing, retrieve and delete favourites properties + */ +(function(app){ + 'use strict'; + + // add service to app + app.factory('FavouritesService', FavouritesService); + + // dependencies of service + FavouritesService.$inject = ['$log', '$q', '_', 'localforage', '$window'] + + // service + function FavouritesService($log, $q, _, localforage, $window) { + + // local copy of favourites + var favourites = null; + + // public interface + var service = { + getAll: getFavourites, + store: storeFav, + remove: removeFav, + isFav: isFav + }; + + return service; + + ////////////////////////////// + + /** + * retrieve stored favourites and cache them in service local variable + * + * @return Promise + */ + function init() { + return localforage.getItem('favouriteProperties') + .then(initComplete) + .catch(initFailed); + + function initComplete(value) { + favourites = value; + return favourites; + } + + function initFailed(error) { + $log.error(error); + } + } + + /** + * Get favourites from local variable or storage + * + * @return Promise + */ + function getFavourites() { + if (favourites !== null) { + return $q.resolve(favourites); + } else { + return init(); + } + } + + /** + * Generates key from property + * + * @param Object property + * @return String Generated key + */ + function getPropertyKey(property) { + return $window.btoa(property.lister_url); + } + + /** + * Check if a property is favourite + * + * @param Object property + * @return Promise + */ + function isFav(property) { + return getFavourites().then(isFavComplete) + .catch(isFavFailed); + + function isFavComplete(favourites) { + return _.findIndex(favourites, ['key', getPropertyKey(property)]) > -1; + } + + function isFavFailed(error) { + $log.error(error); + return false; + } + } + + /** + * Stores a property in favourites list + * + * @param Object property + */ + function storeFav(property) { + + property.key = getPropertyKey(property); + + if (favourites === null || _.isEmpty(favourites)) { + favourites = [property]; + } + else { + // try to find term + var index = _.findIndex(favourites, ['key', property.key]); + + // update date or insert + if (index > -1) { + favourites[index] = property; + } + else { + favourites.push(property); + } + } + + // update storage + localforage.setItem('favouriteProperties', favourites); + } + + /** + * Remove a property from favourites storage + * + * @param Object property + */ + function removeFav(property) { + + // try to find property + var index = _.findIndex(favourites, ['key', getPropertyKey(property)]); + + // delete element from favourites + if (index > -1) { + _.pull(favourites, favourites[index]); + } + + // update storage + localforage.setItem('favouriteProperties', favourites); + } + } +})(window.app); \ No newline at end of file diff --git a/onsenui2/www/services/localforage.service.js b/onsenui2/www/services/localforage.service.js new file mode 100644 index 00000000..495bcae2 --- /dev/null +++ b/onsenui2/www/services/localforage.service.js @@ -0,0 +1,13 @@ +(function(app){ + 'use strict'; + + // Register factory + app.factory('localforage', LocalForageFactory); + + LocalForageFactory.$inject = ['$window']; + + function LocalForageFactory($window) { + return $window.localforage; + } + +})(window.app); \ No newline at end of file diff --git a/onsenui2/www/services/lodash.service.js b/onsenui2/www/services/lodash.service.js new file mode 100644 index 00000000..0594a580 --- /dev/null +++ b/onsenui2/www/services/lodash.service.js @@ -0,0 +1,13 @@ +(function(app){ + 'use strict'; + + // Register factory + app.factory('_', LodashFactory); + + LodashFactory.$inject = ['$window']; + + function LodashFactory($window) { + return $window._; + } + +})(window.app); \ No newline at end of file diff --git a/onsenui2/www/services/properties.service.js b/onsenui2/www/services/properties.service.js new file mode 100644 index 00000000..ec759429 --- /dev/null +++ b/onsenui2/www/services/properties.service.js @@ -0,0 +1,244 @@ +/** + * Service for accesing Property API + */ +(function(app){ + 'use strict'; + + // add service to app + app.factory('PropertiesService', PropertiesService); + + // dependencies of service + PropertiesService.$inject = ['$log', '$http', '$window', '$q', 'PROPERTY_API'] + + // service + function PropertiesService($log, $http, $window, $q, PROPERTY_API) { + var lastQueryResults = {}; + var searchTerm = ''; + var searchCoordinates = null; + + // public + var service = { + searchByTerm: searchByTerm, + searchByPosition: searchByPosition, + loadMore: loadMore, + getLastQueryResults: getLastQueryResults + }; + + return service; + ////////////////////////////// + + /** + * Compose url for term based searches + * + * @param string term Term to search + * @param int page Page number + * @return string URL + */ + function composeTermUrl(term, page) { + return PROPERTY_API.baseUrl + '&page=' + page + '&place_name=' + term; + } + + /** + * Compose url for location based searches + * + * @param Object coordinates Geolocation object + * @param int page Page number + * @return string URL + */ + function composePositionUrl(coordinates, page) { + return PROPERTY_API.baseUrl + '&page=' + page + + '¢re_point=' + coordinates.lat + ',' + coordinates.lng; + } + + /** + * Perform a search of properties by term + * + * @param string term + * @return Promise + */ + function searchByTerm(term) { + searchCoordinates = null; + searchTerm = term; + + return $http.get(composeTermUrl(term, 1), {timeout: 5000}) + .then(searchByTermComplete) + .catch(searchByTermFailed); + + function searchByTermComplete(response) { + return processResponse(response.data); + } + + function searchByTermFailed(error) { + return processFailedResponse(error, PROPERTY_API.error.messages.GENERIC_ERROR); + } + } + + /** + * Perform search by Position + * + * @return Promise + */ + function searchByPosition() { + searchCoordinates = null; + searchTerm = ''; + + return $q(function(resolve, reject){ + + // try to get current position + $window.navigator.geolocation + .getCurrentPosition(positionSuccess, positionError, { enableHighAccuracy: true, timeout: 5000 }); + + function positionSuccess(position) { + searchCoordinates = { + lat: position.coords.latitude, + lng: position.coords.longitude + }; + + $http.get(composePositionUrl(searchCoordinates, 1), {timeout: 5000}) + .then(searchByPositionComplete) + .catch(positionError); + + function searchByPositionComplete(response) { + var info = processResponse(response.data); + resolve(info); + } + } + + function positionError(error) { + var msg = ''; + + if (error.code === error.PERMISSION_DENIED) { + msg = PROPERTY_API.error.messages.LOCATION_DISABLED; + } else if (error.code === error.POSITION_UNAVAILABLE) { + msg = PROPERTY_API.error.messages.LOCATION_UNAVAILABLE; + } + else { + msg = PROPERTY_API.error.messages.GENERIC_ERROR + } + + var err = processFailedResponse(error, msg); + reject(err); + } + }); + } + + /** + * Process successfull response from API + * + * @param Object data API response + * @return Object Procesed results + */ + function processResponse(data) { + + switch (data.response.application_response_code) { + // OK codes + case '100': + case '101': + case '110': + // Some properties found + if (data.response.listings.length) { + lastQueryResults = { + status: PROPERTY_API.status.SUCCESS, + message: '', + searchTerm: searchTerm, + searchCoordinates: searchCoordinates, + page: data.response.page, + pages: data.response.total_pages + 1, + showing: data.response.listings.length, + results: data.response.total_results, + properties: data.response.listings + }; + } + // No properties found + else { + lastQueryResults = { + status: PROPERTY_API.status.ERROR, + message: 'There were no properties found for the given location.', + searchTerm: searchTerm, + searchCoordinates: searchCoordinates + }; + } + + break; + // Ambiguous codes + case '200': + case '202': + lastQueryResults = { + status: PROPERTY_API.status.AMBIGUOUS, + message: '', + searchCoordinates: searchCoordinates, + searchTerm: searchTerm, + locations: data.response.locations + }; + break; + // everything else is considered as error + default: + lastQueryResults = processFailedResponse(null, PROPERTY_API.error.messages.GENERIC_ERROR); + } // switch + + return lastQueryResults; + } + + /** + * Process erroneous responses from API + * + * @param string error Browser description of error + * @param string msg Message shown to user + * @return Object + */ + function processFailedResponse(error, msg) { + $log.error(error); + + lastQueryResults = { + status: PROPERTY_API.status.ERROR, // error + message: msg, + searchCoordinates: searchCoordinates, + searchTerm: searchTerm + }; + + return lastQueryResults; + } + + /** + * Use last query parameter to get more results by asking for next page. + * + * @return Promise + */ + function loadMore() { + + // Term based search + if (lastQueryResults.searchCoordinates === null) { + return $http.get(composeTermUrl(lastQueryResults.searchTerm, lastQueryResults.page +1)) + .then(loadMoreComplete) + .catch(loadMoreFailed); + } + // Location based search + else { + return $http.get(composePositionUrl(lastQueryResults.searchCoordinates, lastQueryResults.page +1)) + .then(loadMoreComplete) + .catch(loadMoreFailed); + } + + function loadMoreComplete(response) { + lastQueryResults.page++; + lastQueryResults.properties = lastQueryResults.properties.concat(response.data.response.listings); + lastQueryResults.showing = lastQueryResults.properties.length; + + return response.data; + } + + function loadMoreFailed(error) { + return processFailedResponse(error, PROPERTY_API.error.messages.GENERIC_ERROR); + } + } + + /** + * Return last results obtained + * + * @return Object + */ + function getLastQueryResults() { + return lastQueryResults; + } + } +})(window.app); \ No newline at end of file diff --git a/onsenui2/www/services/recent-searches.service.js b/onsenui2/www/services/recent-searches.service.js new file mode 100644 index 00000000..d27ad117 --- /dev/null +++ b/onsenui2/www/services/recent-searches.service.js @@ -0,0 +1,100 @@ +/** + * Service for storing and retrieving recent searches + */ +(function(app){ + 'use strict'; + + // add service to app + app.factory('RecentSearchesService', RecentSearchesService); + + // dependencies of service + RecentSearchesService.$inject = ['$log', '$q', '_', 'localforage', '$timeout'] + + // service + function RecentSearchesService($log, $q, _, localforage) { + // local copy of storage + var searches = null; + + // public + var service = { + get: getRecentSearches, + store: storeSearch + }; + + return service; + + ////////////////////////////// + + /** + * retrieve stored recent searches and cache them in service local variable + * + * @return Promise + */ + function init() { + return localforage.getItem('recentSearches') + .then(initComplete) + .catch(initFailed); + + function initComplete(value) { + searches = value; + return searches; + } + + function initFailed(error) { + $log.error(error); + } + } + + /** + * Get recent searches + * + * @return Promise + */ + function getRecentSearches() { + if (searches !== null) { + return $q.resolve(searches); + } else { + return init(); + } + } + + /** + * Store recent search + * + * @param Object searchInfo Search to be stored + */ + function storeSearch(searchInfo) { + var search = { + term: searchInfo.term, + results: searchInfo.results, + date: new Date().toISOString() + } + + // no searches stored + if (searches === null) { + searches = [search]; + } + else { + // try to find term + var index = _.findIndex(searches, ['term', search.term]); + + // update date or insert + if (index > -1) { + searches[index] = search; + } + else { + searches.push(search); + } + + // order + searches = _.reverse(_.sortBy(searches, ['date'])); + + // only 6 elements + searches = _.slice(searches, 0, 6); + } + + // persist storage + localforage.setItem('recentSearches', searches); + } + } +})(window.app); \ No newline at end of file