├── .gitignore ├── .idea └── vcs.xml ├── .npmignore ├── LICENSE ├── README.md ├── config.xml ├── hooks └── README.md ├── package-lock.json ├── package.json ├── res ├── drawable │ └── notification_icon.png ├── icon.png ├── ios │ ├── icon-1024.png │ ├── icon-167.png │ ├── icon-60.png │ ├── icon-60@2x.png │ ├── icon-60@3x.png │ ├── icon-72.png │ ├── icon-72@2x.png │ ├── icon-76.png │ ├── icon-76@2x.png │ ├── icon-83.5@2x.png │ ├── icon-small-40.png │ ├── icon-small-40@2x.png │ ├── icon-small-40@3x.png │ ├── icon-small-50.png │ ├── icon-small-50@2x.png │ ├── icon-small.png │ ├── icon-small@2x.png │ ├── icon-small@3x.png │ ├── icon.png │ └── icon@2x.png └── values │ └── colors.xml └── www ├── css ├── app.css └── editor.css ├── img ├── agenda.svg ├── assessment.svg ├── calendar.svg ├── cartoon.svg ├── course.svg ├── default.svg ├── document │ ├── border-title.png │ ├── hr-1.png │ └── hr-2.png ├── documents.svg ├── down.svg ├── drawing-pin.svg ├── dropbox.svg ├── folder_audio.svg ├── folder_chat.svg ├── folder_document.svg ├── folder_flash.svg ├── folder_gallery.svg ├── folder_images.svg ├── folder_learningpath.svg ├── folder_users.svg ├── folder_video.svg ├── forum.svg ├── icon.png ├── info.svg ├── laptop.svg ├── learnpath.svg ├── logo-chamilo.svg ├── logo.png ├── notebook.svg ├── objective.svg ├── scorms.svg ├── session_default.png ├── strategy.svg ├── teacher.svg ├── topics.svg ├── user.svg ├── valves.svg └── wizard.svg ├── index.html ├── js ├── main.js └── require-setup.js ├── src ├── app.js ├── collection │ ├── course-announcements.js │ ├── course-descriptions.js │ ├── course-documents.js │ ├── course-events.js │ ├── course-forumcategories.js │ ├── course-lpcategories.js │ ├── course-notebooks.js │ ├── courses.js │ ├── messages.js │ └── sessions.js ├── database.js ├── model │ ├── campus.js │ ├── course-announcement.js │ ├── course-description.js │ ├── course-document.js │ ├── course-event.js │ ├── course-forum.js │ ├── course-forumcategory.js │ ├── course-forumpost.js │ ├── course-forumthread.js │ ├── course-lp.js │ ├── course-lpcategory.js │ ├── course-notebook.js │ ├── course.js │ ├── message.js │ ├── session.js │ ├── sessioncategory.js │ ├── spinner.js │ └── user.js ├── nls │ ├── de │ │ └── lang.js │ ├── es │ │ └── lang.js │ ├── fr │ │ └── lang.js │ ├── lang.js │ └── root │ │ └── lang.js ├── template │ ├── course-agenda.html │ ├── course-announcement-item.html │ ├── course-announcement.html │ ├── course-announcements.html │ ├── course-description-content.html │ ├── course-description-title.html │ ├── course-descriptions.html │ ├── course-document.html │ ├── course-documents.html │ ├── course-event.html │ ├── course-forum.html │ ├── course-forumcategories.html │ ├── course-forumcategory.html │ ├── course-forumpost-item.html │ ├── course-forumthread.html │ ├── course-home.html │ ├── course-lp-item.html │ ├── course-lpcategories.html │ ├── course-lpcategory-item.html │ ├── course-notebook.html │ ├── course-notebooks.html │ ├── course.html │ ├── home.html │ ├── inbox-message.html │ ├── inbox.html │ ├── login.html │ ├── logout.html │ ├── message.html │ ├── session-category.html │ ├── spinner.html │ └── user-profile.html └── view │ ├── course-agenda.js │ ├── course-announcement-item.js │ ├── course-announcement.js │ ├── course-announcements.js │ ├── course-description-content.js │ ├── course-description-title.js │ ├── course-descriptions.js │ ├── course-document.js │ ├── course-documents.js │ ├── course-event.js │ ├── course-forum.js │ ├── course-forumcategories.js │ ├── course-forumcategory.js │ ├── course-forumpost-item.js │ ├── course-forumthread.js │ ├── course-home.js │ ├── course-lp-item.js │ ├── course-lpcategories.js │ ├── course-lpcategory-item.js │ ├── course-notebook.js │ ├── course-notebooks.js │ ├── course.js │ ├── home.js │ ├── inbox-message.js │ ├── inbox.js │ ├── login.js │ ├── logout.js │ ├── message.js │ ├── session-category.js │ ├── spinner.js │ └── user-profile.js └── vendor ├── backbone.js └── backbone-min.js ├── bootstrap ├── css │ ├── bootstrap-theme.min.css │ ├── bootstrap.min.css │ └── roboto.css ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ ├── glyphicons-halflings-regular.woff2 │ ├── roboto-cyrillic-bold.woff2 │ ├── roboto-cyrillic-ext-bold.woff2 │ ├── roboto-cyrillic-ext-light.woff2 │ ├── roboto-cyrillic-ext-medium.woff2 │ ├── roboto-cyrillic-ext-regular.woff2 │ ├── roboto-cyrillic-light.woff2 │ ├── roboto-cyrillic-medium.woff2 │ ├── roboto-cyrillic-regular.woff2 │ ├── roboto-greek-bold.woff2 │ ├── roboto-greek-ext-bold.woff2 │ ├── roboto-greek-ext-light.woff2 │ ├── roboto-greek-ext-medium.woff2 │ ├── roboto-greek-ext-regular.woff2 │ ├── roboto-greek-light.woff2 │ ├── roboto-greek-medium.woff2 │ ├── roboto-greek-regular.woff2 │ ├── roboto-latin-bold.woff2 │ ├── roboto-latin-ext-bold.woff2 │ ├── roboto-latin-ext-light.woff2 │ ├── roboto-latin-ext-medium.woff2 │ ├── roboto-latin-ext-regular.woff2 │ ├── roboto-latin-light.woff2 │ ├── roboto-latin-medium.woff2 │ ├── roboto-latin-regular.woff2 │ ├── roboto-vietnamese-bold.woff2 │ ├── roboto-vietnamese-light.woff2 │ ├── roboto-vietnamese-medium.woff2 │ └── roboto-vietnamese-regular.woff2 └── js │ └── bootstrap.min.js ├── font-awesome ├── css │ ├── font-awesome.css │ └── font-awesome.min.css └── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ └── fontawesome-webfont.woff2 ├── jquery └── jquery.min.js ├── require-i18n └── i18n.min.js ├── require-text └── text.min.js ├── require.js └── require.min.js └── underscore.js └── underscore-min.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | /dist/ 4 | /www 5 | npm-debug.log* 6 | yarn-debug.log* 7 | yarn-error.log* 8 | 9 | # Cordova 10 | /platforms 11 | /plugins 12 | 13 | # Editor directories and files 14 | .idea 15 | .vscode 16 | *.suo 17 | *.ntvs* 18 | *.njsproj 19 | *.sln 20 | /nbproject 21 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # OS X 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Chamilo LMS mobile app 2 | ================================ 3 | 4 | > This is a Cordova mobile app([1]) to get notifications of new messages from the 5 | Chamilo LMS campus of your choice and review the content from the main course 6 | tools. 7 | 8 | The finished application should: 9 | * Allow you to connect to one or more Chamilo LMS campuses 10 | * Notify you when you have a new message on the Chamilo LMS campus(es) 11 | * Store your messages locally (but not allow you to answer just yet) 12 | * Review the principal tools for courses and sessions 13 | 14 | Spirit of this project 15 | ---------------------- 16 | 17 | This is developed as a side project and it might require a few updates to 18 | Chamilo itself for the first version to work (web services in Chamilo will have 19 | to be extended for it to work([2])). 20 | 21 | ## Development environment 22 | 23 | Clone this repository 24 | ``` 25 | git clone git@github.com:chamilo/mobile.git 26 | cd mobile 27 | ``` 28 | 29 | Add the platforms 30 | ``` 31 | cordova platform add android 32 | cordova platform add ios 33 | ``` 34 | 35 | Add the plugins (support-google-services and firebase-messaging are optionals) 36 | ``` 37 | cordova plugin add cordova-plugin-file 38 | cordova plugin add cordova-support-google-services 39 | cordova plugin add cordova-plugin-firebase-messaging 40 | ``` 41 | 42 | Build the application for the platforms added 43 | ``` 44 | cordova build android 45 | cordoba build ios 46 | ``` 47 | 48 | Execute on an Android device 49 | 50 | ``` 51 | cordova run android 52 | ``` 53 | 54 | ### Enable push notification from Chamilo 55 | 56 | #### Customizing the app 57 | 58 | You need configure your project and app in Google's Firebase Console. And download the config files 59 | according to the platforms (`google-services.json` Android and @GoogleService-Info.plist@ for iOS). See the 60 | [README](https://github.com/chemerisuk/cordova-support-google-services/blob/master/README.md#installation) file 61 | for the Google Services plugin. 62 | 63 | Edit the `config.xml` file: 64 | ```xml 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | ``` 74 | 75 | #### Configuring Chamilo LMS portal 76 | 77 | If you'd like to use push notifications (only tested on Android and only available from Chamilo v1.10.4), you will have to enable and set the following parameters in your Chamilo server's: 78 | 79 | **For Chamilo v1.10.4** 80 | ``` 81 | //Allow send a push notification when an email are sent 82 | //$_configuration['messaging_allow_send_push_notification'] = 'true'; 83 | //Project number in the Google Developer Console 84 | //$_configuration['messaging_gdc_project_number'] = ''; 85 | //Api Key in the Google Developer Console 86 | //$_configuration['messaging_gdc_api_key'] = ''; 87 | ``` 88 | 89 | **For Chamilo v1.11.x** 90 | Fill the settings about the Web Services category in Configuration Settings (in administration page) 91 | 92 | Contributing 93 | ------------ 94 | 95 | This development is taken as a side-project, so it might advance slowly at 96 | first. Please feel free to send Pull Requests through Github, we will review 97 | and include them if we feel they're bringing value. 98 | 99 | Coding conventions are not clear at this time as we're mainly PHP developers 100 | trying out HTML+JS stuff to generate a mobile app, but we have good grounds with 101 | PSR-1 and PSR-2, so we will not accept ugly code, but we will comment on it. 102 | 103 | [1]: http://beeznest.wordpress.com/2014/09/05/quick-phonegap-setup-on-ubuntu/ 104 | [2]: https://support.chamilo.org/issues/7402 105 | -------------------------------------------------------------------------------- /config.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | Chamilo Messaging 6 | 7 | The Messaging app for Chamilo LMS is a multi-mobile-OS application that allows you to get your messages from Chamilo LMS's social network. 8 | 9 | 10 | BeezNest 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 | 28 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /hooks/README.md: -------------------------------------------------------------------------------- 1 | 21 | # Cordova Hooks 22 | 23 | Cordova Hooks represent special scripts which could be added by application and plugin developers or even by your own build system to customize cordova commands. Hook scripts could be defined by adding them to the special predefined folder (`/hooks`) or via configuration files (`config.xml` and `plugin.xml`) and run serially in the following order: 24 | * Application hooks from `/hooks`; 25 | * Application hooks from `config.xml`; 26 | * Plugin hooks from `plugins/.../plugin.xml`. 27 | 28 | __Remember__: Make your scripts executable. 29 | 30 | __Note__: `.cordova/hooks` directory is also supported for backward compatibility, but we don't recommend using it as it is deprecated. 31 | 32 | ## Supported hook types 33 | The following hook types are supported: 34 | 35 | after_build/ 36 | after_compile/ 37 | after_docs/ 38 | after_emulate/ 39 | after_platform_add/ 40 | after_platform_rm/ 41 | after_platform_ls/ 42 | after_plugin_add/ 43 | after_plugin_ls/ 44 | after_plugin_rm/ 45 | after_plugin_search/ 46 | after_plugin_install/ <-- Plugin hooks defined in plugin.xml are executed exclusively for a plugin being installed 47 | after_prepare/ 48 | after_run/ 49 | after_serve/ 50 | before_build/ 51 | before_compile/ 52 | before_docs/ 53 | before_emulate/ 54 | before_platform_add/ 55 | before_platform_rm/ 56 | before_platform_ls/ 57 | before_plugin_add/ 58 | before_plugin_ls/ 59 | before_plugin_rm/ 60 | before_plugin_search/ 61 | before_plugin_install/ <-- Plugin hooks defined in plugin.xml are executed exclusively for a plugin being installed 62 | before_plugin_uninstall/ <-- Plugin hooks defined in plugin.xml are executed exclusively for a plugin being uninstalled 63 | before_prepare/ 64 | before_run/ 65 | before_serve/ 66 | pre_package/ <-- Windows 8 and Windows Phone only. 67 | 68 | ## Ways to define hooks 69 | ### Via '/hooks' directory 70 | To execute custom action when corresponding hook type is fired, use hook type as a name for a subfolder inside 'hooks' directory and place you script file here, for example: 71 | 72 | # script file will be automatically executed after each build 73 | hooks/after_build/after_build_custom_action.js 74 | 75 | 76 | ### Config.xml 77 | 78 | Hooks can be defined in project's `config.xml` using `` elements, for example: 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | ... 89 | 90 | 91 | 92 | 93 | 94 | 95 | ... 96 | 97 | 98 | ### Plugin hooks (plugin.xml) 99 | 100 | As a plugin developer you can define hook scripts using `` elements in a `plugin.xml` like that: 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | ... 109 | 110 | 111 | `before_plugin_install`, `after_plugin_install`, `before_plugin_uninstall` plugin hooks will be fired exclusively for the plugin being installed/uninstalled. 112 | 113 | ## Script Interface 114 | 115 | ### Javascript 116 | 117 | If you are writing hooks in Javascript you should use the following module definition: 118 | ```javascript 119 | module.exports = function(context) { 120 | ... 121 | } 122 | ``` 123 | 124 | You can make your scipts async using Q: 125 | ```javascript 126 | module.exports = function(context) { 127 | var Q = context.requireCordovaModule('q'); 128 | var deferral = new Q.defer(); 129 | 130 | setTimeout(function(){ 131 | console.log('hook.js>> end'); 132 | deferral.resolve(); 133 | }, 1000); 134 | 135 | return deferral.promise; 136 | } 137 | ``` 138 | 139 | `context` object contains hook type, executed script full path, hook options, command-line arguments passed to Cordova and top-level "cordova" object: 140 | ```json 141 | { 142 | "hook": "before_plugin_install", 143 | "scriptLocation": "c:\\script\\full\\path\\appBeforePluginInstall.js", 144 | "cmdLine": "The\\exact\\command\\cordova\\run\\with arguments", 145 | "opts": { 146 | "projectRoot":"C:\\path\\to\\the\\project", 147 | "cordova": { 148 | "platforms": ["wp8"], 149 | "plugins": ["com.plugin.withhooks"], 150 | "version": "0.21.7-dev" 151 | }, 152 | "plugin": { 153 | "id": "com.plugin.withhooks", 154 | "pluginInfo": { 155 | ... 156 | }, 157 | "platform": "wp8", 158 | "dir": "C:\\path\\to\\the\\project\\plugins\\com.plugin.withhooks" 159 | } 160 | }, 161 | "cordova": {...} 162 | } 163 | 164 | ``` 165 | `context.opts.plugin` object will only be passed to plugin hooks scripts. 166 | 167 | You can also require additional Cordova modules in your script using `context.requireCordovaModule` in the following way: 168 | ```javascript 169 | var Q = context.requireCordovaModule('q'); 170 | ``` 171 | 172 | __Note__: new module loader script interface is used for the `.js` files defined via `config.xml` or `plugin.xml` only. 173 | For compatibility reasons hook files specified via `/hooks` folders are run via Node child_process spawn, see 'Non-javascript' section below. 174 | 175 | ### Non-javascript 176 | 177 | Non-javascript scripts are run via Node child_process spawn from the project's root directory and have the root directory passes as the first argument. All other options are passed to the script using environment variables: 178 | 179 | * CORDOVA_VERSION - The version of the Cordova-CLI. 180 | * CORDOVA_PLATFORMS - Comma separated list of platforms that the command applies to (e.g.: android, ios). 181 | * CORDOVA_PLUGINS - Comma separated list of plugin IDs that the command applies to (e.g.: org.apache.cordova.file, org.apache.cordova.file-transfer) 182 | * CORDOVA_HOOK - Path to the hook that is being executed. 183 | * CORDOVA_CMDLINE - The exact command-line arguments passed to cordova (e.g.: cordova run ios --emulate) 184 | 185 | If a script returns a non-zero exit code, then the parent cordova command will be aborted. 186 | 187 | ## Writing hooks 188 | 189 | We highly recommend writing your hooks using Node.js so that they are 190 | cross-platform. Some good examples are shown here: 191 | 192 | [http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/](http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/) 193 | 194 | Also, note that even if you are working on Windows, and in case your hook scripts aren't bat files (which is recommended, if you want your scripts to work in non-Windows operating systems) Cordova CLI will expect a shebang line as the first line for it to know the interpreter it needs to use to launch the script. The shebang line should match the following example: 195 | 196 | #!/usr/bin/env [name_of_interpreter_executable] 197 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "org.chamilo.messaging", 3 | "displayName": "Chamilo Messaging", 4 | "version": "2.2.5", 5 | "description": "The Messaging app for Chamilo LMS is a multi-mobile-OS application that allows you to get your messages from Chamilo LMS's social network.", 6 | "main": "index.js", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "BeezNest ", 11 | "license": "AGPL-3.0", 12 | "dependencies": { 13 | "cordova-android": "^8.1.0", 14 | "cordova-ios": "^5.1.0", 15 | "cordova-plugin-file": "^6.0.2", 16 | "cordova-plugin-firebase-messaging": "^4.0.1", 17 | "cordova-support-android-plugin": "^1.0.1", 18 | "cordova-support-google-services": "^1.3.2" 19 | }, 20 | "cordova": { 21 | "plugins": { 22 | "cordova-plugin-whitelist": {}, 23 | "cordova-plugin-file": {}, 24 | "cordova-support-google-services": {}, 25 | "cordova-plugin-firebase-messaging": { 26 | "FIREBASE_ANALYTICS_VERSION": "17.2.+", 27 | "FIREBASE_MESSAGING_VERSION": "20.0.+", 28 | "ANDROIDX_CORE_VERSION": "1.0.+" 29 | } 30 | }, 31 | "platforms": [ 32 | "android", 33 | "ios" 34 | ] 35 | }, 36 | "devDependencies": { 37 | "cordova-plugin-whitelist": "1" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /res/drawable/notification_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/drawable/notification_icon.png -------------------------------------------------------------------------------- /res/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/icon.png -------------------------------------------------------------------------------- /res/ios/icon-1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon-1024.png -------------------------------------------------------------------------------- /res/ios/icon-167.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon-167.png -------------------------------------------------------------------------------- /res/ios/icon-60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon-60.png -------------------------------------------------------------------------------- /res/ios/icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon-60@2x.png -------------------------------------------------------------------------------- /res/ios/icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon-60@3x.png -------------------------------------------------------------------------------- /res/ios/icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon-72.png -------------------------------------------------------------------------------- /res/ios/icon-72@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon-72@2x.png -------------------------------------------------------------------------------- /res/ios/icon-76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon-76.png -------------------------------------------------------------------------------- /res/ios/icon-76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon-76@2x.png -------------------------------------------------------------------------------- /res/ios/icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon-83.5@2x.png -------------------------------------------------------------------------------- /res/ios/icon-small-40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon-small-40.png -------------------------------------------------------------------------------- /res/ios/icon-small-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon-small-40@2x.png -------------------------------------------------------------------------------- /res/ios/icon-small-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon-small-40@3x.png -------------------------------------------------------------------------------- /res/ios/icon-small-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon-small-50.png -------------------------------------------------------------------------------- /res/ios/icon-small-50@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon-small-50@2x.png -------------------------------------------------------------------------------- /res/ios/icon-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon-small.png -------------------------------------------------------------------------------- /res/ios/icon-small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon-small@2x.png -------------------------------------------------------------------------------- /res/ios/icon-small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon-small@3x.png -------------------------------------------------------------------------------- /res/ios/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon.png -------------------------------------------------------------------------------- /res/ios/icon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/res/ios/icon@2x.png -------------------------------------------------------------------------------- /res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #2e75a3 4 | 5 | -------------------------------------------------------------------------------- /www/css/app.css: -------------------------------------------------------------------------------- 1 | hr { 2 | margin: 10px 0; 3 | } 4 | 5 | .navbar { 6 | font-size: 20px; 7 | } 8 | .navbar button { 9 | background: transparent; 10 | border: 0; 11 | color: #EEE; 12 | float: left; 13 | margin-left: -15px; 14 | padding: 17px 15px; 15 | outline: 0 none; 16 | } 17 | .navbar button:hover, 18 | .navbar button:active { 19 | color: #DDD; 20 | outline: 0 none; 21 | } 22 | .navbar .navbar-text { 23 | color: #EEE; 24 | display: block; 25 | float: left; 26 | margin: 17px auto; 27 | overflow: hidden; 28 | text-overflow: ellipsis; 29 | white-space: nowrap; 30 | width: calc(100% - 42px); 31 | } 32 | 33 | .navbar.navbar-btbb .navbar-text { 34 | width: calc(100% - 42px - 90px); 35 | } 36 | .navbar.navbar-btbb button:not(:first-child) { 37 | margin-left: 0; 38 | } 39 | .navbar.navbar-btbb button:last-child { 40 | 41 | margin-right: -15px; 42 | } 43 | 44 | .navbar-header { 45 | margin-left: 0 !important; 46 | width: 50%; 47 | } 48 | .navbar-header button { 49 | margin: 0 0 0 -15px; 50 | } 51 | 52 | .container > .navbar-header, 53 | .container-fluid .navbar-header, 54 | .container > .navbar-collapse, 55 | .container-fluid .navbar-collapse { 56 | margin-right: -15px; 57 | } 58 | 59 | .navbar-brand { 60 | color: #FFF; 61 | } 62 | .navbar-inverse .navbar-brand{ 63 | color: #b2dbfb; 64 | display: inline-flex; 65 | width: 100%; 66 | } 67 | .navbar-inverse .navbar-brand .fa{ 68 | padding-right: 10px; 69 | } 70 | .navbar-inverse #lbl-title{ 71 | overflow: hidden; 72 | white-space: nowrap; 73 | padding: 0; 74 | text-overflow: ellipsis; 75 | width: 90%; 76 | } 77 | .navbar-inverse .navbar-brand.no-event{ 78 | display: inherit; 79 | width: auto; 80 | } 81 | .article-content { 82 | overflow-x: auto; 83 | } 84 | 85 | .word-break-all { 86 | word-break: break-all; 87 | } 88 | /* CSS PAGES */ 89 | .page-inside{ 90 | padding-top: 80px; 91 | } 92 | .page-inside .container .btn-block{ 93 | margin-bottom: 2rem; 94 | } 95 | .splash{ 96 | padding-top: 150px; 97 | } 98 | #page-login, #page-splash{ 99 | background: #01579b; 100 | background: -moz-linear-gradient(top, #01579b 0%, #2196f3 100%); 101 | background: -webkit-linear-gradient(top, #01579b 0%,#2196f3 100%); 102 | background: linear-gradient(to bottom, #01579b 0%,#2196f3 100%); 103 | bottom: 0; 104 | display: table; 105 | height: 100%; 106 | position: absolute; 107 | top: 0; 108 | width: 100%; 109 | } 110 | #page-login .container, 111 | #page-splash .container { 112 | display: table-cell; 113 | vertical-align: middle; 114 | } 115 | 116 | .my-host legend{ 117 | border: none; 118 | margin-bottom: 0; 119 | } 120 | .app-text-normal{ 121 | color: #FFFFFF; 122 | } 123 | .app-text-secundary{ 124 | color: #757575; 125 | } 126 | .app-text-primary{ 127 | color: #212121; 128 | } 129 | .app-color-accentuation{ 130 | color: #FF5722; 131 | } 132 | .app-color-primary{ 133 | color: #2196f3; 134 | } 135 | .app-color-dark{ 136 | color: #1976D2; 137 | } 138 | .app-color-primary-light{ 139 | color: #BBDEFB; 140 | } 141 | .bold{ 142 | font-weight: bold; 143 | } 144 | .description{ 145 | padding-top: 15px; 146 | padding-bottom: 15px; 147 | } 148 | .description .title{ 149 | font-size: 18px; 150 | margin: 0; 151 | } 152 | .description .code{ 153 | font-size: 12px; 154 | padding-bottom: 4px; 155 | padding-top: 4px; 156 | } 157 | .btn-reply{ 158 | color: #b2dbfb; 159 | font-size: 2rem; 160 | width: 32px; 161 | position: absolute; 162 | right: 0; 163 | top: 18px; 164 | } 165 | .navigation{ 166 | color: #b2dbfb; 167 | font-size: 2rem; 168 | width: 70px; 169 | position: absolute; 170 | right: 0; 171 | top: 15px; 172 | display: flex; 173 | text-align: right; 174 | } 175 | .navigation .navbar-brand{ 176 | padding: 5px; 177 | width: 32px; 178 | } 179 | .btn-reply:hover{ 180 | color: #FFF; 181 | } 182 | .btn-back{ 183 | color: #FFFFFF; 184 | padding-top: 15px; 185 | } 186 | .btn-back a{ 187 | color: #FFFFFF; 188 | } 189 | .btn-back a:hover, .btn-back a:focus{ 190 | text-decoration: none; 191 | } 192 | .bg-white{ 193 | background-color: white; 194 | } 195 | .navbar .title span{ 196 | margin-right: 10px; 197 | } 198 | .navbar .title{ 199 | width: 320px; 200 | text-overflow: ellipsis; 201 | white-space: nowrap; 202 | overflow: hidden; 203 | } 204 | .nav-shadow{ 205 | -webkit-box-shadow: 0px 10px 13px -10px rgba(0,0,0,0.43); 206 | -moz-box-shadow: 0px 10px 13px -10px rgba(0,0,0,0.43); 207 | box-shadow: 0px 10px 13px -10px rgba(0,0,0,0.43); 208 | } 209 | 210 | .panel-heading img{ 211 | float: left; 212 | padding-right: 5px; 213 | } 214 | 215 | /* Course description */ 216 | #ls-course-descriptions .nav.nav-tabs li a{ 217 | padding: 10px 2px; 218 | } 219 | 220 | /* Course documents */ 221 | #ls-course-documents { 222 | padding-bottom: 1em; 223 | } 224 | #ls-course-documents .media-heading a:active, 225 | #ls-course-documents .media-heading a:hover { 226 | text-decoration: none; 227 | } 228 | #ls-course-documents .progress { 229 | margin-bottom: 0; 230 | } 231 | 232 | 233 | .thumbnail { 234 | position: relative; 235 | } 236 | .thumbnail .special-course-pin { 237 | position: absolute; 238 | right: -2px; 239 | top: -4px; 240 | } 241 | 242 | /* Small devices (tablets, 768px and up) */ 243 | @media (min-width: 768px) { 244 | .navigation .navbar-brand { 245 | padding: 5px; 246 | width: 60px; 247 | } 248 | } 249 | 250 | /* Medium devices (desktops, 992px and up) */ 251 | @media (min-width: 992px) { 252 | .navigation .navbar-brand { 253 | padding: 5px; 254 | width: 60px; 255 | } 256 | } 257 | 258 | /* Large devices (large desktops, 1200px and up) */ 259 | @media (min-width: 1200px) { 260 | } 261 | -------------------------------------------------------------------------------- /www/css/editor.css: -------------------------------------------------------------------------------- 1 | /* 2 | Theme Name: Frame Scorm 3 | URI Project: http://www.chamilo.org 4 | Description: Styles main base of Chamilo LMS appearance, works with Bootstrap 3.0.x 5 | Author: 6 | alex.aragon@beeznest.com 7 | Version: 1.0 8 | */ 9 | 10 | @import url(../vendor/font-awesome/css/font-awesome.min.css); 11 | 12 | 13 | body{ 14 | color: #666; 15 | font-family: 'Roboto', sans-serif; 16 | line-height: 30px; 17 | 18 | } 19 | .ck{ 20 | display: block; 21 | font-style: normal; 22 | font-weight: normal; 23 | line-height: 1; 24 | font-size-adjust: none; 25 | font-stretch: normal; 26 | font-feature-settings: normal; 27 | font-language-override: normal; 28 | font-kerning: auto; 29 | font-synthesis: weight style; 30 | font-variant: normal; 31 | } 32 | .ck-article{ 33 | text-transform: uppercase; 34 | color: #E95839; 35 | font-weight: bold; 36 | background: url(../img/document/border-title.png) repeat-x 0 80%; 37 | padding-bottom: 2%; 38 | margin-bottom: 10px; 39 | } 40 | .ck-article:before{ 41 | content: "\f15c"; 42 | margin-right: 5px; 43 | font-family: FontAwesome; 44 | font-weight: normal; 45 | } 46 | .ck-paragraph-box{ 47 | background-color: #F5EEE2; 48 | padding: 2% 3%; 49 | line-height: 20px; 50 | } 51 | .ck-title{ 52 | display: block; 53 | font-weight: bold; 54 | color: #000; 55 | } 56 | .ck-title2{ 57 | padding-top: 0; 58 | margin-top: 0; 59 | font-weight: 500; 60 | position: relative; 61 | color: #000; 62 | } 63 | .ck-title2:after{ 64 | background-color:#E95839; 65 | margin: 10px 0px 0px; 66 | width: 50px; 67 | height: 2px; 68 | display: block; 69 | content: ""; 70 | 71 | } 72 | 73 | figure .image.alignleft{ 74 | margin: 0 20px 20px 0; 75 | } 76 | figure .image.alignright{ 77 | margin: 0 20px 0px 20px; 78 | } 79 | figure .image{ 80 | margin: 0 20px 0px 20px; 81 | } 82 | figure figcaption{ 83 | text-align: left; 84 | background-color: #f3f3f3; 85 | padding-top: 0px; 86 | margin: 0px; 87 | border-radius: 0px; 88 | padding-left: 5px; 89 | } 90 | figure{ 91 | border: 1px solid #ddd; 92 | margin-bottom: 20px !important; 93 | padding: 5px; 94 | border-radius: 5px; 95 | } 96 | blockquote { 97 | background: #f9f9f9; 98 | border-left: 8px solid #ccc; 99 | font: 14px/20px italic Times, serif; 100 | margin: 1.5em 10px; 101 | padding: 0.5em 10px; 102 | quotes: "\201C""\201D""\2018""\2019"; 103 | display: inline-block; 104 | } 105 | blockquote:before { 106 | color: #ccc; 107 | content: open-quote; 108 | font-size: 4em; 109 | line-height: 0.1em; 110 | margin-right: 0.25em; 111 | vertical-align: -0.4em; 112 | } 113 | blockquote p { 114 | display: inline; 115 | } 116 | .ck-stand-out{ 117 | background-color: yellow; 118 | } 119 | /* line horizontal separation */ 120 | .ck-style1 { 121 | height: 6px; 122 | background: url(../img/document/hr-1.png) repeat-x 0 0; 123 | border: 0; 124 | } 125 | .ck-style2 { 126 | height: 6px; 127 | background: url(../img/document/hr-2.png) repeat-x 0 0; 128 | border: 0; 129 | } 130 | .ck-style3 { 131 | border-top: 1px dashed #8c8b8b; 132 | } 133 | .ck-style3:after { 134 | content: '\002702'; 135 | display: inline-block; 136 | position: relative; 137 | top: -12px; 138 | left: 40px; 139 | padding: 0 3px; 140 | background: #FFF; 141 | color: #8c8b8b; 142 | font-size: 18px; 143 | } 144 | .alert { 145 | padding: 15px; 146 | margin-bottom: 20px; 147 | border: 1px solid transparent; 148 | border-radius: 4px; 149 | } 150 | .alert h4 { 151 | margin-top: 0; 152 | color: inherit; 153 | } 154 | .alert .alert-link { 155 | font-weight: bold; 156 | } 157 | .alert > p, 158 | .alert > ul { 159 | margin-bottom: 0; 160 | } 161 | .alert > p + p { 162 | margin-top: 5px; 163 | } 164 | .alert-success { 165 | color: #3c763d; 166 | background-color: #dff0d8; 167 | border-color: #d6e9c6; 168 | } 169 | .alert-success hr { 170 | border-top-color: #c9e2b3; 171 | } 172 | .alert-success .alert-link { 173 | color: #2b542c; 174 | } 175 | .alert-info { 176 | color: #31708f; 177 | background-color: #d9edf7; 178 | border-color: #bce8f1; 179 | } 180 | .alert-info hr { 181 | border-top-color: #a6e1ec; 182 | } 183 | .alert-info .alert-link { 184 | color: #245269; 185 | } 186 | .alert-warning { 187 | color: #8a6d3b; 188 | background-color: #fcf8e3; 189 | border-color: #faebcc; 190 | } 191 | .alert-warning hr { 192 | border-top-color: #f7e1b5; 193 | } 194 | .alert-warning .alert-link { 195 | color: #66512c; 196 | } 197 | .alert-danger { 198 | color: #a94442; 199 | background-color: #f2dede; 200 | border-color: #ebccd1; 201 | } 202 | .alert-danger hr { 203 | border-top-color: #e4b9c0; 204 | } 205 | .alert-danger .alert-link { 206 | color: #843534; 207 | } -------------------------------------------------------------------------------- /www/img/calendar.svg: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 22 | image/svg+xml 23 | 25 | 26 | 27 | 28 | 29 | 31 | 51 | 53 | 58 | 63 | 68 | 73 | 78 | 83 | 88 | 93 | 98 | 103 | 108 | 113 | 118 | 123 | 128 | 133 | 138 | 143 | 148 | 153 | 158 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /www/img/document/border-title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/img/document/border-title.png -------------------------------------------------------------------------------- /www/img/document/hr-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/img/document/hr-1.png -------------------------------------------------------------------------------- /www/img/document/hr-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/img/document/hr-2.png -------------------------------------------------------------------------------- /www/img/down.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 20 | 21 | 23 | image/svg+xml 24 | 26 | 27 | 28 | 29 | 30 | 32 | 52 | 60 | 64 | 68 | 71 | 74 | 77 | 78 | 85 | 89 | 93 | 97 | 101 | 105 | 109 | 113 | 116 | 119 | 122 | 125 | 128 | 131 | 134 | 135 | 143 | 147 | 151 | 154 | 157 | 160 | 161 | 164 | 169 | 174 | 179 | 184 | 185 | 186 | -------------------------------------------------------------------------------- /www/img/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/img/icon.png -------------------------------------------------------------------------------- /www/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/img/logo.png -------------------------------------------------------------------------------- /www/img/session_default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/img/session_default.png -------------------------------------------------------------------------------- /www/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Mobile Messaging - Chamilo LMS 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 |
19 | Chamilo Mobile 20 |
21 |
22 | Chamilo Mobile 23 |
24 |
25 |
26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /www/js/main.js: -------------------------------------------------------------------------------- 1 | document.addEventListener('deviceready', function () { 2 | require([ 3 | 'database', 4 | 'app' 5 | ], function (DB, app) { 6 | DB.setUp().done(function () { 7 | app.init(); 8 | }).fail(function () { 9 | alert('App not loaded'); 10 | }); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /www/js/require-setup.js: -------------------------------------------------------------------------------- 1 | var require = { 2 | paths: { 3 | jquery: '../vendor/jquery/jquery.min', 4 | bootstrap: '../vendor/bootstrap/js/bootstrap.min', 5 | underscore: '../vendor/underscore.js/underscore-min', 6 | backbone: '../vendor/backbone.js/backbone-min', 7 | text: '../vendor/require-text/text.min', 8 | i18n: '../vendor/require-i18n/i18n.min' 9 | }, 10 | shim: { 11 | ripples: { 12 | deps: ['jquery'], 13 | exports: 'jQuery.fn.ripples' 14 | }, 15 | material: { 16 | deps: ['jquery', 'ripples'], 17 | exports: 'jQuery.material' 18 | }, 19 | bootstrap: { 20 | deps: ['jquery'] 21 | }, 22 | backbone: { 23 | deps: ['underscore', 'jquery'] 24 | }, 25 | database: { 26 | deps: ['jquery'], 27 | exports: 'DB', 28 | init: function ($) { 29 | return this.DB; 30 | } 31 | } 32 | }, 33 | baseUrl: 'src', 34 | deps: ['i18n!nls/lang', 'bootstrap'], 35 | callback: function (lang) { 36 | window.lang = lang; 37 | } 38 | }; -------------------------------------------------------------------------------- /www/src/collection/course-announcements.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'model/course-announcement' 4 | ], function (Backbone, CourseAnnouncementModel) { 5 | var CourseAnnouncementsCollection = Backbone.Collection.extend({ 6 | model: CourseAnnouncementModel, 7 | fetch: function () { 8 | var self = this, 9 | deferred = new $.Deferred(); 10 | 11 | $.ajax({ 12 | type: 'post', 13 | data: { 14 | action: 'course_announcements' 15 | }, 16 | success: function (response) { 17 | if (response.error) { 18 | deferred.reject(response.message); 19 | 20 | return; 21 | } 22 | 23 | response.data 24 | .forEach(function (announcementData) { 25 | var announcement = new CourseAnnouncementModel(announcementData); 26 | announcement.id = announcementData.id; 27 | 28 | self.add(announcement); 29 | }); 30 | 31 | deferred.resolve(); 32 | }, 33 | error: function () { 34 | deferred.reject(); 35 | } 36 | }); 37 | 38 | return deferred.promise(); 39 | } 40 | }); 41 | 42 | return CourseAnnouncementsCollection; 43 | }); 44 | -------------------------------------------------------------------------------- /www/src/collection/course-descriptions.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'model/course-description' 4 | ], function (Backbone, CourseDescriptionModel) { 5 | var CourseDescriptionsCollection = Backbone.Collection.extend({ 6 | model: CourseDescriptionModel, 7 | fetch: function () { 8 | var self = this, 9 | deferred = new $.Deferred(); 10 | 11 | $.ajax({ 12 | type: 'post', 13 | data: { 14 | action: 'course_descriptions' 15 | }, 16 | success: function (response) { 17 | if (response.error) { 18 | deferred.reject(response.message); 19 | 20 | return; 21 | } 22 | 23 | response.data 24 | .forEach(function (descriptionData) { 25 | var description = new CourseDescriptionModel(descriptionData); 26 | description.id = descriptionData.id; 27 | 28 | self.add(description); 29 | }); 30 | 31 | deferred.resolve(); 32 | }, 33 | error: function () { 34 | deferred.reject(); 35 | } 36 | }); 37 | 38 | return deferred.promise(); 39 | } 40 | }); 41 | 42 | return CourseDescriptionsCollection; 43 | }); 44 | 45 | -------------------------------------------------------------------------------- /www/src/collection/course-documents.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'model/course-document' 4 | ], function (Backbone, CourseDocumentModel) { 5 | var CourseDocumentsCollection = Backbone.Collection.extend({ 6 | model: CourseDocumentModel, 7 | directoryId: 0, 8 | initialize: function () { 9 | this.directoryId = parseInt(window.sessionStorage.directoryId); 10 | }, 11 | fetch: function () { 12 | var self = this, 13 | deferred = new $.Deferred(); 14 | 15 | $.ajax({ 16 | type: 'post', 17 | data: { 18 | action: 'course_documents', 19 | dir_id: this.directoryId 20 | }, 21 | success: function (response) { 22 | if (response.error) { 23 | deferred.reject(response.message); 24 | 25 | return; 26 | } 27 | 28 | response.data 29 | .forEach(function (documentData) { 30 | var document = new CourseDocumentModel(documentData); 31 | document.id = documentData.id; 32 | 33 | self.add(document); 34 | }); 35 | 36 | deferred.resolve(); 37 | }, 38 | error: function () { 39 | deferred.reject(); 40 | } 41 | }); 42 | 43 | return deferred.promise(); 44 | } 45 | }); 46 | 47 | return CourseDocumentsCollection; 48 | }); 49 | 50 | -------------------------------------------------------------------------------- /www/src/collection/course-events.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'model/course-event' 4 | ], function (Backbone, CourseEventModel) { 5 | var CourseEventsCollection = Backbone.Collection.extend({ 6 | model: CourseEventModel, 7 | fetch: function () { 8 | var self = this, 9 | deferred = new $.Deferred(); 10 | 11 | $.ajax({ 12 | type: 'post', 13 | data: { 14 | action: 'course_agenda' 15 | }, 16 | success: function (response) { 17 | if (response.error) { 18 | deferred.reject(response.message); 19 | 20 | return; 21 | } 22 | 23 | response.data 24 | .forEach(function (eventData) { 25 | var event = new CourseEventModel(eventData); 26 | event.id = eventData.id; 27 | 28 | self.add(event); 29 | }); 30 | 31 | deferred.resolve(); 32 | }, 33 | error: function () { 34 | deferred.reject(); 35 | } 36 | }); 37 | 38 | return deferred.promise(); 39 | } 40 | }); 41 | 42 | return CourseEventsCollection; 43 | }); 44 | -------------------------------------------------------------------------------- /www/src/collection/course-forumcategories.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'model/course-forumcategory' 4 | ], function (Backbone, CourseForumCategoryModel) { 5 | var CourseForumCategoriesCollection = Backbone.Collection.extend({ 6 | model: CourseForumCategoryModel, 7 | fetch: function () { 8 | var self = this, 9 | deferred = new $.Deferred(); 10 | 11 | $.ajax({ 12 | type: 'post', 13 | data: { 14 | action: 'course_forumcategories' 15 | }, 16 | success: function (response) { 17 | if (response.error) { 18 | deferred.reject(response.message); 19 | 20 | return; 21 | } 22 | 23 | response.data 24 | .forEach(function (forumCategoryData) { 25 | var forumCategory = new CourseForumCategoryModel(forumCategoryData); 26 | forumCategory.id = forumCategoryData.id; 27 | 28 | self.add(forumCategory); 29 | }); 30 | 31 | deferred.resolve(); 32 | }, 33 | error: function () { 34 | deferred.reject(); 35 | } 36 | }); 37 | 38 | return deferred.promise(); 39 | } 40 | }); 41 | 42 | return CourseForumCategoriesCollection; 43 | }); 44 | 45 | -------------------------------------------------------------------------------- /www/src/collection/course-lpcategories.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'model/course-lpcategory' 4 | ], function (Backbone, CourseLpCategoryModel) { 5 | var CourseLpCategoriesCollection = Backbone.Collection.extend({ 6 | model: CourseLpCategoryModel, 7 | fetch: function () { 8 | var self = this, 9 | deferred = new $.Deferred(); 10 | 11 | $.ajax({ 12 | type: 'post', 13 | data: { 14 | action: 'course_learnpaths' 15 | }, 16 | success: function (response) { 17 | if (response.error) { 18 | deferred.reject(response.message); 19 | 20 | return; 21 | } 22 | 23 | response.data 24 | .forEach(function (lpCategoryData) { 25 | if (!lpCategoryData.learnpaths.length) { 26 | return; 27 | } 28 | 29 | var lpCategory = new CourseLpCategoryModel(lpCategoryData); 30 | lpCategory.id = lpCategoryData.id; 31 | 32 | self.add(lpCategory); 33 | }); 34 | 35 | deferred.resolve(); 36 | }, 37 | error: function () { 38 | deferred.reject(); 39 | } 40 | }); 41 | 42 | return deferred.promise(); 43 | } 44 | }); 45 | 46 | return CourseLpCategoriesCollection; 47 | }); 48 | 49 | -------------------------------------------------------------------------------- /www/src/collection/course-notebooks.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'model/course-notebook' 4 | ], function (Backbone, CourseNotebookModel) { 5 | var CourseNotebooksCollection = Backbone.Collection.extend({ 6 | model: CourseNotebookModel, 7 | fetch: function () { 8 | var self = this, 9 | deferred = new $.Deferred(); 10 | 11 | $.ajax({ 12 | type: 'post', 13 | data: { 14 | action: 'course_notebooks' 15 | }, 16 | success: function (response) { 17 | if (response.error) { 18 | deferred.reject(response.message); 19 | 20 | return; 21 | } 22 | 23 | response.data 24 | .forEach(function (notebookData) { 25 | var notebook = new CourseNotebookModel(notebookData); 26 | notebook.id = notebookData.id; 27 | 28 | self.add(notebook); 29 | }); 30 | 31 | deferred.resolve(); 32 | }, 33 | error: function () { 34 | deferred.reject(); 35 | } 36 | }); 37 | 38 | return deferred.promise(); 39 | } 40 | }); 41 | 42 | return CourseNotebooksCollection; 43 | }); 44 | 45 | -------------------------------------------------------------------------------- /www/src/collection/courses.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'model/course' 4 | ], function (Backbone, CourseModel) { 5 | var CoursesCollection = Backbone.Collection.extend({ 6 | model: CourseModel, 7 | fetch: function () { 8 | var self = this, 9 | deferred = new $.Deferred(); 10 | 11 | $.ajax({ 12 | type: 'post', 13 | data: { 14 | action: 'user_courses' 15 | }, 16 | success: function (response) { 17 | if (response.error) { 18 | deferred.reject(response.message); 19 | 20 | return; 21 | } 22 | 23 | response.data 24 | .forEach(function (courseData) { 25 | var course = new CourseModel(courseData); 26 | course.id = courseData.id; 27 | 28 | self.add(course); 29 | }); 30 | 31 | deferred.resolve(); 32 | }, 33 | error: function () { 34 | deferred.reject(); 35 | } 36 | }); 37 | 38 | return deferred.promise(); 39 | } 40 | }); 41 | 42 | return CoursesCollection; 43 | }); -------------------------------------------------------------------------------- /www/src/collection/messages.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'database', 4 | 'model/message' 5 | ], function (Backbone, DB, MessageModel) { 6 | var MessagesCollection = Backbone.Collection.extend({ 7 | model: MessageModel, 8 | create: function (attributes, options) { 9 | var self = this, 10 | deferred = new $.Deferred(); 11 | 12 | var message = new MessageModel(); 13 | message.save(attributes) 14 | .done(function () { 15 | self.add(message); 16 | 17 | deferred.resolve(); 18 | }) 19 | .fail(function () { 20 | deferred.reject(); 21 | }); 22 | }, 23 | fetch: function () { 24 | var self = this, 25 | deferred = new $.Deferred(); 26 | 27 | var transaction = DB.conx.transaction([DB.TABLE_MESSAGE], 'readonly'), 28 | store = transaction.objectStore(DB.TABLE_MESSAGE), 29 | index = store.index('sendDate'), 30 | request = index.openCursor(null); 31 | 32 | request.onsuccess = function (e) { 33 | var cursor = e.target.result; 34 | 35 | if (!cursor) { 36 | deferred.resolve(); 37 | 38 | return; 39 | } 40 | 41 | var message = new MessageModel(cursor.value); 42 | message.id = cursor.primaryKey; 43 | message.cid = message.id; 44 | self.add(message); 45 | 46 | cursor.continue(); 47 | }; 48 | 49 | request.onerror = function () { 50 | deferred.reject(); 51 | }; 52 | 53 | return deferred.promise(); 54 | } 55 | }); 56 | 57 | return MessagesCollection; 58 | }); 59 | -------------------------------------------------------------------------------- /www/src/collection/sessions.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'model/sessioncategory' 4 | ], function (Backbone, SessionCategoryModel) { 5 | var SessionCollection = Backbone.Collection.extend({ 6 | model: SessionCategoryModel, 7 | fetch: function () { 8 | var self = this, 9 | deferred = new $.Deferred(); 10 | 11 | $.ajax({ 12 | type: 'post', 13 | data: { 14 | action: 'user_sessions' 15 | }, 16 | success: function (response) { 17 | if (response.error) { 18 | deferred.reject(response.message); 19 | 20 | return; 21 | } 22 | 23 | response.data 24 | .forEach(function (sessionCategoryData) { 25 | var sessionCategory = new SessionCategoryModel(sessionCategoryData); 26 | sessionCategory.id = sessionCategoryData.id || 0; 27 | 28 | self.add(sessionCategory); 29 | }); 30 | 31 | deferred.resolve(); 32 | }, 33 | error: function () { 34 | deferred.reject(); 35 | } 36 | }); 37 | 38 | return deferred.promise(); 39 | } 40 | }); 41 | 42 | return SessionCollection; 43 | }); 44 | -------------------------------------------------------------------------------- /www/src/database.js: -------------------------------------------------------------------------------- 1 | define({ 2 | name: 'chamilo-messaging', 3 | version: 4, 4 | TABLE_ACCOUNT: 'account', 5 | TABLE_MESSAGE: 'message', 6 | conx: null, 7 | setUp: function () { 8 | var deferred = $.Deferred(); 9 | var self = this; 10 | 11 | var dbRequest = window.indexedDB.open(self.name, self.version); 12 | dbRequest.onupgradeneeded = function (e) { 13 | var database = e.target.result; 14 | var upgradeTransaction = e.target.transaction; 15 | 16 | if (!database.objectStoreNames.contains(self.TABLE_ACCOUNT)) { 17 | var accountStore = database.createObjectStore(self.TABLE_ACCOUNT, { 18 | autoIncrement: true 19 | }); 20 | accountStore.createIndex('url', 'url'); 21 | accountStore.createIndex('username', 'username'); 22 | accountStore.createIndex('apiKey', 'apiKey', { 23 | unique: true 24 | }); 25 | accountStore.createIndex('lastMessage', 'lastMessage'); 26 | accountStore.createIndex('lastCheckDate', 'lastCheckDate'); 27 | accountStore.createIndex('gcmSenderId', 'gcmSenderId', { 28 | unique: true 29 | }); 30 | } 31 | 32 | if (!database.objectStoreNames.contains(self.TABLE_MESSAGE)) { 33 | var messageStore = database.createObjectStore(self.TABLE_MESSAGE, { 34 | autoIncrement: true 35 | }); 36 | messageStore.createIndex('messageId', 'messageId', { 37 | unique: true 38 | }); 39 | messageStore.createIndex('title', 'title'); 40 | messageStore.createIndex('sender', 'sender'); 41 | messageStore.createIndex('hasAttachment', 'hasAttachment'); 42 | messageStore.createIndex('sendDate', 'sendDate'); 43 | messageStore.createIndex('content', 'content'); 44 | messageStore.createIndex('url', 'url'); 45 | } 46 | 47 | switch (database.version) { 48 | case 4: 49 | upgradeTransaction.objectStore(self.TABLE_MESSAGE).createIndex('beenSeen', 'beenSeen'); 50 | break; 51 | } 52 | }; 53 | 54 | dbRequest.onsuccess = function (e) { 55 | self.conx = e.target.result; 56 | 57 | deferred.resolve(e); 58 | }; 59 | 60 | dbRequest.onerror = function () { 61 | deferred.reject(); 62 | }; 63 | 64 | return deferred.promise(); 65 | } 66 | }); 67 | -------------------------------------------------------------------------------- /www/src/model/campus.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'database', 3 | 'backbone' 4 | ], function (DB, Backbone) { 5 | var CampusModel = Backbone.Model.extend({ 6 | defaults: { 7 | url: '', 8 | username: '', 9 | apiKey: '', 10 | lastMessage: 0, 11 | lastCheckDate: new Date(), 12 | gcmSenderId: null 13 | }, 14 | fetch: function (options) { 15 | var self = this, 16 | deferred = new $.Deferred(); 17 | 18 | var transaction = DB.conx.transaction([DB.TABLE_ACCOUNT], 'readwrite'), 19 | store = transaction.objectStore(DB.TABLE_ACCOUNT), 20 | request = store.openCursor(); 21 | 22 | request.onsuccess = function (e) { 23 | var cursor = e.target.result; 24 | 25 | if (!cursor) { 26 | deferred.reject(); 27 | 28 | return; 29 | } 30 | 31 | self.cid = cursor.key; 32 | self.set({ 33 | url: cursor.value.url, 34 | username: cursor.value.username, 35 | apiKey: cursor.value.apiKey, 36 | lastMessage: cursor.value.lastMessage, 37 | lastCheckDate: cursor.value.lastCheckDate, 38 | gcmSenderId: cursor.value.gcmSenderId 39 | }); 40 | 41 | deferred.resolve(); 42 | }; 43 | 44 | request.onerror = function (e) { 45 | deferred.reject(); 46 | }; 47 | 48 | return deferred.promise(); 49 | }, 50 | save: function (attributes, options) { 51 | var self = this; 52 | 53 | self.attributes = $.extend(self.attributes, attributes); 54 | 55 | options = $.extend({ 56 | isNew: true, 57 | success: null, 58 | error: null 59 | }, options); 60 | 61 | var transaction = DB.conx.transaction([DB.TABLE_ACCOUNT], 'readwrite'), 62 | store = transaction.objectStore(DB.TABLE_ACCOUNT), 63 | request; 64 | 65 | if (options.isNew) { 66 | request = store.add(this.toJSON()); 67 | } else { 68 | self.set(attributes); 69 | request = store.put(this.toJSON(), this.cid); 70 | } 71 | 72 | request.onsuccess = function (e) { 73 | if (!attributes) { 74 | self.cid = e.target.result; 75 | } 76 | 77 | if (options.success) { 78 | options.success(); 79 | } 80 | }; 81 | 82 | request.onerror = function () { 83 | if (options.error) { 84 | options.error(request.error); 85 | } 86 | }; 87 | }, 88 | clear: function () { 89 | var deferred = new $.Deferred(), 90 | transaction = DB.conx.transaction([DB.TABLE_ACCOUNT], 'readwrite'), 91 | store = transaction.objectStore(DB.TABLE_ACCOUNT), 92 | request = store.clear(); 93 | 94 | request.onsuccess = function () { 95 | deferred.resolve(); 96 | }; 97 | 98 | request.onerror = function () { 99 | deferred.reject(); 100 | }; 101 | 102 | return deferred.promise(); 103 | } 104 | }); 105 | 106 | return CampusModel; 107 | }); -------------------------------------------------------------------------------- /www/src/model/course-announcement.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone' 3 | ], function (Backbone) { 4 | var CourseAnnouncementModel = Backbone.Model.extend({ 5 | defaults: { 6 | id: 0, 7 | title: '', 8 | creatorName: '', 9 | date: '', 10 | content: '' 11 | }, 12 | initialize: function () { 13 | this.id = parseInt(window.sessionStorage.announcementId); 14 | }, 15 | fetch: function () { 16 | var self = this, 17 | deferred = new $.Deferred(); 18 | 19 | $.ajax({ 20 | type: 'post', 21 | data: { 22 | action: 'course_announcement', 23 | announcement: this.id 24 | }, 25 | success: function (response) { 26 | if (response.error) { 27 | deferred.reject(response.message); 28 | 29 | return; 30 | } 31 | 32 | self.set(response.data); 33 | 34 | deferred.resolve(); 35 | }, 36 | error: function () { 37 | deferred.reject(); 38 | } 39 | }); 40 | 41 | return deferred.promise(); 42 | } 43 | }); 44 | 45 | return CourseAnnouncementModel; 46 | }); 47 | -------------------------------------------------------------------------------- /www/src/model/course-description.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone' 3 | ], function (Backbone) { 4 | var CourseDescriptionModel = Backbone.Model.extend({ 5 | defaults: { 6 | id: 0, 7 | title: '', 8 | content: '' 9 | } 10 | }); 11 | 12 | return CourseDescriptionModel; 13 | }); 14 | 15 | -------------------------------------------------------------------------------- /www/src/model/course-document.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone' 3 | ], function (Backbone) { 4 | var CourseDocumentModel = Backbone.Model.extend({ 5 | defaults: { 6 | id: 0, 7 | type: '', 8 | title: '', 9 | path: '/', 10 | url: '', 11 | size: 0, 12 | icon: '' 13 | }, 14 | updateIcon: function () { 15 | if (this.get('type') === 'file') { 16 | this.set('icon', 'default.svg'); 17 | return; 18 | } 19 | 20 | if (this.get('path') === '/shared_folder') { 21 | this.set('icon', 'folder_users.svg'); 22 | return; 23 | } 24 | 25 | if (this.get('path').indexOf('shared_folder_session_') >= 0) { 26 | this.set('icon', 'folder_users.svg'); 27 | return; 28 | } 29 | 30 | switch (this.get('path')) { 31 | case '/audio': 32 | this.set('icon', 'folder_audio.svg'); 33 | return; 34 | case '/flash': 35 | this.set('icon', 'folder_flash.svg'); 36 | return; 37 | case '/images': 38 | this.set('icon', 'folder_images.svg'); 39 | return; 40 | case '/video': 41 | this.set('icon', 'folder_video.svg'); 42 | return; 43 | case '/images/gallery': 44 | this.set('icon', 'folder_gallery.svg'); 45 | return; 46 | case '/chat_files': 47 | this.set('icon', 'folder_chat.svg'); 48 | return; 49 | case '/learning_path': 50 | this.set('icon', 'folder_learningpath.svg'); 51 | return; 52 | } 53 | 54 | this.set('icon', 'folder_document.svg'); 55 | return; 56 | } 57 | }); 58 | 59 | return CourseDocumentModel; 60 | }); 61 | -------------------------------------------------------------------------------- /www/src/model/course-event.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone' 3 | ], function (Backbone) { 4 | var CourseEventModel = Backbone.Model.extend({ 5 | defaults: { 6 | id: 0, 7 | title: '', 8 | content: '', 9 | startDate: '', 10 | endDate: '', 11 | isAllDay: false 12 | } 13 | }); 14 | 15 | return CourseEventModel; 16 | }); 17 | -------------------------------------------------------------------------------- /www/src/model/course-forum.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone' 3 | ], function (Backbone) { 4 | var CourseForumModel = Backbone.Model.extend({ 5 | defaults: { 6 | id: 0, 7 | title: '', 8 | description: '', 9 | image: '', 10 | threads: [] 11 | }, 12 | initialize: function () { 13 | this.id = parseInt(window.sessionStorage.forumId); 14 | }, 15 | fetch: function () { 16 | var self = this, 17 | deferred = new $.Deferred(); 18 | 19 | $.ajax({ 20 | type: 'post', 21 | data: { 22 | action: 'course_forum', 23 | forum: this.id 24 | }, 25 | success: function (response) { 26 | if (response.error) { 27 | deferred.reject(response.message); 28 | 29 | return; 30 | } 31 | 32 | self.set(response.data); 33 | deferred.resolve(); 34 | }, 35 | error: function () { 36 | deferred.reject(); 37 | } 38 | }); 39 | 40 | return deferred.promise(); 41 | } 42 | }); 43 | 44 | return CourseForumModel; 45 | }); 46 | -------------------------------------------------------------------------------- /www/src/model/course-forumcategory.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone' 3 | ], function (Backbone) { 4 | var CourseForumCategoryModel = Backbone.Model.extend({ 5 | defaults: { 6 | id: 0, 7 | title: '', 8 | catId: 0, 9 | description: '', 10 | forums: [], 11 | courseId: 0 12 | } 13 | }); 14 | 15 | return CourseForumCategoryModel; 16 | }); 17 | -------------------------------------------------------------------------------- /www/src/model/course-forumpost.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone' 3 | ], function (Backbone) { 4 | var CourseForumPostModel = Backbone.Model.extend({ 5 | defaults: { 6 | id: 0, 7 | title: '', 8 | text: '', 9 | author: '', 10 | date: '', 11 | parentId: 0, 12 | threadId: 0, 13 | forumId: 0 14 | }, 15 | forumId: 0, 16 | initialize: function () { 17 | this.forumId = parseInt(window.sessionStorage.forumId); 18 | }, 19 | save: function (attributes, options) { 20 | var deferred = new $.Deferred; 21 | 22 | $.ajax({ 23 | type: 'post', 24 | data: { 25 | action: 'save_forum_post', 26 | title: attributes.title, 27 | text: attributes.text, 28 | thread: attributes.threadId, 29 | forum: this.forumId, 30 | notify: options.notify ? 1 : 0, 31 | parent: attributes.parentId 32 | }, 33 | success: function (response) { 34 | if (response.error) { 35 | deferred.reject(response.message); 36 | 37 | return; 38 | } 39 | 40 | deferred.resolve(); 41 | }, 42 | error: function () { 43 | deferred.reject(); 44 | } 45 | }); 46 | 47 | return deferred.promise(); 48 | } 49 | }); 50 | 51 | return CourseForumPostModel; 52 | }); 53 | -------------------------------------------------------------------------------- /www/src/model/course-forumthread.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'model/course-forumpost' 4 | ], function (Backbone, CourseForumPostModel) { 5 | var CourseForumThreadModel = Backbone.Model.extend({ 6 | forumId: 0, 7 | defaults: { 8 | id: 0, 9 | cId: 0, 10 | title: '', 11 | forumId: 0, 12 | posts: [] 13 | }, 14 | initialize: function () { 15 | this.forumId = parseInt(window.sessionStorage.forumId); 16 | this.id = parseInt(window.sessionStorage.threadId); 17 | }, 18 | fetch: function () { 19 | var self = this, 20 | deferred = new $.Deferred; 21 | 22 | $.ajax({ 23 | type: 'post', 24 | data: { 25 | action: 'course_forumthread', 26 | thread: this.id, 27 | forum: this.forumId 28 | }, 29 | success: function (response) { 30 | if (response.error) { 31 | deferred.reject(response.message); 32 | 33 | return; 34 | } 35 | 36 | self.set({ 37 | id: response.data.id, 38 | cId: response.data.cId, 39 | forumId: response.data.forumId, 40 | title: response.data.title 41 | }); 42 | 43 | var posts = []; 44 | 45 | _.each(response.data.posts, function (postData) { 46 | postData.threadId = self.get('id'); 47 | postData.forumId = self.get('forumId'); 48 | 49 | var forumPost = new CourseForumPostModel(postData); 50 | 51 | posts.push(forumPost); 52 | }); 53 | 54 | self.set('posts', posts); 55 | 56 | deferred.resolve(); 57 | }, 58 | error: function () { 59 | deferred.reject(); 60 | } 61 | }); 62 | 63 | return deferred.promise(); 64 | } 65 | }); 66 | 67 | return CourseForumThreadModel; 68 | }); 69 | -------------------------------------------------------------------------------- /www/src/model/course-lp.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone' 3 | ], function (Backbone) { 4 | var CourseLpModel = Backbone.Model.extend({ 5 | defaults: { 6 | id: 0, 7 | title: '', 8 | progress: 0, 9 | url: null 10 | } 11 | }); 12 | 13 | return CourseLpModel; 14 | }); 15 | -------------------------------------------------------------------------------- /www/src/model/course-lpcategory.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone' 3 | ], function (Backbone) { 4 | var CourseLpModel = Backbone.Model.extend({ 5 | defaults: { 6 | id: 0, 7 | name: '', 8 | learnpaths: [] 9 | } 10 | }); 11 | 12 | return CourseLpModel; 13 | }); 14 | -------------------------------------------------------------------------------- /www/src/model/course-notebook.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone' 3 | ], function (Backbone) { 4 | var CourseNotebookModel = Backbone.Model.extend({ 5 | defaults: { 6 | id: 0, 7 | title: '', 8 | description: '', 9 | creationDate: '', 10 | updateDate: '' 11 | } 12 | }); 13 | 14 | return CourseNotebookModel; 15 | }); 16 | 17 | -------------------------------------------------------------------------------- /www/src/model/course.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone' 3 | ], function (Backbone) { 4 | var CourseModel = Backbone.Model.extend({ 5 | defaults: { 6 | id: 0, 7 | title: '', 8 | code: '', 9 | directory: '', 10 | urlPicture: null, 11 | teachers: '', 12 | isSpecial: false, 13 | tools: [ 14 | {type: 'description'}, 15 | {type: 'documents'}, 16 | {type: 'learning_paths'}, 17 | {type: 'forum'}, 18 | {type: 'agenda'}, 19 | {type: 'notebook'}, 20 | {type: 'announcements'} 21 | ] 22 | }, 23 | fetch: function (options) { 24 | var self = this, 25 | deferred = new $.Deferred(); 26 | 27 | $.ajax({ 28 | type: 'post', 29 | data: { 30 | action: 'course_info' 31 | }, 32 | success: function (response) { 33 | if (response.error) { 34 | deferred.reject(response.message); 35 | 36 | return; 37 | } 38 | 39 | self.cid = response.data.id; 40 | self.id = response.data.id; 41 | self.set(response.data); 42 | 43 | deferred.resolve(); 44 | }, 45 | error: function () { 46 | deferred.reject(); 47 | } 48 | }); 49 | 50 | return deferred.promise(); 51 | } 52 | }); 53 | 54 | return CourseModel; 55 | }); 56 | -------------------------------------------------------------------------------- /www/src/model/message.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'database', 3 | 'backbone' 4 | ], function (DB, Backbone) { 5 | var MessageModel = Backbone.Model.extend({ 6 | defaults: { 7 | messageId: 0, 8 | sender: '', 9 | title: '', 10 | content: '', 11 | hasAttachment: false, 12 | sendDate: new Date(), 13 | url: '', 14 | beenSeen: false, 15 | }, 16 | save: function (attributes, options) { 17 | var self = this, 18 | deferred = new $.Deferred(); 19 | 20 | var oldBeenSeen = self.get('beenSeen'); 21 | 22 | self.attributes = $.extend(self.attributes, attributes); 23 | 24 | var transaction = DB.conx.transaction([DB.TABLE_MESSAGE], 'readwrite'), 25 | store = transaction.objectStore(DB.TABLE_MESSAGE), 26 | request = store.put(this.toJSON(), this.id); 27 | 28 | request.onsuccess = function (e) { 29 | self.id = e.target.result; 30 | self.cid = self.id; 31 | 32 | if (!oldBeenSeen && self.get('beenSeen')) { 33 | $.ajax({ 34 | type: 'post', 35 | data: { 36 | action: 'user_message_read', 37 | messages: [self.get('messageId')], 38 | } 39 | }); 40 | } 41 | 42 | deferred.resolve(); 43 | }; 44 | 45 | request.onerror = function () { 46 | deferred.reject(); 47 | }; 48 | 49 | return deferred.promise(); 50 | }, 51 | fetch: function (options) { 52 | var self = this; 53 | 54 | options = $.extend({ 55 | success: null, 56 | error: null 57 | }, options); 58 | 59 | var transaction = DB.conx.transaction([DB.TABLE_MESSAGE]), 60 | store = transaction.objectStore(DB.TABLE_MESSAGE), 61 | request = store.get(this.cid); 62 | 63 | request.onsuccess = function (e) { 64 | if (!request.result) { 65 | if (options.error) { 66 | options.error(request.error); 67 | } 68 | 69 | return; 70 | } 71 | 72 | if (request.result) { 73 | self.set(request.result); 74 | 75 | if (options.success) { 76 | options.success(); 77 | } 78 | } 79 | }; 80 | 81 | request.onerror = function () { 82 | if (options.error) { 83 | options.error(request.error); 84 | } 85 | }; 86 | }, 87 | next: function (options) { 88 | options = $.extend({ 89 | success: null, 90 | error: null 91 | }, options); 92 | 93 | var range = IDBKeyRange.lowerBound(this.get('messageId'), true), 94 | transaction = DB.conx.transaction([DB.TABLE_MESSAGE], 'readonly'), 95 | store = transaction.objectStore(DB.TABLE_MESSAGE), 96 | index = store.index('messageId'), 97 | request = index.openCursor(range); 98 | 99 | request.onsuccess = function (e) { 100 | var nextMessage = null, 101 | cursor = e.target.result; 102 | 103 | if (cursor) { 104 | nextMessage = new MessageModel(cursor.value); 105 | nextMessage.id = cursor.primaryKey; 106 | nextMessage.cid = cursor.primaryKey; 107 | } 108 | 109 | if (options.success) { 110 | options.success(nextMessage); 111 | } 112 | }; 113 | 114 | request.onerror = function () { 115 | if (options.error) { 116 | options.error(request.error); 117 | } 118 | }; 119 | }, 120 | previous: function (options) { 121 | options = $.extend({ 122 | success: null, 123 | error: null 124 | }, options); 125 | 126 | var range = IDBKeyRange.upperBound(this.get('messageId'), true), 127 | transaction = DB.conx.transaction([DB.TABLE_MESSAGE], 'readonly'), 128 | store = transaction.objectStore(DB.TABLE_MESSAGE), 129 | index = store.index('messageId'), 130 | request = index.openCursor(range, 'prev'); 131 | 132 | request.onsuccess = function (e) { 133 | var previousMessage = null, 134 | cursor = e.target.result; 135 | 136 | if (cursor) { 137 | previousMessage = new MessageModel(cursor.value); 138 | previousMessage.id = cursor.primaryKey; 139 | previousMessage.cid = cursor.primaryKey; 140 | } 141 | 142 | if (options.success) { 143 | options.success(previousMessage); 144 | } 145 | }; 146 | 147 | request.onerror = function () { 148 | if (options.error) { 149 | options.error(request.error); 150 | } 151 | }; 152 | }, 153 | clear: function () { 154 | var deferred = $.Deferred(), 155 | transaction = DB.conx.transaction([DB.TABLE_MESSAGE], 'readwrite'), 156 | store = transaction.objectStore(DB.TABLE_MESSAGE), 157 | request = store.clear(); 158 | 159 | request.onsuccess = function () { 160 | deferred.resolve(); 161 | }; 162 | 163 | request.onerror = function () { 164 | deferred.reject(); 165 | }; 166 | 167 | return deferred.promise(); 168 | } 169 | }); 170 | 171 | return MessageModel; 172 | }); 173 | -------------------------------------------------------------------------------- /www/src/model/session.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'model/course' 4 | ], function (Backbone, CourseModel) { 5 | var SessionModel = Backbone.Model.extend({ 6 | defaults: { 7 | name: '', 8 | id: 0, 9 | date: '', 10 | duration: '', 11 | courses: [] 12 | }, 13 | initialize: function (attributes) { 14 | var courses = []; 15 | 16 | _.each(attributes.courses, function (course) { 17 | courses.push(new CourseModel(course)); 18 | }); 19 | 20 | this.set('courses', courses); 21 | } 22 | }); 23 | 24 | return SessionModel; 25 | }); 26 | -------------------------------------------------------------------------------- /www/src/model/sessioncategory.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'model/session' 4 | ], function (Backbone, SessionModel) { 5 | var SessionCategoryModel = Backbone.Model.extend({ 6 | defaults: { 7 | id: 0, 8 | name: '', 9 | sessions: [] 10 | }, 11 | initialize: function (attributes) { 12 | var sessions = []; 13 | 14 | _.each(attributes.sessions, function (session) { 15 | sessions.push(new SessionModel(session)); 16 | }); 17 | 18 | this.set('sessions', sessions); 19 | } 20 | }); 21 | 22 | return SessionCategoryModel; 23 | }); 24 | -------------------------------------------------------------------------------- /www/src/model/spinner.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone' 3 | ], function (Backbone) { 4 | var SpinnerModel = Backbone.Model.extend({ 5 | defaults: { 6 | loading: true, 7 | noContent: false 8 | } 9 | }); 10 | 11 | return SpinnerModel; 12 | }); -------------------------------------------------------------------------------- /www/src/model/user.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone' 3 | ], function (Backbone) { 4 | var UserModel = Backbone.Model.extend({ 5 | defaults: { 6 | pictureUri: '', 7 | fullName: '', 8 | username: '', 9 | officialCode: null, 10 | phone: null, 11 | extra: [] 12 | }, 13 | fetch: function () { 14 | var self = this, 15 | deferred = new $.Deferred(); 16 | 17 | $.ajax({ 18 | type: 'post', 19 | data: { 20 | action: 'user_profile' 21 | }, 22 | success: function (response) { 23 | if (response.error) { 24 | deferred.reject(response.message); 25 | 26 | return; 27 | } 28 | 29 | self.set(response.data); 30 | 31 | deferred.resolve(); 32 | } 33 | }); 34 | 35 | return deferred.promise(); 36 | } 37 | }); 38 | 39 | return UserModel; 40 | }); 41 | -------------------------------------------------------------------------------- /www/src/nls/de/lang.js: -------------------------------------------------------------------------------- 1 | define({ 2 | appName: "Chamilo LMS Mobiel", 3 | myChamilo: "Mein Chamilo LMS", 4 | myCourses: 'Meine Kurse', 5 | domain: "Domaine", 6 | myAccount: "Mein Konto", 7 | username: "Benutzername", 8 | password: "Passwort", 9 | signIn: "Login", 10 | messages: "Nachrichten", 11 | profile: "Profil", 12 | signOut: "Ausloggen", 13 | goToCourse: "Zur Lerninsel", 14 | courseAgenda: "Kalender", 15 | announcement: "Ankündigungen", 16 | courseAnnouncements: "Lerninselankündigungen", 17 | courseDescriptions: "Lerninselbeschreibung", 18 | courseDocuments: "Lerninseldokumente", 19 | allDay: "Den ganzen Tag", 20 | forum: "Forum", 21 | views: "Vues", 22 | replies: "Antworten", 23 | forumCategories: "Forumkategorie", 24 | numberOfThreads: "Themenanzahl", 25 | lastPost: "Letzte Veröffentlichung", 26 | reply: "Antworten", 27 | quote: "Zitieren", 28 | replyTo: function (title) { 29 | return "An antworten" + title + ""; 30 | }, 31 | title: "Titel", 32 | text: "Text", 33 | notifyMeByEmail: "Per Email benachrichtigen", 34 | replyThisPost: "Antwort abschicken", 35 | thread: "Thema", 36 | replyThisThread: "Auf dieses Thema antworten", 37 | description: "Beschreibung", 38 | documents: "Dokumente", 39 | learningPaths: "Lernpfad", 40 | agenda: "Kalender", 41 | notebook: "Notizblock", 42 | announcements: "Ankündigungen", 43 | learningPathsCategories: "Lernpfadkategorie", 44 | creationDate: function (date) { 45 | return "Angelegt am: " + date; 46 | }, 47 | updateDate: function (date) { 48 | return "Überarbeitet am: " + date; 49 | }, 50 | courseNotebook: "Bewertungsmappe", 51 | inbox: "Posteingang", 52 | myProfile: "Mein Profil", 53 | phoneNumber: "Telefonnummer", 54 | signingOut: "Logout", 55 | loading: "Seite wird geladen", 56 | noContentAvailable: "Seite nicht vorhanden" 57 | }); 58 | -------------------------------------------------------------------------------- /www/src/nls/es/lang.js: -------------------------------------------------------------------------------- 1 | define({ 2 | appName: "Chamilo LMS Mobile", 3 | myChamilo: "Mi Chamilo LMS", 4 | myCourses: 'Mis cursos', 5 | domain: "Dominio", 6 | myAccount: "Mi cuenta", 7 | username: "Nombre de usuario", 8 | password: "Contraseña", 9 | signIn: "Ingresar", 10 | messages: "Mensajes", 11 | profile: "Perfil", 12 | signOut: "Salir", 13 | goToCourse: "Ir al curso", 14 | courseAgenda: "Agenda del curso", 15 | announcement: "Anuncio", 16 | courseAnnouncements: "Anuncios del curso", 17 | courseDescriptions: "Descripción del curso", 18 | courseDocuments: "Documentos del curso", 19 | allDay: "Todo el día", 20 | forum: "Foro", 21 | views: "Vistas", 22 | replies: "Respuestas", 23 | forumCategories: "Categorías de foro", 24 | numberOfThreads: "Número de temas", 25 | lastPost: "Última publicación", 26 | reply: "Responder", 27 | quote: "Citar", 28 | replyTo: function (title) { 29 | return "Responder a " + title + ""; 30 | }, 31 | title: "Título", 32 | text: "Texto", 33 | notifyMeByEmail: "Notificarme por correo electrónico", 34 | replyThisPost: "Responder esta publicación", 35 | thread: "Tema", 36 | replyThisThread: "Responder este tema", 37 | description: "Descripción", 38 | documents: "Documentos", 39 | learningPaths: "Lecciones", 40 | agenda: "Agenda", 41 | notebook: "Notas personales", 42 | announcements: "Anuncios", 43 | learningPathsCategories: "Categorías de lecciones", 44 | creationDate: function (date) { 45 | return "Fecha de creación: " + date; 46 | }, 47 | updateDate: function (date) { 48 | return "Fecha de actualización: " + date; 49 | }, 50 | courseNotebook: "Notas personales en el curso", 51 | inbox: "Bandeja de entrada", 52 | myProfile: "Mi perfil", 53 | phoneNumber: "Número de teléfono", 54 | signingOut: "Cerrando sessión", 55 | loading: "Cargando", 56 | noContentAvailable: "Contenido no disponible", 57 | downloadComplete: "Download completed", 58 | downloadFailed: "Download failed", 59 | sessions: "Sessiones de formación", 60 | fromDateUntilDate: function (from, until) { 61 | if (from && !until) { 62 | return "Desde " + from; 63 | } 64 | 65 | if (!from && until) { 66 | return "Hasta " + until; 67 | } 68 | 69 | return "Desde " + from + " hasta " + until; 70 | }, 71 | downloadCompleted: "Descarga completada", 72 | downloadFailed: "Descarga fallida" 73 | }); 74 | -------------------------------------------------------------------------------- /www/src/nls/fr/lang.js: -------------------------------------------------------------------------------- 1 | define({ 2 | appName: "Chamilo LMS Mobile", 3 | myChamilo: "Mon Chamilo LMS", 4 | myCourses: 'Mes cours', 5 | domain: "Domaine", 6 | myAccount: "Mon compte", 7 | username: "Login", 8 | password: "Mot de passe", 9 | signIn: "Se connecter", 10 | messages: "Messages", 11 | profile: "Profil", 12 | signOut: "Se déconnecter", 13 | goToCourse: "Vers le cours", 14 | courseAgenda: "Agenda du cours", 15 | announcement: "Annonces", 16 | courseAnnouncements: "Annonces de cours", 17 | courseDescriptions: "Descriptions de cours", 18 | courseDocuments: "Documents de cours", 19 | allDay: "Toute la journée", 20 | forum: "Forum", 21 | views: "Vues", 22 | replies: "Réponses", 23 | forumCategories: "Catégories de forum", 24 | numberOfThreads: "Nombre de thèmes", 25 | lastPost: "Dernière publication", 26 | reply: "Répondre", 27 | quote: "Citer", 28 | replyTo: function (title) { 29 | return "Répondre à " + title + ""; 30 | }, 31 | title: "Titre", 32 | text: "Texte", 33 | notifyMeByEmail: "Notifier par mail", 34 | replyThisPost: "Répondre à cette publication", 35 | thread: "Thème", 36 | replyThisThread: "Répondre à ce thème", 37 | description: "Description", 38 | documents: "Documents", 39 | learningPaths: "Parcours", 40 | agenda: "Agenda", 41 | notebook: "Notes perso", 42 | announcements: "Annonces", 43 | learningPathsCategories: "Catégories de parcours", 44 | creationDate: function (date) { 45 | return "Date de création: " + date; 46 | }, 47 | updateDate: function (date) { 48 | return "Date de mise à jour: " + date; 49 | }, 50 | courseNotebook: "Cahiers de notes de cours", 51 | inbox: "Boîte aux lettres", 52 | myProfile: "Mon profil", 53 | phoneNumber: "Numéro de tél", 54 | signingOut: "Déconnexion", 55 | loading: "Loading", 56 | noContentAvailable: "No content available" 57 | }); 58 | -------------------------------------------------------------------------------- /www/src/nls/lang.js: -------------------------------------------------------------------------------- 1 | define({ 2 | "root": true, 3 | "es": true, 4 | "fr": true, 5 | "de": true 6 | }); 7 | -------------------------------------------------------------------------------- /www/src/nls/root/lang.js: -------------------------------------------------------------------------------- 1 | define({ 2 | appName: "Chamilo LMS Mobile", 3 | myChamilo: "My Chamilo LMS", 4 | myCourses: 'My courses', 5 | domain: "Domain", 6 | myAccount: "My account", 7 | username: "Username", 8 | password: "Password", 9 | signIn: "Sign in", 10 | messages: "Messages", 11 | profile: "Profile", 12 | signOut: "Sign out", 13 | goToCourse: "Go to course", 14 | courseAgenda: "Course agenda", 15 | announcement: "Announcement", 16 | courseAnnouncements: "Course announcements", 17 | courseDescriptions: "Course descriptions", 18 | courseDocuments: "Course documents", 19 | allDay: "All day", 20 | forum: "Forum", 21 | views: "Views", 22 | replies: "Replies", 23 | forumCategories: "Forum categories", 24 | numberOfThreads: "Number of threads", 25 | lastPost: "Last post", 26 | reply: "Reply", 27 | quote: "Quote", 28 | replyTo: function (title) { 29 | return "Reply to " + title + ""; 30 | }, 31 | title: "Title", 32 | text: "Text", 33 | notifyMeByEmail: "Notify me by email", 34 | replyThisPost: "Reply this post", 35 | thread: "Thread", 36 | replyThisThread: "Reply this thread", 37 | description: "Description", 38 | documents: "Documents", 39 | learningPaths: "Learning paths", 40 | agenda: "Agenda", 41 | notebook: "Notebook", 42 | announcements: "Announcements", 43 | learningPathsCategories: "Learning paths categories", 44 | creationDate: function (date) { 45 | return "Creation date: " + date; 46 | }, 47 | updateDate: function (date) { 48 | return "Update date: " + date; 49 | }, 50 | courseNotebook: "Course notebooks", 51 | inbox: "Inbox", 52 | myProfile: "My profile", 53 | phoneNumber: "Phone number", 54 | signingOut: "Signing out", 55 | loading: "Loading", 56 | noContentAvailable: "No content available", 57 | sessions: 'Sessions', 58 | fromDateUntilDate: function (from, until) { 59 | if (from && !until) { 60 | return "From " + from; 61 | } 62 | 63 | if (!from && until) { 64 | return "Until " + until; 65 | } 66 | 67 | return "From " + from + " until " + until; 68 | }, 69 | downloadCompleted: "Download completed", 70 | downloadFailed: "Download failed" 71 | }); 72 | -------------------------------------------------------------------------------- /www/src/template/course-agenda.html: -------------------------------------------------------------------------------- 1 | 10 | 11 |
12 |
13 |
14 | -------------------------------------------------------------------------------- /www/src/template/course-announcement-item.html: -------------------------------------------------------------------------------- 1 |

<%= title %>

2 |

3 | <%= creatorName %> - <%= date %> 4 |

5 | -------------------------------------------------------------------------------- /www/src/template/course-announcement.html: -------------------------------------------------------------------------------- 1 | 10 | 11 |
12 |
13 |
14 |
15 |

<%= title %>

16 |
17 |
18 |
    19 |
  • 20 | <%= creatorName %> 21 |
  • 22 |
  • 23 | <%= date %> 24 |
  • 25 |
26 |
27 |
28 | <%= content %> 29 |
30 |
31 |
32 |
33 |
34 | -------------------------------------------------------------------------------- /www/src/template/course-announcements.html: -------------------------------------------------------------------------------- 1 | 10 | 11 |
12 |
13 |
14 | -------------------------------------------------------------------------------- /www/src/template/course-description-content.html: -------------------------------------------------------------------------------- 1 |
2 |

<%= title %>

3 |
4 |
<%= content %>
5 | -------------------------------------------------------------------------------- /www/src/template/course-description-title.html: -------------------------------------------------------------------------------- 1 | <% 2 | var icon = null; 3 | 4 | switch (id) { 5 | case '1': 6 | icon = 'info.svg'; 7 | break; 8 | case '2': 9 | icon = 'objective.svg'; 10 | break; 11 | case '3': 12 | icon = 'topics.svg'; 13 | break; 14 | case '4': 15 | icon = 'strategy.svg'; 16 | break; 17 | case '5': 18 | icon = 'laptop.svg'; 19 | break; 20 | case '6': 21 | icon = 'teacher.svg'; 22 | break; 23 | case '7': 24 | icon = 'assessment.svg'; 25 | break; 26 | case '8': 27 | icon = 'wizard.svg'; 28 | break; 29 | } 30 | %> 31 | 32 | <%= title %> 33 | 34 | -------------------------------------------------------------------------------- /www/src/template/course-descriptions.html: -------------------------------------------------------------------------------- 1 | 10 | 11 |
12 |
13 | 14 |
15 |
16 |
17 | -------------------------------------------------------------------------------- /www/src/template/course-document.html: -------------------------------------------------------------------------------- 1 |
2 | <%= title %> 3 |
4 |
5 |
6 | <%= title %> 7 |
8 | <% if (type === 'file') { %> 9 | 14 | 17 | 20 | <% } %> 21 |
22 | <% if (type === 'file') { %> 23 |
24 | <%= size %> 25 |
26 | <% } %> 27 | -------------------------------------------------------------------------------- /www/src/template/course-documents.html: -------------------------------------------------------------------------------- 1 | 10 | 11 |
12 |
13 |
14 | -------------------------------------------------------------------------------- /www/src/template/course-event.html: -------------------------------------------------------------------------------- 1 |
2 | <%= title %> 3 |

4 | <%= title %> 5 |

6 |
7 |
8 |
    9 | <% if (startDate == endDate) { %> 10 |
  • 11 | <%= startDate %> 12 |
  • 13 | <% if (isAllDay) { %> 14 |
  • <%= lang.allDay %>
  • 15 | <% } %> 16 | <% } else { %> 17 |
  • 18 | <%= startDate %> 19 |
  • 20 |
  • 21 | <% if (isAllDay) { %> 22 | <%= lang.allDay %> 23 | <% } else { %> 24 | 25 | <%= endDate %> 26 | <% } %> 27 |
  • 28 | <% } %> 29 |
30 |
31 |
32 | <%= content %> 33 |
34 |
35 | -------------------------------------------------------------------------------- /www/src/template/course-forum.html: -------------------------------------------------------------------------------- 1 | 10 | 11 |
12 | 45 |
46 | -------------------------------------------------------------------------------- /www/src/template/course-forumcategories.html: -------------------------------------------------------------------------------- 1 | 10 | 11 |
12 |
13 |
14 |
15 | -------------------------------------------------------------------------------- /www/src/template/course-forumcategory.html: -------------------------------------------------------------------------------- 1 | 8 |
9 | <% if (description) { %> 10 |
11 | <%= description %> 12 |
13 | <% } %> 14 | 15 | <% if (forums.length) { %> 16 |
    17 | <% forums.forEach(function (forum) { %> 18 |
  • 19 |
    20 | <%= forum.title %> 21 |
    22 |
    23 | <% if (forum.description) { %> 24 | <%= forum.description %> 25 | <% } %> 26 | 27 |
    28 |
    29 | <%= lang.numberOfThreads %> 30 |
    31 |
    32 | <%= forum.numberOfThreads %> 33 |
    34 |
    35 | 36 | <% if (forum.lastPost) { %> 37 |
    38 |
    39 | <%= lang.lastPost %> 40 |
    41 |
    42 | <%= forum.lastPost.user %>
    43 | <%= forum.lastPost.date %> 44 |
    45 |
    46 | <% } %> 47 |
    48 |
  • 49 | <% }) %> 50 |
51 | <% } %> 52 |
53 | -------------------------------------------------------------------------------- /www/src/template/course-forumpost-item.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

<%= title %>

4 |
5 |
6 |
    7 |
  • 8 | <%= author %> 9 |
  • 10 |
  • 11 | <%= date %> 12 |
  • 13 |
14 | <%= text %> 15 |
16 |
17 |
18 | 21 | 24 |
25 |
26 |
27 |
28 | 29 | 78 | -------------------------------------------------------------------------------- /www/src/template/course-forumthread.html: -------------------------------------------------------------------------------- 1 | 13 | 14 |
15 |
16 |
17 | 18 |
19 | <% if (posts.length) { %> 20 |
21 | <% } %> 22 |
23 |
24 | 25 | 67 | -------------------------------------------------------------------------------- /www/src/template/course-home.html: -------------------------------------------------------------------------------- 1 | 12 | 13 |
14 | <% if (tools.length) { %> 15 |
16 | <% 17 | _.each(tools, function (tool) { 18 | switch (tool.type) { 19 | case 'course_description': 20 | %> 21 | 27 | <% 28 | break; 29 | case 'document': 30 | %> 31 | 37 | <% 38 | break; 39 | case 'learnpath': 40 | %> 41 | 47 | <% 48 | break; 49 | case 'forum': 50 | %> 51 | 57 | <% 58 | break; 59 | case 'calendar_event': 60 | %> 61 | 67 | <% 68 | break; 69 | case 'notebook': 70 | %> 71 | 77 | <% 78 | break; 79 | case 'announcement': 80 | %> 81 | 87 | <% 88 | break; 89 | } 90 | }); 91 | %> 92 |
93 | <% } %> 94 |
95 | -------------------------------------------------------------------------------- /www/src/template/course-lp-item.html: -------------------------------------------------------------------------------- 1 | <%= progress %>% 2 | 3 | <%= title %> 4 | 5 | 6 | -------------------------------------------------------------------------------- /www/src/template/course-lpcategories.html: -------------------------------------------------------------------------------- 1 | 10 | 11 |
12 |
13 | 14 |
15 |
16 | -------------------------------------------------------------------------------- /www/src/template/course-lpcategory-item.html: -------------------------------------------------------------------------------- 1 | 2 |
    3 | -------------------------------------------------------------------------------- /www/src/template/course-notebook.html: -------------------------------------------------------------------------------- 1 |
    2 |

    <%= title %>

    3 |
    4 |
    5 | <%= description %> 6 |
    7 | 15 | -------------------------------------------------------------------------------- /www/src/template/course-notebooks.html: -------------------------------------------------------------------------------- 1 | 10 | 11 |
    12 |
    13 |
    14 | -------------------------------------------------------------------------------- /www/src/template/course.html: -------------------------------------------------------------------------------- 1 |
    2 | <% if (isSpecial) { %> 3 | 4 | <% } %> 5 | <%= title %>'s picture 6 |
    7 |

    <%= title %>

    8 |
    <%= code %>
    9 |

    <%= teachers %>

    10 | 11 | <%= lang.goToCourse %> 12 | 13 |
    14 |
    15 | -------------------------------------------------------------------------------- /www/src/template/home.html: -------------------------------------------------------------------------------- 1 | 32 | 33 |
    34 |
    35 |
    36 |
    37 | -------------------------------------------------------------------------------- /www/src/template/inbox-message.html: -------------------------------------------------------------------------------- 1 |

    2 | <% if (beenSeen) { %> 3 | <%= sender %> 4 | <% } else { %> 5 | <%= sender %> 6 | <% } %> 7 |

    8 | <% if (hasAttachment) { %> 9 | 10 | 11 | 12 | <% } %> 13 |

    14 | <%= title %> 15 |

    16 | -------------------------------------------------------------------------------- /www/src/template/inbox.html: -------------------------------------------------------------------------------- 1 | 10 | 11 |
    12 |
    13 |
    14 | -------------------------------------------------------------------------------- /www/src/template/login.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 | Chamilo Mobile 6 |
    7 |
    8 | Chamilo Mobile 9 |
    10 |
    11 | 44 |
    45 |
    46 |
    47 | -------------------------------------------------------------------------------- /www/src/template/logout.html: -------------------------------------------------------------------------------- 1 |
    2 |

    <%= lang.signingOut %>

    3 |
    4 |
    5 | 100% 6 |
    7 |
    8 |
    9 | -------------------------------------------------------------------------------- /www/src/template/message.html: -------------------------------------------------------------------------------- 1 | 16 | 17 |
    18 |
    19 |
    20 |

    <%= title %>

    21 |
    22 |
    23 | <%= sender %> 24 | <% if (url) { %> 25 | 26 | View in platform 27 | 28 | <% } %> 29 |
    30 | <%= sendDate %> 31 | <% if (hasAttachment) { %> 32 |
    33 | Has attachments 34 | <% } %> 35 |
    36 | <%= content %> 37 |
    38 |
    39 |
    40 | -------------------------------------------------------------------------------- /www/src/template/session-category.html: -------------------------------------------------------------------------------- 1 | <% if (id) { %> 2 | 3 | <% } %> 4 | <% _.each(sessions, function (session) { %> 5 |
    6 |
    7 |

    <%= session.get('name') %>

    8 |
    9 |
    10 |

    11 | 12 | <%= session.get('duration') ? session.get('duration') : session.get('date') %> 13 |

    14 |
    15 | <% _.each(session.get('courses'), function (course) { %> 16 |
    17 |
    18 | <%= course.get('title') %>'s picture 19 |
    20 |

    <%= course.get('title') %>

    21 |
    <%= course.get('code') %>
    22 |

    <%= course.get('teachers') %>

    23 | 24 | <%= lang.goToCourse %> 25 | 26 |
    27 |
    28 |
    29 | <% }); %> 30 |
    31 |
    32 |
    33 | <% }); %> 34 | -------------------------------------------------------------------------------- /www/src/template/spinner.html: -------------------------------------------------------------------------------- 1 | <% if (loading) { %> 2 | 3 | <%= lang.loading %> 4 | <% } else if (noContent) { %> 5 |

    <%= lang.noContentAvailable %>

    6 | <% } %> 7 | -------------------------------------------------------------------------------- /www/src/template/user-profile.html: -------------------------------------------------------------------------------- 1 | 10 | 11 |
    12 | <%= username %>'s picture 13 | 19 |
    20 |
    <%= lang.username %>
    21 |
    <%= username %>
    22 | <% if (phone) { %> 23 |
    <%= lang.phoneNumber %>
    24 |
    <%= phone %>
    25 | <% } %> 26 |
    27 | <% if (extra) { %> 28 |
    29 | <% extra.forEach(function (item) { %> 30 |
    <%= item.title %>
    31 |
    <%= item.value %>
    32 | <% }); %> 33 |
    34 | <% } %> 35 |
    36 | -------------------------------------------------------------------------------- /www/src/view/course-agenda.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-agenda.html', 4 | 'collection/course-events', 5 | 'view/course-event', 6 | 'view/spinner' 7 | ], function (Backbone, viewTemplate, CourseEventsCollection, CourseEventView, SpinnerView) { 8 | var CourseAgendaView = Backbone.View.extend({ 9 | tagName: 'div', 10 | className: 'page-inside', 11 | id: 'course-agenda', 12 | spinner: null, 13 | container: null, 14 | template: _.template(viewTemplate), 15 | initialize: function () { 16 | this.spinner = new SpinnerView(); 17 | 18 | this.collection = new CourseEventsCollection(); 19 | this.collection.on('add', this.renderEvent, this); 20 | }, 21 | render: function () { 22 | var self = this; 23 | 24 | this.el.innerHTML = this.template(); 25 | 26 | this.container = this.$el.find('#container'); 27 | this.container.prepend(this.spinner.render().$el); 28 | 29 | this.collection.fetch() 30 | .always(function () { 31 | if (!self.collection.length) { 32 | self.spinner.stopFailed(); 33 | } 34 | }); 35 | 36 | return this; 37 | }, 38 | renderEvent: function (event, events) { 39 | if (events.length === 1) { 40 | this.spinner.stop(); 41 | } 42 | 43 | var courseEventView = new CourseEventView({ 44 | model: event 45 | }); 46 | 47 | this.$el.find('#ls-course-agenda') 48 | .append(courseEventView.render().el); 49 | 50 | return this; 51 | } 52 | }); 53 | 54 | return CourseAgendaView; 55 | }); 56 | -------------------------------------------------------------------------------- /www/src/view/course-announcement-item.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-announcement-item.html' 4 | ], function (Backbone, viewTemplate) { 5 | var CourseDescriptionItemView = Backbone.View.extend({ 6 | tagName: 'a', 7 | className: 'list-group-item', 8 | attributes: { 9 | href: '#' 10 | }, 11 | template: _.template(viewTemplate), 12 | render: function () { 13 | this.el.innerHTML = this.template(this.model.toJSON()); 14 | 15 | return this; 16 | } 17 | }); 18 | 19 | return CourseDescriptionItemView; 20 | }); 21 | -------------------------------------------------------------------------------- /www/src/view/course-announcement.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-announcement.html', 4 | 'model/course-announcement', 5 | 'view/spinner' 6 | ], function (Backbone, viewTemplate, CourseAnnouncementModel, SpinnerView) { 7 | var CourseAnnouncementView = Backbone.View.extend({ 8 | tagName: 'div', 9 | id: 'course-announcement', 10 | className: 'page-inside', 11 | spinner: null, 12 | container: null, 13 | template: _.template(viewTemplate), 14 | initialize: function () { 15 | this.spinner = new SpinnerView(); 16 | 17 | this.model = new CourseAnnouncementModel(); 18 | this.model.on('change', this.onChange, this); 19 | }, 20 | render: function () { 21 | var self = this; 22 | 23 | this.el.innerHTML = this.template(this.model.toJSON()); 24 | 25 | this.container = this.$el.find('#container'); 26 | this.container.html(this.spinner.render().$el); 27 | 28 | this.model.fetch() 29 | .fail(function () { 30 | if (!self.model.length) { 31 | self.spinner.stopFailed(); 32 | } 33 | }); 34 | 35 | return this; 36 | }, 37 | onChange: function () { 38 | this.spinner.stop(); 39 | 40 | this.el.innerHTML = this.template(this.model.toJSON()); 41 | } 42 | }); 43 | 44 | return CourseAnnouncementView; 45 | }); 46 | -------------------------------------------------------------------------------- /www/src/view/course-announcements.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-announcements.html', 4 | 'collection/course-announcements', 5 | 'view/course-announcement-item', 6 | 'view/spinner' 7 | ], function (Backbone, viewTemplate, CourseAnnouncementsCollection, CourseAnnouncementItemView, SpinnerView) { 8 | var CourseAnnouncementsView = Backbone.View.extend({ 9 | tagName: 'div', 10 | id: 'course-announcements', 11 | className: 'page-inside', 12 | template: _.template(viewTemplate), 13 | spinner: null, 14 | container: null, 15 | initialize: function () { 16 | this.spinner = new SpinnerView(); 17 | 18 | this.collection = new CourseAnnouncementsCollection(); 19 | this.collection.on('add', this.renderAnnouncement, this); 20 | }, 21 | render: function () { 22 | var self = this; 23 | 24 | this.el.innerHTML = this.template(); 25 | 26 | this.container = this.$el.find('#container'); 27 | this.container.prepend(this.spinner.render().el); 28 | 29 | this.collection.fetch() 30 | .always(function () { 31 | if (!self.collection.length) { 32 | self.spinner.stopFailed(); 33 | } 34 | }); 35 | 36 | return this; 37 | }, 38 | renderAnnouncement: function (announcement, announcements) { 39 | if (announcements.length === 1) { 40 | this.spinner.stop(); 41 | } 42 | 43 | var announcementItemView = new CourseAnnouncementItemView({ 44 | model: announcement, 45 | attributes: { 46 | href: '#announcement/' + announcement.get('id') 47 | } 48 | }); 49 | 50 | this.$el.find('#ls-course-announcements') 51 | .append(announcementItemView.render().el); 52 | 53 | return this; 54 | } 55 | }); 56 | 57 | return CourseAnnouncementsView; 58 | }); 59 | -------------------------------------------------------------------------------- /www/src/view/course-description-content.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-description-content.html' 4 | ], function (Backbone, courseDescriptionTemplate) { 5 | var CourseDescriptionView = Backbone.View.extend({ 6 | tagName: 'article', 7 | className: 'tab-pane fade', 8 | attributes: { 9 | 'role': 'tabpanel' 10 | }, 11 | template: _.template(courseDescriptionTemplate), 12 | render: function () { 13 | var id = this.model.get('id'); 14 | 15 | this.$el 16 | .html( 17 | this.template(this.model.toJSON()) 18 | ) 19 | .attr('id', 'description-' + id); 20 | 21 | return this; 22 | } 23 | }); 24 | 25 | return CourseDescriptionView; 26 | }); 27 | -------------------------------------------------------------------------------- /www/src/view/course-description-title.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-description-title.html' 4 | ], function (Backbone, courseDescriptionTemplate) { 5 | var CourseDescriptionView = Backbone.View.extend({ 6 | tagName: 'li', 7 | attributes: { 8 | 'role': 'presentation' 9 | }, 10 | template: _.template(courseDescriptionTemplate), 11 | render: function () { 12 | this.$el 13 | .html( 14 | this.template(this.model.toJSON()) 15 | ); 16 | 17 | return this; 18 | } 19 | }); 20 | 21 | return CourseDescriptionView; 22 | }); 23 | -------------------------------------------------------------------------------- /www/src/view/course-descriptions.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-descriptions.html', 4 | 'collection/course-descriptions', 5 | 'view/course-description-title', 6 | 'view/course-description-content', 7 | 'view/spinner' 8 | ], function ( 9 | Backbone, 10 | courseDescriptionsTemplate, 11 | CourseDescriptionsCollection, 12 | CourseDescriptionTitleView, 13 | CourseDescriptionContentView, 14 | SpinnerView 15 | ) { 16 | var CourseDescriptionsView = Backbone.View.extend({ 17 | tagName: 'div', 18 | className: 'page-inside', 19 | spinner: null, 20 | container: null, 21 | initialize: function () { 22 | this.spinner = new SpinnerView(); 23 | 24 | this.collection = new CourseDescriptionsCollection(); 25 | this.collection.on('add', this.renderDescription, this); 26 | }, 27 | template: _.template(courseDescriptionsTemplate), 28 | render: function () { 29 | var self = this; 30 | 31 | this.el.innerHTML = this.template(); 32 | 33 | this.container = this.$el.find('#container'); 34 | this.container.prepend(this.spinner.render().$el); 35 | 36 | this.collection.fetch() 37 | .always(function () { 38 | if (!self.collection.length) { 39 | self.spinner.stopFailed(); 40 | } 41 | 42 | self.container.find('#ls-course-descriptions .nav.nav-tabs a') 43 | .click(function (e) { 44 | e.preventDefault() 45 | $(this).tab('show') 46 | }); 47 | }); 48 | 49 | return this; 50 | }, 51 | renderDescription: function (description, descriptions) { 52 | var descriptionTitleView = new CourseDescriptionTitleView({ 53 | model: description 54 | }); 55 | 56 | var descriptionContentView = new CourseDescriptionContentView({ 57 | model: description 58 | }); 59 | 60 | this.$el 61 | .find('#ls-course-descriptions ul.nav.nav-tabs') 62 | .append(descriptionTitleView.render().$el); 63 | 64 | this.$el 65 | .find('#ls-course-descriptions div.tab-content') 66 | .append(descriptionContentView.render().$el); 67 | 68 | if (descriptions.length === 1) { 69 | descriptionTitleView.$el.addClass('active'); 70 | descriptionContentView.$el.addClass('in active'); 71 | 72 | this.spinner.stop(); 73 | } 74 | 75 | return this; 76 | } 77 | }); 78 | 79 | return CourseDescriptionsView; 80 | }); 81 | 82 | -------------------------------------------------------------------------------- /www/src/view/course-document.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-document.html' 4 | ], function (Backbone, viewTemplate) { 5 | function onError(error) { 6 | console.error(error); 7 | } 8 | 9 | var CourseDocumentView = Backbone.View.extend({ 10 | tagName: 'div', 11 | className: 'media', 12 | template: _.template(viewTemplate), 13 | render: function () { 14 | this.el.innerHTML = this.template(this.model.toJSON()); 15 | 16 | return this; 17 | }, 18 | events: { 19 | 'click .btn-download': 'btnDownloadOnClick' 20 | }, 21 | btnDownloadOnClick: function (e) { 22 | e.preventDefault(); 23 | 24 | var filePath = this.model.get('path'), 25 | fileURL = this.model.get('url'); 26 | 27 | if (this.model.get('type') !== 'file') { 28 | Backbone.history.navigate('#documents/' + this.model.get('id'), { 29 | trigger: true 30 | }); 31 | 32 | return; 33 | } 34 | 35 | var $pgb = this.$el.find('.progress'), 36 | $txtSuccess = this.$el.find('.text-success'), 37 | $txtDanger = this.$el.find('.text-danger'); 38 | 39 | if (!$pgb.length) { 40 | return; 41 | } 42 | 43 | window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fileSystem) { 44 | fileSystem.root.getDirectory('chamilo-lms', {create: true, exclusive: false}, function (directory) { 45 | $txtDanger.addClass('hidden'); 46 | $txtSuccess.addClass('hidden'); 47 | 48 | $pgb 49 | .removeClass('hidden') 50 | .removeAttr('aria-hidden') 51 | .find('.progress-bar') 52 | .attr('aria-valuenow', 0) 53 | .css('width', 0 + '%') 54 | .find('.sr-only') 55 | .text(0 + '%'); 56 | 57 | var xhrRequest = new XMLHttpRequest(); 58 | xhrRequest.open('GET', fileURL, true); 59 | xhrRequest.responseType = 'blob'; 60 | xhrRequest.onload = function () { 61 | if (this.status != 200) { 62 | $pgb.addClass('hidden'); 63 | $txtDanger.removeClass('hidden'); 64 | 65 | return; 66 | } 67 | 68 | var blob = xhrRequest.response; 69 | 70 | if (!blob) { 71 | $pgb.addClass('hidden'); 72 | $txtDanger.removeClass('hidden'); 73 | } 74 | 75 | saveFile(blob); 76 | }; 77 | xhrRequest.onprogress = function (e) { 78 | var value = e.lengthComputable ? (e.loaded / e.total * 100) : 100; 79 | var percentage = value.toFixed(2); 80 | 81 | $pgb.find('.progress-bar') 82 | .attr('aria-valuenow', percentage) 83 | .css('width', percentage + '%') 84 | .find('.sr-only') 85 | .text(percentage + '%'); 86 | }; 87 | xhrRequest.onerror = function () { 88 | $pgb.addClass('hidden'); 89 | $txtDanger.removeClass('hidden'); 90 | }; 91 | xhrRequest.send(); 92 | 93 | function saveFile(blob) { 94 | var fileNameParts = filePath.split('/').reverse(); 95 | 96 | directory.getFile( 97 | fileNameParts[0], 98 | {create: true, exclusive: true}, 99 | function (fileEntry) { 100 | writeFile(fileEntry, blob) 101 | }, 102 | function (e) { 103 | if (e.code == 12) { 104 | $pgb.addClass('hidden'); 105 | $txtSuccess.removeClass('hidden'); 106 | } 107 | } 108 | ); 109 | } 110 | 111 | function writeFile(fileEntry, blob) { 112 | fileEntry.createWriter(function (fileWriter) { 113 | fileWriter.onwriteend = function () { 114 | $pgb.find('.progress-bar') 115 | .attr('aria-valuenow', 100) 116 | .css('width', 100 + '%') 117 | .find('.sr-only') 118 | .text(100 + '%'); 119 | 120 | $pgb.addClass('hidden'); 121 | $txtSuccess.removeClass('hidden'); 122 | }; 123 | 124 | fileWriter.onerror = function () { 125 | $pgb.addClass('hidden'); 126 | $txtDanger.removeClass('hidden'); 127 | }; 128 | 129 | fileWriter.write(blob) 130 | }); 131 | } 132 | }); 133 | }); 134 | } 135 | }); 136 | 137 | return CourseDocumentView; 138 | }); 139 | -------------------------------------------------------------------------------- /www/src/view/course-documents.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-documents.html', 4 | 'collection/course-documents', 5 | 'view/course-document', 6 | 'view/spinner' 7 | ], function (Backbone, viewTemplate, CourseDocumentsCollection, CourseDocumentView, SpinnerView) { 8 | var CourseDocumentsView = Backbone.View.extend({ 9 | id: 'course-documents', 10 | tagName: 'div', 11 | className: 'page-inside', 12 | spinner: null, 13 | container: null, 14 | initialize: function () { 15 | this.spinner = new SpinnerView(); 16 | 17 | this.collection = new CourseDocumentsCollection(); 18 | this.collection.on('add', this.renderDocument, this); 19 | }, 20 | template: _.template(viewTemplate), 21 | render: function () { 22 | var self = this; 23 | 24 | this.el.innerHTML = this.template(); 25 | 26 | this.container = this.$el.find('#container'); 27 | this.container.prepend(this.spinner.render().$el); 28 | 29 | this.collection.fetch() 30 | .always(function () { 31 | if (self.collection.length) { 32 | return; 33 | } 34 | 35 | self.spinner.stopFailed(); 36 | }); 37 | 38 | return this; 39 | }, 40 | renderDocument: function (document, documents) { 41 | if (documents.length === 1) { 42 | this.spinner.stop(); 43 | } 44 | 45 | document.updateIcon(); 46 | 47 | var courseDocumentView = new CourseDocumentView({ 48 | model: document 49 | }); 50 | 51 | this.$el 52 | .find('#ls-course-documents') 53 | .append(courseDocumentView.render().el); 54 | 55 | return this; 56 | } 57 | }); 58 | 59 | return CourseDocumentsView; 60 | }); 61 | 62 | -------------------------------------------------------------------------------- /www/src/view/course-event.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-event.html' 4 | ], function (Backbone, viewTemplate) { 5 | var CourseEventView = Backbone.View.extend({ 6 | tagName: 'article', 7 | className: 'panel panel-default', 8 | template: _.template(viewTemplate), 9 | render: function () { 10 | this.el 11 | .innerHTML = this.template(this.model.toJSON()); 12 | 13 | return this; 14 | } 15 | }); 16 | 17 | return CourseEventView; 18 | }); 19 | -------------------------------------------------------------------------------- /www/src/view/course-forum.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-forum.html', 4 | 'model/course-forum', 5 | 'view/spinner' 6 | ], function (Backbone, viewTemplate, CourseForumModel, SpinnerView) { 7 | var CourseForumView = Backbone.View.extend({ 8 | tagName: 'div', 9 | id: 'course-forum', 10 | className: 'page-inside', 11 | spinner: null, 12 | container: null, 13 | initialize: function () { 14 | this.spinner = new SpinnerView(); 15 | 16 | this.model = new CourseForumModel(); 17 | this.model.on('change', this.onChange, this); 18 | }, 19 | template: _.template(viewTemplate), 20 | render: function () { 21 | var self = this; 22 | 23 | this.el.innerHTML = this.template(this.model.toJSON()); 24 | 25 | this.container = this.$el.find('#container'); 26 | this.container.html(this.spinner.render().$el); 27 | 28 | this.model.fetch() 29 | .fail(function () { 30 | self.spinner.stopFailed(); 31 | }); 32 | 33 | return this; 34 | }, 35 | onChange: function (forum) { 36 | this.spinner.stop(); 37 | 38 | this.el.innerHTML = this.template(forum.toJSON()); 39 | } 40 | }); 41 | 42 | return CourseForumView; 43 | }); 44 | -------------------------------------------------------------------------------- /www/src/view/course-forumcategories.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-forumcategories.html', 4 | 'collection/course-forumcategories', 5 | 'view/course-forumcategory', 6 | 'view/spinner' 7 | ], function (Backbone, viewTemplate, CourseForumCategoriesCollection, CourseForumCategoryView, SpinnerView) { 8 | var CourseForumCategoriesView = Backbone.View.extend({ 9 | tagName: 'div', 10 | className: 'page-inside', 11 | id: 'course-forumcategories', 12 | spinner: null, 13 | container: null, 14 | initialize: function () { 15 | this.spinner = new SpinnerView(); 16 | 17 | this.collection = new CourseForumCategoriesCollection(); 18 | this.collection.on('add', this.renderForumCategory, this); 19 | }, 20 | template: _.template(viewTemplate), 21 | render: function () { 22 | var self = this; 23 | 24 | this.el.innerHTML = this.template(); 25 | 26 | this.container = this.$el.find('#container'); 27 | this.container.prepend(this.spinner.render().$el); 28 | 29 | this.collection.fetch() 30 | .always(function () { 31 | if (!self.collection.length) { 32 | self.spinner.stopFailed(); 33 | } 34 | }); 35 | 36 | return this; 37 | }, 38 | renderForumCategory: function (forumCategory, categories) { 39 | if (categories.length === 1) { 40 | this.spinner.stop(); 41 | } 42 | 43 | var courseForumCategoryView = new CourseForumCategoryView({ 44 | model: forumCategory 45 | }); 46 | 47 | this.$el.find('#ls-course-forumcategories') 48 | .append(courseForumCategoryView.render().el); 49 | 50 | return this; 51 | } 52 | }); 53 | 54 | return CourseForumCategoriesView; 55 | }); 56 | 57 | -------------------------------------------------------------------------------- /www/src/view/course-forumcategory.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-forumcategory.html' 4 | ], function (Backbone, viewTemplate) { 5 | var CourseForumCategoryView = Backbone.View.extend({ 6 | tagName: 'article', 7 | id: 'forum-category', 8 | className: 'panel panel-default', 9 | template: _.template(viewTemplate), 10 | render: function () { 11 | this.el.innerHTML = this.template(this.model.toJSON()); 12 | 13 | return this; 14 | } 15 | }); 16 | 17 | return CourseForumCategoryView; 18 | }); 19 | -------------------------------------------------------------------------------- /www/src/view/course-forumpost-item.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-forumpost-item.html', 4 | 'model/course-forumpost' 5 | ], function (Backbone, viewTemplate, CourseForumPostModel) { 6 | var campus = null, 7 | courseId = 0; 8 | 9 | var CourseForumPostItemView = Backbone.View.extend({ 10 | tagName: 'article', 11 | className: 'media', 12 | template: _.template(viewTemplate), 13 | initialize: function (options) { 14 | campus = options.campus; 15 | courseId = options.courseId; 16 | }, 17 | render: function () { 18 | this.el.innerHTML = this.template(this.model.toJSON()); 19 | 20 | return this; 21 | }, 22 | events: { 23 | 'show.bs.modal aside.modal': 'modalOnShow', 24 | 'submit form': 'frmOnSubmit' 25 | }, 26 | frmOnSubmit: function (e) { 27 | e.preventDefault(); 28 | 29 | var id = this.model.get('id'), 30 | forumPost = new CourseForumPostModel(); 31 | 32 | var text = this.$el.find('#txt-text-' + id).val(); 33 | 34 | if (!$('#lbl-quote-' + id).is('hidden')) { 35 | text = $('#lbl-quote-' + id).html() + text; 36 | } 37 | 38 | forumPost 39 | .save({ 40 | title: this.$el.find('#txt-title-' + id).val(), 41 | text: text, 42 | parentId: this.$el.find('#txt-parent-' + id).val(), 43 | forumId: this.$el.find('#txt-forum-' + id).val(), 44 | threadId: this.$el.find('#txt-thread-' + id).val() 45 | }, { 46 | courseId: courseId, 47 | notify: this.$el.find('#chk-notify-' + id).is(':checked') ? 1 : 0, 48 | campus: campus 49 | }) 50 | .done(function () { 51 | var currentFragment = Backbone.history.fragment; 52 | 53 | Backbone.history.fragment = null; 54 | Backbone.history.navigate(currentFragment, true); 55 | }) 56 | .fail(function (errorMessage) { 57 | alert(errorMessage ? errorMessage : 'Forum post not saved'); 58 | }); 59 | }, 60 | modalOnShow: function (e) { 61 | var button = $(e.relatedTarget); 62 | 63 | if (!button.data('isquote')) { 64 | this.$el 65 | .find('#lbl-quote-' + this.model.get('id')) 66 | .addClass('hidden'); 67 | 68 | return; 69 | } 70 | 71 | this.$el 72 | .find('#lbl-quote-' + this.model.get('id')) 73 | .removeClass('hidden'); 74 | } 75 | }); 76 | 77 | return CourseForumPostItemView; 78 | }); 79 | -------------------------------------------------------------------------------- /www/src/view/course-forumthread.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-forumthread.html', 4 | 'model/course-forumthread', 5 | 'view/course-forumpost-item', 6 | 'model/course-forumpost', 7 | 'view/spinner' 8 | ], function ( 9 | Backbone, 10 | viewTemplate, 11 | CourseForumThreadModel, 12 | CourseForumPostItemView, 13 | CourseForumPostModel, 14 | SpinnerView 15 | ) { 16 | var CourseForumThreadView = Backbone.View.extend({ 17 | tagName: 'div', 18 | className: 'page-inside', 19 | id: 'forum-thread', 20 | spinner: null, 21 | container: null, 22 | template: _.template(viewTemplate), 23 | initialize: function () { 24 | this.spinner = new SpinnerView(); 25 | 26 | this.model = new CourseForumThreadModel(); 27 | this.model.on('change', this.onChange, this); 28 | }, 29 | render: function () { 30 | var self = this; 31 | 32 | this.el.innerHTML = this.template(this.model.toJSON()); 33 | 34 | this.container = this.$el.find('#container'); 35 | this.container.html(this.spinner.render().$el); 36 | 37 | this.model.fetch() 38 | .fail(function () { 39 | self.spinner.stopFailed(); 40 | }); 41 | 42 | return this; 43 | }, 44 | onChange: function (thread) { 45 | this.el.innerHTML = this.template(thread.toJSON()); 46 | 47 | _.each(thread.get('posts'), this.renderPost, this); 48 | }, 49 | renderPost: function (post) { 50 | var postView = new CourseForumPostItemView({ 51 | model: post, 52 | courseId: this.model.get('cId') 53 | }); 54 | 55 | this.$el 56 | .find('#lst-posts') 57 | .append(postView.render().el); 58 | }, 59 | events: { 60 | 'submit #frm-reply': 'frmReplyOnSubmit' 61 | }, 62 | frmReplyOnSubmit: function (e) { 63 | e.preventDefault(); 64 | 65 | var id = this.model.get('id'), 66 | forumPost = new CourseForumPostModel(); 67 | 68 | forumPost 69 | .save({ 70 | title: this.$el.find('#txt-reply-title').val(), 71 | text: this.$el.find('#txt-reply-text').val(), 72 | forum: this.$el.find('#txt-reply-forum').val(), 73 | threadId: this.$el.find('#txt-reply-thread').val() 74 | }, { 75 | notify: this.$el.find('#chk-notify-' + id).is(':checked') ? 1 : 0 76 | }) 77 | .done(function () { 78 | var currentFragment = Backbone.history.fragment; 79 | 80 | Backbone.history.fragment = null; 81 | Backbone.history.navigate(currentFragment, true); 82 | 83 | $('body').removeClass('modal-open'); 84 | }) 85 | .fail(function (errorMessage) { 86 | alert(errorMessage ? errorMessage : 'Forum post not saved'); 87 | }); 88 | } 89 | }); 90 | 91 | return CourseForumThreadView; 92 | }); 93 | -------------------------------------------------------------------------------- /www/src/view/course-home.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'underscore', 3 | 'backbone', 4 | 'text!template/course-home.html', 5 | 'model/course', 6 | 'view/spinner' 7 | ], function (_, Backbone, courseHomeTemplate, CourseModel, SpinnerView) { 8 | var CourseHomeView = Backbone.View.extend({ 9 | tagName: 'div', 10 | className: 'page-inside', 11 | template: _.template(courseHomeTemplate), 12 | spinner: null, 13 | lblTitle: null, 14 | container: null, 15 | initialize: function () { 16 | this.model = new CourseModel(); 17 | this.model.on('change', this.onChange, this); 18 | 19 | this.spinner = new SpinnerView(); 20 | }, 21 | render: function () { 22 | var self = this; 23 | 24 | this.el.innerHTML = this.template(this.model.toJSON()); 25 | this.lblTitle = this.$el.find('#lbl-title'); 26 | 27 | this.container = this.$el.find('#container'); 28 | this.container.html(this.spinner.render().$el); 29 | 30 | this.model.fetch() 31 | .fail(function () { 32 | self.spinner.stopFailed(); 33 | }); 34 | 35 | return this; 36 | }, 37 | onChange: function (course) { 38 | this.spinner.stop(); 39 | 40 | this.el.innerHTML = this.template(course.toJSON()); 41 | } 42 | }); 43 | 44 | return CourseHomeView; 45 | }); 46 | -------------------------------------------------------------------------------- /www/src/view/course-lp-item.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-lp-item.html', 4 | 'model/course-lp' 5 | ], function (Backbone, viewTemplate, CourseLpModel) { 6 | var CourseLPCategoryItemView = Backbone.View.extend({ 7 | tagName: 'li', 8 | className: 'list-group-item', 9 | initialize: function (options) { 10 | this.model = new CourseLpModel(options.data); 11 | }, 12 | template: _.template(viewTemplate), 13 | render: function () { 14 | this.el.innerHTML = this.template(this.model.toJSON()); 15 | 16 | return this; 17 | } 18 | }); 19 | 20 | return CourseLPCategoryItemView; 21 | }); 22 | -------------------------------------------------------------------------------- /www/src/view/course-lpcategories.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-lpcategories.html', 4 | 'collection/course-lpcategories', 5 | 'view/course-lpcategory-item', 6 | 'view/spinner' 7 | ], function (Backbone, viewTemplate, CourseLpCategoriesCollection, CourseLpCategoryItemView, SpinnerView) { 8 | var CourseLpCategoriesView = Backbone.View.extend({ 9 | tagName: 'div', 10 | id: 'course-lpcategories', 11 | className: 'page-inside', 12 | spinner: null, 13 | container: null, 14 | initialize: function () { 15 | this.spinner = new SpinnerView(); 16 | 17 | this.collection = new CourseLpCategoriesCollection(); 18 | this.collection.on('add', this.renderLpCategory, this); 19 | }, 20 | template: _.template(viewTemplate), 21 | render: function () { 22 | var self = this; 23 | 24 | this.el.innerHTML = this.template(); 25 | 26 | this.container = this.$el.find('#container'); 27 | this.container.prepend(this.spinner.render().$el); 28 | 29 | this.collection.fetch() 30 | .always(function () { 31 | if (!self.collection.length) { 32 | self.spinner.stopFailed(); 33 | } 34 | }); 35 | 36 | return this; 37 | }, 38 | renderLpCategory: function (lpCategory, categories) { 39 | if (categories.length === 1) { 40 | this.spinner.stop(); 41 | } 42 | 43 | var lpCategoryItemView = new CourseLpCategoryItemView({ 44 | model: lpCategory 45 | }); 46 | 47 | this.$el 48 | .find('#ls-course-lpcategories') 49 | .append(lpCategoryItemView.render().el); 50 | 51 | return this; 52 | } 53 | }); 54 | 55 | return CourseLpCategoriesView; 56 | }); 57 | 58 | -------------------------------------------------------------------------------- /www/src/view/course-lpcategory-item.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-lpcategory-item.html', 4 | 'view/course-lp-item' 5 | ], function (Backbone, viewTemplate, CourseLpItemView) { 6 | var CourseLPCategoryItemView = Backbone.View.extend({ 7 | tagName: 'div', 8 | attributes: { 9 | id: 'lpcategory' 10 | }, 11 | template: _.template(viewTemplate), 12 | render: function () { 13 | this.el 14 | .innerHTML = this.template(this.model.toJSON()); 15 | 16 | _.each(this.model.get('learnpaths'), this.renderLp, this); 17 | 18 | return this; 19 | }, 20 | renderLp: function (lpData) { 21 | var lpView = new CourseLpItemView({ 22 | data: lpData 23 | }); 24 | 25 | this.$el 26 | .find('#lst-learning-paths-' + this.model.get('id')) 27 | .append(lpView.render().el); 28 | } 29 | }); 30 | 31 | return CourseLPCategoryItemView; 32 | }); 33 | -------------------------------------------------------------------------------- /www/src/view/course-notebook.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-notebook.html' 4 | ], function (Backbone, viewTemplate) { 5 | var CourseNotebookView = Backbone.View.extend({ 6 | tagName: 'article', 7 | className: 'panel panel-default', 8 | template: _.template(viewTemplate), 9 | render: function () { 10 | this.el.innerHTML = this.template(this.model.toJSON()); 11 | 12 | return this; 13 | } 14 | }); 15 | 16 | return CourseNotebookView; 17 | }); 18 | -------------------------------------------------------------------------------- /www/src/view/course-notebooks.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course-notebooks.html', 4 | 'collection/course-notebooks', 5 | 'view/course-notebook', 6 | 'view/spinner' 7 | ], function (Backbone, viewTemplate, CourseNotebooksCollection, CourseNotebookView, SpinnerView) { 8 | var CourseNotebooksView = Backbone.View.extend({ 9 | tagName: 'div', 10 | id: 'course-notebooks', 11 | className: 'page-inside', 12 | spinner: null, 13 | container: null, 14 | initialize: function () { 15 | this.spinner = new SpinnerView(); 16 | 17 | this.collection = new CourseNotebooksCollection(); 18 | this.collection.on('add', this.renderNotebook, this); 19 | }, 20 | template: _.template(viewTemplate), 21 | render: function () { 22 | var self = this; 23 | 24 | this.el.innerHTML = this.template(); 25 | 26 | this.container = this.$el.find('#container'); 27 | this.container.prepend(this.spinner.render().$el); 28 | 29 | this.collection.fetch() 30 | .always(function () { 31 | if (!self.collection.length) { 32 | self.spinner.stopFailed(); 33 | } 34 | }); 35 | 36 | return this; 37 | }, 38 | renderNotebook: function (notebook, notebooks) { 39 | if (notebooks.length === 1) { 40 | this.spinner.stop(); 41 | } 42 | 43 | var courseNotebookView = new CourseNotebookView({ 44 | model: notebook 45 | }); 46 | 47 | this.$el 48 | .find('#ls-course-notebooks') 49 | .append(courseNotebookView.render().el); 50 | 51 | return this; 52 | }, 53 | events: { 54 | 'click #btn-back': 'btnBackOnClick' 55 | }, 56 | btnBackOnClick: function (e) { 57 | e.preventDefault(); 58 | 59 | window.history.back(); 60 | } 61 | }); 62 | 63 | return CourseNotebooksView; 64 | }); 65 | 66 | -------------------------------------------------------------------------------- /www/src/view/course.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/course.html' 4 | ], function (Backbone, courseTemplate) { 5 | var CourseItemView = Backbone.View.extend({ 6 | tagName: 'div', 7 | className: 'col-xs-12 col-sm-6 col-md-4 col-lg-3', 8 | template: _.template(courseTemplate), 9 | render: function () { 10 | var html = this.template(this.model.toJSON()); 11 | 12 | this.$el.html(html); 13 | 14 | return this; 15 | } 16 | }); 17 | 18 | return CourseItemView; 19 | }); 20 | -------------------------------------------------------------------------------- /www/src/view/home.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/home.html', 4 | 'collection/courses', 5 | 'collection/sessions', 6 | 'view/course', 7 | 'view/session-category', 8 | 'view/spinner' 9 | ], function ( 10 | Backbone, 11 | homeTemplate, 12 | CoursesCollection, 13 | SessionCollection, 14 | CourseView, 15 | SessionCategoryView, 16 | SpinnerView 17 | ) { 18 | var HomeView = Backbone.View.extend({ 19 | tagName: 'div', 20 | className: 'page-inside', 21 | id: 'home', 22 | template: _.template(homeTemplate), 23 | $lstCourses: null, 24 | $lstSessionCategories: null, 25 | spinner: null, 26 | initialize: function () { 27 | this.courseCollection = new CoursesCollection(); 28 | this.courseCollection.on('add', this.onAddCourse, this); 29 | 30 | this.sessionCollection = new SessionCollection(); 31 | this.sessionCollection.on('add', this.onAddSession, this); 32 | 33 | this.spinner = new SpinnerView(); 34 | }, 35 | render: function () { 36 | var self = this; 37 | 38 | this.el.innerHTML = this.template(); 39 | this.$lstCourses = this.$el.find('#lst-courses'); 40 | this.$lstCourses.html(this.spinner.render().$el); 41 | this.$lstSessionCategories = this.$el.find('#lst-session-categories'); 42 | 43 | $ 44 | .when( 45 | this.courseCollection.fetch(), 46 | this.sessionCollection.fetch() 47 | ) 48 | .done(function () { 49 | if (self.courseCollection.length + self.sessionCollection.length > 0) { 50 | self.spinner.stop(); 51 | 52 | return; 53 | } 54 | 55 | self.spinner.stopFailed(); 56 | }); 57 | 58 | return this; 59 | }, 60 | onAddCourse: function (course, collection) { 61 | var courseView = new CourseView({ 62 | model: course 63 | }); 64 | 65 | this.$lstCourses 66 | .append(courseView.render().$el); 67 | }, 68 | onAddSession: function (sessionCategory, collection) { 69 | var sessionCategoryView = new SessionCategoryView({ 70 | model: sessionCategory 71 | }); 72 | 73 | this.$lstSessionCategories 74 | .append(sessionCategoryView.render().$el); 75 | } 76 | }); 77 | 78 | return HomeView; 79 | }); 80 | -------------------------------------------------------------------------------- /www/src/view/inbox-message.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/inbox-message.html' 4 | ], function (Backbone, inboxMessageTemplate) { 5 | var InboxMessageView = Backbone.View.extend({ 6 | tagName: 'a', 7 | className: 'list-group-item', 8 | template: _.template(inboxMessageTemplate), 9 | render: function () { 10 | this.el.setAttribute('href', '#message/' + this.model.cid); 11 | 12 | this.el.innerHTML = this.template(this.model.toJSON()); 13 | 14 | return this; 15 | } 16 | }); 17 | 18 | return InboxMessageView; 19 | }); -------------------------------------------------------------------------------- /www/src/view/inbox.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/inbox.html', 4 | 'collection/messages', 5 | 'view/inbox-message', 6 | 'view/spinner' 7 | ], function (Backbone, inboxTemplate, MessagesCollection, InboxMessageView, SpinnerView) { 8 | var campus = null, 9 | messages = null, 10 | messagesContainer = null; 11 | 12 | var loadMessages = function () { 13 | if (!campus) { 14 | alert('No campus'); 15 | 16 | return; 17 | } 18 | 19 | return $.ajax({ 20 | type: 'post', 21 | data: { 22 | action: 'user_messages', 23 | last: campus.get('lastMessage') 24 | }, 25 | success: function (response) { 26 | if (response.error) { 27 | alert(response.message); 28 | 29 | return; 30 | } 31 | 32 | response.data.reverse(); 33 | 34 | response.data.forEach(function (messageDetail) { 35 | messages.create({ 36 | messageId: parseInt(messageDetail.id), 37 | sender: messageDetail.sender.completeName, 38 | title: messageDetail.title, 39 | content: messageDetail.content, 40 | hasAttachment: messageDetail.hasAttachments, 41 | sendDate: messageDetail.sendDate, 42 | url: messageDetail.url 43 | }); 44 | }); 45 | 46 | if (response.data.length) { 47 | var lastMessage = _.last(response.data); 48 | 49 | campus.save({ 50 | lastMessage: parseInt(lastMessage.id), 51 | lastCheckDate: new Date() 52 | }); 53 | } 54 | } 55 | }); 56 | }; 57 | 58 | function renderInMessageList(message) { 59 | if (!messagesContainer) { 60 | return; 61 | } 62 | 63 | var messageView = new InboxMessageView({ model: message }); 64 | 65 | messagesContainer.prepend( 66 | messageView.render().el 67 | ); 68 | } 69 | 70 | var InboxView = Backbone.View.extend({ 71 | tagName: 'div', 72 | className: 'page-inside', 73 | id: 'inbox', 74 | initialize: function () { 75 | this.collection = new MessagesCollection(); 76 | 77 | campus = this.model; 78 | messages = this.collection; 79 | }, 80 | spinner: new SpinnerView(), 81 | container: null, 82 | template: _.template(inboxTemplate), 83 | render: function () { 84 | var self = this; 85 | 86 | this.el.innerHTML = this.template(); 87 | 88 | messagesContainer = this.$el.find('#lst-messages'); 89 | 90 | this.container = this.$el.find('#container'); 91 | this.container.prepend(this.spinner.render().$el); 92 | 93 | this.collection.fetch() 94 | .done(function () { 95 | messages.each(renderInMessageList); 96 | messages.on('add', renderInMessageList); 97 | 98 | loadMessages() 99 | .done(function () { 100 | self.spinner.stop(); 101 | }); 102 | }); 103 | 104 | return this; 105 | }, 106 | reloadView: function () { 107 | var self = this; 108 | 109 | this.container.prepend(this.spinner.render().$el); 110 | 111 | loadMessages() 112 | .done(function () { 113 | self.spinner.stop(); 114 | }); 115 | } 116 | }); 117 | 118 | return InboxView; 119 | }); -------------------------------------------------------------------------------- /www/src/view/login.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/login.html', 4 | 'model/campus' 5 | ], function (Backbone, loginTemplate, CampusModel) { 6 | var LoginView = Backbone.View.extend({ 7 | tagName: 'div', 8 | id: 'page-login', 9 | template: _.template(loginTemplate), 10 | render: function () { 11 | this.el.innerHTML = this.template(); 12 | 13 | return this; 14 | }, 15 | events: { 16 | 'submit #frm-login': 'frmLoginOnSubmit', 17 | 'click #chk-password': 'chkPasswordOnClick' 18 | }, 19 | frmLoginOnSubmit: function (e) { 20 | e.preventDefault(); 21 | 22 | var frm = this.$el.find('form'), 23 | txtHostName = this.$el.find('#txt-hostname'), 24 | txtUsername = this.$el.find('#txt-username'), 25 | txtPassword = this.$el.find('#txt-password'); 26 | 27 | frm.children().prop('disabled', true); 28 | 29 | var campusDetails = { 30 | url: txtHostName.val().trim(), 31 | username: txtUsername.val().trim() 32 | }; 33 | 34 | $ 35 | .post(campusDetails.url + '/main/webservices/api/v2.php', { 36 | 'action': 'authenticate', 37 | 'username': campusDetails.username, 38 | 'password': txtPassword.val() 39 | }) 40 | .done(function (response) { 41 | if (response.error) { 42 | alert(response.message); 43 | 44 | frm.children().prop('disabled', false); 45 | 46 | return; 47 | } 48 | 49 | campusDetails.apiKey = response.data.apiKey; 50 | campusDetails.gcmSenderId = response.data.gcmSenderId; 51 | 52 | var campus = new CampusModel(); 53 | campus 54 | .save(campusDetails, { 55 | success: function () { 56 | window.location.reload(); 57 | }, 58 | error: function (e) { 59 | alert(e); 60 | 61 | frm.children().prop('disabled', false); 62 | } 63 | }); 64 | }) 65 | .fail(function () { 66 | frm.children().prop('disabled', false); 67 | }); 68 | }, 69 | chkPasswordOnClick: function (e) { 70 | var inputType = e.target.checked ? 'text' : 'password'; 71 | 72 | this.$('#txt-password').attr('type', inputType); 73 | } 74 | }); 75 | 76 | return LoginView; 77 | }); 78 | -------------------------------------------------------------------------------- /www/src/view/logout.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'underscore', 3 | 'backbone', 4 | 'text!template/logout.html', 5 | 'model/campus', 6 | 'model/message' 7 | ], function (_, Backbone, template, CampusModel, MessageModel) { 8 | var LogoutView = Backbone.View.extend({ 9 | tagName: 'div', 10 | id: 'sign-out', 11 | className: 'page-inside', 12 | template: _.template(template), 13 | initialize: function () { 14 | this.campus = new CampusModel(); 15 | this.message = new MessageModel(); 16 | }, 17 | render: function () { 18 | this.el.innerHTML = this.template(); 19 | 20 | return this; 21 | }, 22 | onClear: function (success) { 23 | var clearCampus = this.campus.clear(), 24 | clearMessage = this.message.clear(); 25 | 26 | $.when(clearCampus, clearMessage).done(function () { 27 | if (success) { 28 | success(); 29 | } 30 | 31 | window.location.href = 'index.html'; 32 | }); 33 | } 34 | }); 35 | 36 | return LogoutView; 37 | }); 38 | -------------------------------------------------------------------------------- /www/src/view/message.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/message.html', 4 | 'model/message' 5 | ], function ( 6 | Backbone, 7 | messageTemplate, 8 | MessageModel 9 | ) { 10 | var previousMessage = null, 11 | nextMessage = null; 12 | 13 | var MessageView = Backbone.View.extend({ 14 | tagName: 'div', 15 | className: 'page-inside', 16 | template: _.template(messageTemplate), 17 | btnPrev: null, 18 | btnNext: null, 19 | initialize: function (options) { 20 | var self = this; 21 | 22 | this.model = new MessageModel(); 23 | this.model.id = options.messageId; 24 | this.model.cid = options.messageId; 25 | this.model.fetch({ 26 | success: function () { 27 | self.model.save({ beenSeen: true }); 28 | } 29 | }); 30 | this.model.on('change', this.render, this); 31 | }, 32 | events: { 33 | 'click button#prev-message': 'btnPrevMessageOnClick', 34 | 'click button#next-message': 'btnNextMessageOnClick' 35 | }, 36 | render: function () { 37 | if (!this.model.get('messageId')) { 38 | return this; 39 | } 40 | 41 | var self = this; 42 | 43 | this.el.innerHTML = this.template(this.model.toJSON()); 44 | 45 | this.btnPrev = this.$el.find('#prev-message'); 46 | this.btnNext = this.$el.find('#next-message'); 47 | 48 | this.model.previous({ 49 | success: function (message) { 50 | if (!message) { 51 | return; 52 | } 53 | 54 | previousMessage = message; 55 | 56 | self.btnPrev.removeClass('hide'); 57 | } 58 | }); 59 | this.model.next({ 60 | success: function (message) { 61 | if (!message) { 62 | return; 63 | } 64 | 65 | nextMessage = message; 66 | 67 | self.btnNext.removeClass('hide'); 68 | } 69 | }); 70 | 71 | return this; 72 | }, 73 | btnPrevMessageOnClick: function (e) { 74 | e.preventDefault(); 75 | 76 | if (this.btnPrev.is('.hide')) { 77 | return; 78 | } 79 | 80 | this.model.set(previousMessage.toJSON()); 81 | previousMessage.save({ beenSeen: true }); 82 | }, 83 | btnNextMessageOnClick: function (e) { 84 | e.preventDefault(); 85 | 86 | if (this.btnNext.is('.disabled')) { 87 | return; 88 | } 89 | 90 | this.model.set(nextMessage.toJSON()); 91 | nextMessage.save({ beenSeen: true }); 92 | } 93 | }); 94 | 95 | return MessageView; 96 | }); 97 | -------------------------------------------------------------------------------- /www/src/view/session-category.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/session-category.html' 4 | ], function (Backbone, template) { 5 | var SessionCategoryView = Backbone.View.extend({ 6 | tagName: 'div', 7 | template: _.template(template), 8 | render: function () { 9 | this.el.id = 'session-category-' + this.model.id; 10 | this.el.innerHTML = this.template(this.model.toJSON()); 11 | 12 | return this; 13 | } 14 | }); 15 | 16 | return SessionCategoryView; 17 | }); 18 | -------------------------------------------------------------------------------- /www/src/view/spinner.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'underscore', 3 | 'backbone', 4 | 'text!template/spinner.html', 5 | 'model/spinner' 6 | ], function (_, Backbone, template, SpinnerModel) { 7 | var SpinnerView = Backbone.View.extend({ 8 | tagName: 'div', 9 | className: 'text-center', 10 | template: _.template(template), 11 | initialize: function () { 12 | this.model = new SpinnerModel(); 13 | this.model.on('change', this.onChange, this); 14 | }, 15 | render: function () { 16 | this.el.innerHTML = this.template(this.model.toJSON()); 17 | 18 | return this; 19 | }, 20 | start: function () { 21 | this.model.set({ 22 | loading: true, 23 | noContent: false 24 | }); 25 | }, 26 | stopFailed: function () { 27 | this.model.set({ 28 | loading: false, 29 | noContent: true 30 | }); 31 | }, 32 | stop: function () { 33 | this.$el.detach(); 34 | }, 35 | onChange: function (model, options) { 36 | this.render(); 37 | } 38 | }); 39 | 40 | return SpinnerView; 41 | }); -------------------------------------------------------------------------------- /www/src/view/user-profile.js: -------------------------------------------------------------------------------- 1 | define([ 2 | 'backbone', 3 | 'text!template/user-profile.html', 4 | 'model/user', 5 | 'view/spinner' 6 | ], function (Backbone, userProfileTemplate, UserModel, SpinnerView) { 7 | var UserProfileView = Backbone.View.extend({ 8 | tagName: 'div', 9 | className: 'page-inside', 10 | spinner: null, 11 | container: null, 12 | initialize: function () { 13 | this.spinner = new SpinnerView(); 14 | 15 | this.model = new UserModel(); 16 | this.model.on('change', this.onChange, this); 17 | }, 18 | template: _.template(userProfileTemplate), 19 | render: function () { 20 | var self = this; 21 | 22 | this.el.innerHTML = this.template(this.model.toJSON()); 23 | 24 | this.container = this.$el.find('#container'); 25 | this.container.html(this.spinner.render().$el); 26 | 27 | this.model.fetch() 28 | .fail(function () { 29 | self.spinner.stopFailed(); 30 | }); 31 | 32 | return this; 33 | }, 34 | onChange: function () { 35 | this.el.innerHTML = this.template(this.model.toJSON()); 36 | } 37 | }); 38 | 39 | return UserProfileView; 40 | }); 41 | -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-cyrillic-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-cyrillic-bold.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-cyrillic-ext-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-cyrillic-ext-bold.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-cyrillic-ext-light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-cyrillic-ext-light.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-cyrillic-ext-medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-cyrillic-ext-medium.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-cyrillic-ext-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-cyrillic-ext-regular.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-cyrillic-light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-cyrillic-light.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-cyrillic-medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-cyrillic-medium.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-cyrillic-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-cyrillic-regular.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-greek-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-greek-bold.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-greek-ext-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-greek-ext-bold.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-greek-ext-light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-greek-ext-light.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-greek-ext-medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-greek-ext-medium.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-greek-ext-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-greek-ext-regular.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-greek-light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-greek-light.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-greek-medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-greek-medium.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-greek-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-greek-regular.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-latin-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-latin-bold.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-latin-ext-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-latin-ext-bold.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-latin-ext-light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-latin-ext-light.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-latin-ext-medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-latin-ext-medium.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-latin-ext-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-latin-ext-regular.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-latin-light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-latin-light.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-latin-medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-latin-medium.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-latin-regular.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-vietnamese-bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-vietnamese-bold.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-vietnamese-light.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-vietnamese-light.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-vietnamese-medium.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-vietnamese-medium.woff2 -------------------------------------------------------------------------------- /www/vendor/bootstrap/fonts/roboto-vietnamese-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/bootstrap/fonts/roboto-vietnamese-regular.woff2 -------------------------------------------------------------------------------- /www/vendor/font-awesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/font-awesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /www/vendor/font-awesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/font-awesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /www/vendor/font-awesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/font-awesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /www/vendor/font-awesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/font-awesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /www/vendor/font-awesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chamilo/mobile/016367bc898eb47641b066276e5c6f78c22d3d94/www/vendor/font-awesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /www/vendor/require-i18n/i18n.min.js: -------------------------------------------------------------------------------- 1 | !function(){"use strict";function addPart(locale,master,needed,toLoad,prefix,suffix){master[locale]&&(needed.push(locale),(master[locale]===!0||1===master[locale])&&toLoad.push(prefix+locale+"/"+suffix))}function addIfExists(req,locale,toLoad,prefix,suffix){var fullName=prefix+locale+"/"+suffix;require._fileExists(req.toUrl(fullName+".js"))&&toLoad.push(fullName)}function mixin(target,source,force){var prop;for(prop in source)!source.hasOwnProperty(prop)||target.hasOwnProperty(prop)&&!force?"object"==typeof source[prop]&&(!target[prop]&&source[prop]&&(target[prop]={}),mixin(target[prop],source[prop],force)):target[prop]=source[prop]}var nlsRegExp=/(^.*(^|\/)nls(\/|$))([^\/]*)\/?([^\/]*)/;define(["module"],function(module){var masterConfig=module.config?module.config():{};return{version:"2.0.6",load:function(name,req,onLoad,config){config=config||{},config.locale&&(masterConfig.locale=config.locale);var masterName,i,part,match=nlsRegExp.exec(name),prefix=match[1],locale=match[4],suffix=match[5],parts=locale.split("-"),toLoad=[],value={},current="";if(match[5]?(prefix=match[1],masterName=prefix+suffix):(masterName=name,suffix=match[4],locale=masterConfig.locale,locale||(locale=masterConfig.locale="undefined"==typeof navigator?"root":(navigator.languages&&navigator.languages[0]||navigator.language||navigator.userLanguage||"root").toLowerCase()),parts=locale.split("-")),config.isBuild){for(toLoad.push(masterName),addIfExists(req,"root",toLoad,prefix,suffix),i=0;i-1&&needed[i];i--)part=needed[i],partBundle=master[part],(partBundle===!0||1===partBundle)&&(partBundle=req(prefix+part+"/"+suffix)),mixin(value,partBundle);onLoad(value)})})}}})}(); -------------------------------------------------------------------------------- /www/vendor/require-text/text.min.js: -------------------------------------------------------------------------------- 1 | define(["module"],function(module){var text,fs,Cc,Ci,xpcIsWindows,progIds=["Msxml2.XMLHTTP","Microsoft.XMLHTTP","Msxml2.XMLHTTP.4.0"],xmlRegExp=/^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,bodyRegExp=/]*>\s*([\s\S]+)\s*<\/body>/im,hasLocation=typeof location!=="undefined"&&location.href,defaultProtocol=hasLocation&&location.protocol&&location.protocol.replace(/\:/,""),defaultHostName=hasLocation&&location.hostname,defaultPort=hasLocation&&(location.port||undefined),buildMap={},masterConfig=(module.config&&module.config())||{};text={version:"2.0.12",strip:function(content){if(content){content=content.replace(xmlRegExp,"");var matches=content.match(bodyRegExp);if(matches){content=matches[1]}}else{content=""}return content},jsEscape:function(content){return content.replace(/(['\\])/g,"\\$1").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r").replace(/[\u2028]/g,"\\u2028").replace(/[\u2029]/g,"\\u2029")},createXhr:masterConfig.createXhr||function(){var xhr,i,progId;if(typeof XMLHttpRequest!=="undefined"){return new XMLHttpRequest()}else{if(typeof ActiveXObject!=="undefined"){for(i=0;i<3;i+=1){progId=progIds[i];try{xhr=new ActiveXObject(progId)}catch(e){}if(xhr){progIds=[progId];break}}}}return xhr},parseName:function(name){var modName,ext,temp,strip=false,index=name.indexOf("."),isRelative=name.indexOf("./")===0||name.indexOf("../")===0;if(index!==-1&&(!isRelative||index>1)){modName=name.substring(0,index);ext=name.substring(index+1,name.length)}else{modName=name}temp=ext||modName;index=temp.indexOf("!");if(index!==-1){strip=temp.substring(index+1)==="strip";temp=temp.substring(0,index);if(ext){ext=temp}else{modName=temp}}return{moduleName:modName,ext:ext,strip:strip}},xdRegExp:/^((\w+)\:)?\/\/([^\/\\]+)/,useXhr:function(url,protocol,hostname,port){var uProtocol,uHostName,uPort,match=text.xdRegExp.exec(url);if(!match){return true}uProtocol=match[2];uHostName=match[3];uHostName=uHostName.split(":");uPort=uHostName[1];uHostName=uHostName[0];return(!uProtocol||uProtocol===protocol)&&(!uHostName||uHostName.toLowerCase()===hostname.toLowerCase())&&((!uPort&&!uHostName)||uPort===port)},finishLoad:function(name,strip,content,onLoad){content=strip?text.strip(content):content;if(masterConfig.isBuild){buildMap[name]=content}onLoad(content)},load:function(name,req,onLoad,config){if(config&&config.isBuild&&!config.inlineText){onLoad();return}masterConfig.isBuild=config&&config.isBuild;var parsed=text.parseName(name),nonStripName=parsed.moduleName+(parsed.ext?"."+parsed.ext:""),url=req.toUrl(nonStripName),useXhr=(masterConfig.useXhr)||text.useXhr;if(url.indexOf("empty:")===0){onLoad();return}if(!hasLocation||useXhr(url,defaultProtocol,defaultHostName,defaultPort)){text.get(url,function(content){text.finishLoad(name,parsed.strip,content,onLoad)},function(err){if(onLoad.error){onLoad.error(err)}})}else{req([nonStripName],function(content){text.finishLoad(parsed.moduleName+"."+parsed.ext,parsed.strip,content,onLoad)})}},write:function(pluginName,moduleName,write,config){if(buildMap.hasOwnProperty(moduleName)){var content=text.jsEscape(buildMap[moduleName]);write.asModule(pluginName+"!"+moduleName,"define(function () { return '"+content+"';});\n")}},writeFile:function(pluginName,moduleName,req,write,config){var parsed=text.parseName(moduleName),extPart=parsed.ext?"."+parsed.ext:"",nonStripName=parsed.moduleName+extPart,fileName=req.toUrl(parsed.moduleName+extPart)+".js";text.load(nonStripName,req,function(value){var textWrite=function(contents){return write(fileName,contents)};textWrite.asModule=function(moduleName,contents){return write.asModule(moduleName,fileName,contents)};text.write(pluginName,nonStripName,textWrite,config)},config)}};if(masterConfig.env==="node"||(!masterConfig.env&&typeof process!=="undefined"&&process.versions&&!!process.versions.node&&!process.versions["node-webkit"])){fs=require.nodeRequire("fs");text.get=function(url,callback,errback){try{var file=fs.readFileSync(url,"utf8");if(file.indexOf("\uFEFF")===0){file=file.substring(1)}callback(file)}catch(e){if(errback){errback(e)}}}}else{if(masterConfig.env==="xhr"||(!masterConfig.env&&text.createXhr())){text.get=function(url,callback,errback,headers){var xhr=text.createXhr(),header;xhr.open("GET",url,true);if(headers){for(header in headers){if(headers.hasOwnProperty(header)){xhr.setRequestHeader(header.toLowerCase(),headers[header])}}}if(masterConfig.onXhr){masterConfig.onXhr(xhr,url)}xhr.onreadystatechange=function(evt){var status,err;if(xhr.readyState===4){status=xhr.status||0;if(status>399&&status<600){err=new Error(url+" HTTP status: "+status);err.xhr=xhr;if(errback){errback(err)}}else{callback(xhr.responseText)}if(masterConfig.onXhrComplete){masterConfig.onXhrComplete(xhr,url)}}};xhr.send(null)}}else{if(masterConfig.env==="rhino"||(!masterConfig.env&&typeof Packages!=="undefined"&&typeof java!=="undefined")){text.get=function(url,callback){var stringBuffer,line,encoding="utf-8",file=new java.io.File(url),lineSeparator=java.lang.System.getProperty("line.separator"),input=new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file),encoding)),content="";try{stringBuffer=new java.lang.StringBuffer();line=input.readLine();if(line&&line.length()&&line.charAt(0)===65279){line=line.substring(1)}if(line!==null){stringBuffer.append(line)}while((line=input.readLine())!==null){stringBuffer.append(lineSeparator);stringBuffer.append(line)}content=String(stringBuffer.toString())}finally{input.close()}callback(content)}}else{if(masterConfig.env==="xpconnect"||(!masterConfig.env&&typeof Components!=="undefined"&&Components.classes&&Components.interfaces)){Cc=Components.classes;Ci=Components.interfaces;Components.utils["import"]("resource://gre/modules/FileUtils.jsm");xpcIsWindows=("@mozilla.org/windows-registry-key;1" in Cc);text.get=function(url,callback){var inStream,convertStream,fileObj,readData={};if(xpcIsWindows){url=url.replace(/\//g,"\\")}fileObj=new FileUtils.File(url);try{inStream=Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);inStream.init(fileObj,1,0,false);convertStream=Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);convertStream.init(inStream,"utf-8",inStream.available(),Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);convertStream.readString(inStream.available(),readData);convertStream.close();inStream.close();callback(readData.value)}catch(e){throw new Error((fileObj&&fileObj.path||"")+": "+e)}}}}}}return text}); --------------------------------------------------------------------------------