├── .drone.star ├── .github └── dependabot.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── Makefile ├── README.md ├── appinfo ├── app.php └── info.xml ├── l10n ├── .tx │ └── config ├── Makefile ├── ar.js ├── ar.json ├── bg_BG.js ├── bg_BG.json ├── cs_CZ.js ├── cs_CZ.json ├── de.js ├── de.json ├── de_CH.js ├── de_CH.json ├── de_DE.js ├── de_DE.json ├── el.js ├── el.json ├── en_GB.js ├── en_GB.json ├── es.js ├── es.json ├── es_AR.js ├── es_AR.json ├── es_ES.js ├── es_ES.json ├── et_EE.js ├── et_EE.json ├── fr.js ├── fr.json ├── fr_FR.js ├── fr_FR.json ├── gl.js ├── gl.json ├── he.js ├── he.json ├── is.js ├── is.json ├── it.js ├── it.json ├── ja.js ├── ja.json ├── ko.js ├── ko.json ├── l10n.pl ├── lt_LT.js ├── lt_LT.json ├── nb_NO.js ├── nb_NO.json ├── nl.js ├── nl.json ├── pl.js ├── pl.json ├── pt_BR.js ├── pt_BR.json ├── ru.js ├── ru.json ├── ru_RU.js ├── ru_RU.json ├── si.js ├── si.json ├── sq.js ├── sq.json ├── sv.js ├── sv.json ├── ta.js ├── ta.json ├── th_TH.js ├── th_TH.json ├── tr.js ├── tr.json ├── ug.js ├── ug.json ├── ur_PK.js ├── ur_PK.json ├── zh-Hans.js ├── zh-Hans.json ├── zh.js ├── zh.json ├── zh_CN.js ├── zh_CN.json ├── zh_TW.js └── zh_TW.json ├── package.json ├── src ├── config.json ├── scripts │ ├── Viewer.vue │ ├── ViewerControls.vue │ ├── ViewerControlsImage.vue │ ├── ViewerControlsMeta.vue │ ├── ViewerControlsNavigate.vue │ ├── ViewerControlsVideo.vue │ ├── ViewerSpinner.vue │ ├── default.js │ ├── getEventListeners.js │ ├── helper.js │ ├── ie11routerfix.js │ ├── init.js │ ├── setup.js │ └── store.js └── styles │ ├── _base.scss │ ├── _helper.scss │ ├── _icons.scss │ ├── _spinner.scss │ ├── _swiper.scss │ ├── _transitions.scss │ ├── _viewer.scss │ ├── _viewerControls.scss │ └── default.scss ├── templates └── settings.php ├── webpack.config.js └── yarn.lock /.drone.star: -------------------------------------------------------------------------------- 1 | OC_CI_NODEJS = "owncloudci/nodejs:%s" 2 | PLUGINS_CODE_COV = "plugins/codecov:latest" 3 | PLUGINS_SLACK = "plugins/slack:1" 4 | 5 | DEFAULT_NODEJS_VERSION = "14" 6 | 7 | dir = { 8 | "base": "/var/www/owncloud", 9 | "apps": "/var/www/owncloud/server/apps", 10 | } 11 | 12 | config = { 13 | 'app': 'files_mediaviewer', 14 | 'rocketchat': { 15 | 'channel': 'builds', 16 | 'from_secret': 'private_rocketchat' 17 | }, 18 | 19 | 'branches': [ 20 | 'master' 21 | ], 22 | 23 | 'appInstallCommand': 'make dist', 24 | 25 | 'javascript': {}, 26 | } 27 | 28 | def main(ctx): 29 | before = beforePipelines() 30 | 31 | stages = stagePipelines() 32 | if (stages == False): 33 | print('Errors detected. Review messages above.') 34 | return [] 35 | 36 | dependsOn(before, stages) 37 | 38 | after = afterPipelines() 39 | dependsOn(stages, after) 40 | 41 | return before + stages + after 42 | 43 | def beforePipelines(): 44 | return [] 45 | 46 | def stagePipelines(): 47 | jsPipelines = javascript() 48 | 49 | return jsPipelines 50 | 51 | def afterPipelines(): 52 | return [ 53 | notify() 54 | ] 55 | 56 | def javascript(): 57 | pipelines = [] 58 | 59 | if 'javascript' not in config: 60 | return pipelines 61 | 62 | default = { 63 | 'coverage': False, 64 | 'logLevel': '2', 65 | 'extraSetup': [], 66 | 'extraServices': [], 67 | 'extraEnvironment': {}, 68 | 'extraCommandsBeforeTestRun': [], 69 | } 70 | 71 | if 'defaults' in config: 72 | if 'javascript' in config['defaults']: 73 | for item in config['defaults']['javascript']: 74 | default[item] = config['defaults']['javascript'][item] 75 | 76 | matrix = config['javascript'] 77 | 78 | if type(matrix) == "bool": 79 | if matrix: 80 | # the config has 'javascript' true, so specify an empty dict that will get the defaults 81 | matrix = {} 82 | else: 83 | return pipelines 84 | 85 | params = {} 86 | for item in default: 87 | params[item] = matrix[item] if item in matrix else default[item] 88 | 89 | result = { 90 | 'kind': 'pipeline', 91 | 'type': 'docker', 92 | 'name': 'javascript-tests', 93 | 'workspace' : { 94 | 'base': dir['base'], 95 | 'path': 'server/apps/%s' % config['app'] 96 | }, 97 | 'steps': 98 | installApp() + 99 | params['extraSetup'] + 100 | [ 101 | { 102 | 'name': 'l10n-read', 103 | 'image': OC_CI_NODEJS % getNodeJsVersion(), 104 | 'environment': params['extraEnvironment'], 105 | 'commands': params['extraCommandsBeforeTestRun'] + [ 106 | 'make l10n-read' 107 | ] 108 | } 109 | ], 110 | 'services': params['extraServices'], 111 | 'depends_on': [], 112 | 'trigger': { 113 | 'ref': [ 114 | 'refs/pull/**', 115 | 'refs/tags/**' 116 | ] 117 | } 118 | } 119 | 120 | if params['coverage']: 121 | result['steps'].append({ 122 | 'name': 'codecov-js', 123 | 'image': 'plugins/codecov:latest', 124 | 'settings': { 125 | 'paths': [ 126 | 'coverage/*.info', 127 | ], 128 | 'token': { 129 | 'from_secret': 'codecov_token' 130 | } 131 | } 132 | }) 133 | 134 | for branch in config['branches']: 135 | result['trigger']['ref'].append('refs/heads/%s' % branch) 136 | 137 | return [result] 138 | 139 | def notify(): 140 | result = { 141 | 'kind': 'pipeline', 142 | 'type': 'docker', 143 | 'name': 'chat-notifications', 144 | 'clone': { 145 | 'disable': True 146 | }, 147 | 'steps': [ 148 | { 149 | 'name': 'notify-rocketchat', 150 | 'image': PLUGINS_SLACK, 151 | 'settings': { 152 | 'webhook': { 153 | 'from_secret': config['rocketchat']['from_secret'] 154 | }, 155 | 'channel': config['rocketchat']['channel'] 156 | } 157 | } 158 | ], 159 | 'depends_on': [], 160 | 'trigger': { 161 | 'ref': [ 162 | 'refs/tags/**' 163 | ], 164 | 'status': [ 165 | 'success', 166 | 'failure' 167 | ] 168 | } 169 | } 170 | 171 | for branch in config['branches']: 172 | result['trigger']['ref'].append('refs/heads/%s' % branch) 173 | 174 | return result 175 | 176 | def installApp(): 177 | if 'appInstallCommand' not in config: 178 | return [] 179 | 180 | return [{ 181 | 'name': 'install-app-%s' % config['app'], 182 | 'image': OC_CI_NODEJS % getNodeJsVersion(), 183 | 'commands': [ 184 | 'cd %s/%s' % (dir['apps'], config['app']), 185 | config['appInstallCommand'] 186 | ] 187 | }] 188 | 189 | def getNodeJsVersion(): 190 | if "nodeJsVersion" not in config: 191 | # We use nodejs 14 as the default 192 | return DEFAULT_NODEJS_VERSION 193 | else: 194 | return config["nodeJsVersion"] 195 | 196 | def dependsOn(earlierStages, nextStages): 197 | for earlierStage in earlierStages: 198 | for nextStage in nextStages: 199 | nextStage['depends_on'].append(earlierStage['name']) 200 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: npm 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | time: "22:00" 8 | open-pull-requests-limit: 10 9 | ignore: 10 | - dependency-name: swiper 11 | versions: 12 | - 6.4.10 13 | - 6.4.11 14 | - 6.4.12 15 | - 6.4.14 16 | - 6.4.15 17 | - 6.4.9 18 | - 6.5.0 19 | - 6.5.5 20 | - 6.5.6 21 | - 6.5.7 22 | - dependency-name: css-loader 23 | versions: 24 | - 5.0.1 25 | - 5.0.2 26 | - 5.1.0 27 | - 5.1.1 28 | - 5.1.2 29 | - 5.1.3 30 | - 5.2.0 31 | - 5.2.1 32 | - dependency-name: "@babel/core" 33 | versions: 34 | - 7.12.13 35 | - 7.12.16 36 | - 7.12.17 37 | - 7.13.1 38 | - 7.13.10 39 | - 7.13.13 40 | - 7.13.14 41 | - 7.13.15 42 | - 7.13.8 43 | - dependency-name: y18n 44 | versions: 45 | - 4.0.1 46 | - dependency-name: "@babel/preset-env" 47 | versions: 48 | - 7.13.10 49 | - 7.13.12 50 | - 7.13.9 51 | - dependency-name: webpack-cli 52 | versions: 53 | - 4.4.0 54 | - 4.5.0 55 | - dependency-name: pug-code-gen 56 | versions: 57 | - 3.0.2 58 | - dependency-name: sass-loader 59 | versions: 60 | - 10.1.1 61 | - dependency-name: webpack 62 | versions: 63 | - 4.46.0 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /build/ 3 | /vendor/ 4 | .php_cs.cache 5 | .drone.yml 6 | /tests/output/ 7 | 8 | /js/ 9 | /css/ 10 | /.DS_Store 11 | 12 | /l10n/files_mediaviewer.pot 13 | *.po 14 | 15 | # Generated from .drone.star 16 | .drone.yml 17 | 18 | # IDE Cache 19 | .idea 20 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). 6 | 7 | ## [Unreleased] 8 | 9 | ## [1.0.5] - 2021-11-09 10 | 11 | ### Changed 12 | 13 | - [Security] Bump y18n from 4.0.0 to 4.0.3 - [#400](https://github.com/owncloud/files_mediaviewer/pull/400) 14 | - [Security] Bump ssri from 6.0.1 to 6.0.2 - [#407](https://github.com/owncloud/files_mediaviewer/pull/407) 15 | - Translation updates - [#548](https://github.com/owncloud/files_mediaviewer/pull/548) 16 | - Bump Libraries 17 | 18 | 19 | ## [1.0.4] - 2021-01-10 20 | 21 | ### Added 22 | 23 | - Add icon and correct text in the file actions menu - [#337](https://github.com/owncloud/files_mediaviewer/pull/337) 24 | - Possibly fix Gallery & files_mediaviewer compatibility issue - [#310](https://github.com/owncloud/files_mediaviewer/pull/310) 25 | - Add bgcolor and adopt the height of the video scrubber - [#287](https://github.com/owncloud/files_mediaviewer/pull/287) 26 | 27 | ### Changed 28 | 29 | - Bump libraries 30 | 31 | ## [1.0.3] - 2020-06-23 32 | 33 | ### Added 34 | 35 | - Update config.json to support mimetype video/quicktime - [#194](https://github.com/owncloud/files_mediaviewer/issues/194) 36 | - Add time display to viewer controls - [#225](https://github.com/owncloud/files_mediaviewer/issues/225) 37 | - Add l10n support - [#217](https://github.com/owncloud/files_mediaviewer/issues/217) 38 | 39 | ### Changed 40 | 41 | - Bump libraries 42 | 43 | ## [1.0.2] - 2020-03-17 44 | 45 | ### Added 46 | 47 | - add QT and check playable - [#196](https://github.com/owncloud/files_mediaviewer/issues/196) 48 | 49 | ### Fixed 50 | 51 | - Add notification on playback error - [#109](https://github.com/owncloud/files_mediaviewer/issues/109) 52 | - Fix moderate Cross-Site-Scripting vulnerability - [#163](https://github.com/owncloud/files_mediaviewer/issues/163) 53 | - Fix media controls on small devices - [#164](https://github.com/owncloud/files_mediaviewer/issues/164) 54 | - Encode # in media URI - [#152](https://github.com/owncloud/files_mediaviewer/issues/152) 55 | 56 | ### Changed 57 | 58 | - [Security] Bump serialize-javascript from 1.8.0 to 2.1.2 - [#200](https://github.com/owncloud/files_mediaviewer/issues/200) 59 | - Update dependencies - [#155](https://github.com/owncloud/files_mediaviewer/issues/155) 60 | 61 | ## [1.0.1] - 2019-11-13 62 | 63 | ### Fixed 64 | 65 | - Mobile browser view fix - [#136](https://github.com/owncloud/files_mediaviewer/issues/136) 66 | 67 | ### Added 68 | 69 | - Add fullscreen support for MSIE, Edge and Safari - [#104](https://github.com/owncloud/files_mediaviewer/issues/104) 70 | - Document how to support more media types - [#100](https://github.com/owncloud/files_mediaviewer/issues/100) 71 | 72 | ## 1.0.0 73 | 74 | - Initial release 75 | 76 | [Unreleased]: https://github.com/owncloud/files_mediaviewer/compare/v1.0.5...HEAD 77 | [1.0.5]: https://github.com/owncloud/files_mediaviewer/compare/v1.0.4...v1.0.5 78 | [1.0.4]: https://github.com/owncloud/files_mediaviewer/compare/v1.0.3...v1.0.4 79 | [1.0.3]: https://github.com/owncloud/files_mediaviewer/compare/v1.0.2...v1.0.3 80 | [1.0.2]: https://github.com/owncloud/files_mediaviewer/compare/v1.0.1...v1.0.2 81 | [1.0.1]: https://github.com/owncloud/files_mediaviewer/compare/v1.0.0...v1.0.1 82 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | SHELL := /bin/bash 2 | 3 | YARN := $(shell command -v yarn 2> /dev/null) 4 | ifndef YARN 5 | $(error yarn is not available on your system, please install yarn) 6 | endif 7 | GIT := $(shell command -v git 2> /dev/null) 8 | ifndef GIT 9 | $(error git is not available on your system, please install git) 10 | endif 11 | 12 | 13 | app_name=files_mediaviewer 14 | build_dir=$(CURDIR)/build 15 | dist_dir=$(build_dir)/dist 16 | src_files=README.md LICENSE CHANGELOG.md 17 | src_dirs=appinfo js l10n templates 18 | all_src=$(src_dirs) $(src_files) 19 | 20 | occ=$(CURDIR)/../../occ 21 | private_key=$(HOME)/.owncloud/certificates/$(app_name).key 22 | certificate=$(HOME)/.owncloud/certificates/$(app_name).crt 23 | sign=$(occ) integrity:sign-app --privateKey="$(private_key)" --certificate="$(certificate)" 24 | sign_skip_msg="Skipping signing, either no key and certificate found in $(private_key) and $(certificate) or occ can not be found at $(occ)" 25 | ifneq (,$(wildcard $(private_key))) 26 | ifneq (,$(wildcard $(certificate))) 27 | ifneq (,$(wildcard $(occ))) 28 | CAN_SIGN=true 29 | endif 30 | endif 31 | endif 32 | 33 | .DEFAULT_GOAL := help 34 | 35 | help: 36 | @fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//' 37 | 38 | ## 39 | ## Build targets 40 | ##-------------------------------------- 41 | 42 | .PHONY: dist 43 | dist: ## Build distribution 44 | dist: js-deps build-js distdir sign package 45 | 46 | .PHONY: js-deps 47 | js-deps: 48 | $(YARN) install 49 | 50 | .PHONY: build-js 51 | build-js: 52 | $(YARN) run build 53 | 54 | .PHONY: distdir 55 | distdir: 56 | rm -rf $(dist_dir) 57 | mkdir -p $(dist_dir)/$(app_name) 58 | cp -R $(all_src) $(dist_dir)/$(app_name) 59 | rm -Rf $(dist_dir)/$(app_name)/l10n/.tx 60 | 61 | .PHONY: sign 62 | sign: 63 | ifdef CAN_SIGN 64 | $(sign) --path="$(dist_dir)/$(app_name)" 65 | else 66 | @echo $(sign_skip_msg) 67 | endif 68 | 69 | .PHONY: package 70 | package: 71 | tar --format=gnu -czf $(dist_dir)/$(app_name).tar.gz -C $(dist_dir) $(app_name) 72 | 73 | ## 74 | ## l10n 75 | ##-------------------------------------- 76 | 77 | .PHONY: l10n-clean 78 | l10n-clean: 79 | cd l10n && make clean 80 | 81 | .PHONY: l10n-read 82 | l10n-read: js-deps 83 | cd l10n && make makemessages 84 | 85 | .PHONY: l10n-write 86 | l10n-write: l10n/l10n.pl 87 | perl l10n/l10n.pl files_mediaviewer write 88 | 89 | .PHONY: l10n-push 90 | l10n-push: 91 | cd l10n && tx push -s 92 | 93 | .PHONY: l10n-pull 94 | l10n-pull: 95 | cd l10n && tx pull -a --minimum-perc=15 96 | 97 | l10n/l10n.pl: 98 | wget -qO l10n/l10n.pl https://rawgit.com/ownclouders/7f3e2bdf09e6c7258850d770c0edaf0b/raw/d3ad1673b5449900f85a04f95cdf7e7149140c4f/l10n.pl 99 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # files_mediaviewer 2 | Viewer for pictures and videos integrated in the files app 3 | 4 | ![2018-12-12 13-08-17 2018-12-12 13_09_44](https://user-images.githubusercontent.com/12717530/49868973-43303f00-fe0f-11e8-8f7a-1a5460f51fcd.gif) 5 | 6 | ## Building 7 | 8 | Requires 9 | * Node.js 10 | * yarn 11 | 12 | Run `yarn install && yarn build` to build. 13 | 14 | ## Supporting more media types 15 | 16 | First, make sure you have installed ImageMagick and its imagick PECL extension. 17 | Next add a few new entries to your **config/config.php** configuration file. 18 | 19 | ``` 20 | 'preview_max_scale_factor' => 1, 21 | 'enabledPreviewProviders' => 22 | array ( 23 | 0 => 'OC\\Preview\\PNG', 24 | 1 => 'OC\\Preview\\JPEG', 25 | 2 => 'OC\\Preview\\GIF', 26 | 11 => 'OC\\Preview\\Illustrator', 27 | 12 => 'OC\\Preview\\Postscript', 28 | 13 => 'OC\\Preview\\Photoshop', 29 | 14 => 'OC\\Preview\\TIFF' 30 | ), 31 | ``` 32 | 33 | Look at the sample configuration (config.sample.php) in your config folder if you need more information about how the config file works. 34 | That's it. You should be able to see more media types in your slideshows and galleries as soon as you've installed the app. 35 | -------------------------------------------------------------------------------- /appinfo/app.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | 11 | use OCP\Util; 12 | 13 | Util::addScript('files_mediaviewer', 'files_mediaviewer_init'); -------------------------------------------------------------------------------- /appinfo/info.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | files_mediaviewer 4 | Media Viewer 5 | Explore, show and share your media collections 6 | 7 | A media viewer that adds image and video viewing capabilities to Files view and Public Links. 8 | 9 | **Features** 10 | 11 | - Support for a large selection of image and video formats (depending on server setup) 12 | - Fullscreen, zoomable slideshow view integrated with the Files view and Public Links 13 | - Image rotation 14 | - Sort images by name or date 15 | - Image and video download straight from the slideshow 16 | - Native SVG support 17 | - Mobile support 18 | GPLv2 19 | Felix Heidecke 20 | 1.0.5 21 | Mediaviewer 22 | 23 | https://github.com/owncloud/files_mediaviewer/blob/master/README.md 24 | 25 | https://raw.githubusercontent.com/owncloud/screenshots/master/files_mediaviewer/ownCloud-app-mediaviewer.jpg 26 | multimedia 27 | https://github.com/owncloud/files_mediaviewer 28 | https://github.com/owncloud/files_mediaviewer/issues 29 | https://github.com/owncloud/files_mediaviewer.git 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /l10n/.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com 3 | lang_map = ja_JP: ja 4 | 5 | [o:owncloud-org:p:owncloud:r:files_mediaviewer] 6 | file_filter = /files_mediaviewer.po 7 | source_file = files_mediaviewer.pot 8 | source_lang = en 9 | type = PO 10 | -------------------------------------------------------------------------------- /l10n/Makefile: -------------------------------------------------------------------------------- 1 | NODE_BINDIR = ../node_modules/.bin 2 | export PATH := $(NODE_BINDIR):$(PATH) 3 | 4 | 5 | # Name of the generated .po files for each available locale. 6 | LOCALE_FILES = $(shell find locale -name '*.po') 7 | 8 | GETTEXT_JS_SOURCES = $(shell find ../src -name '*.js') 9 | GETTEXT_VUE_SOURCES = $(shell find ../src -name '*.vue') 10 | GETTEXT_PHP_SOURCES = $(shell find ../lib -name '*.php') 11 | 12 | # Makefile Targets 13 | .PHONY: clean makemessages translations push pull 14 | 15 | clean: 16 | rm -rf files_mediaviewer.pot locale 17 | 18 | makemessages: 19 | touch files_mediaviewer.pot 20 | ../node_modules/.bin/gettext-extract --attribute v-translate \ 21 | --output=files_mediaviewer.pot $(GETTEXT_VUE_SOURCES) 22 | xgettext --language=JavaScript --keyword=t:2 --keyword=n:2,3 \ 23 | --from-code=utf-8 --join-existing --no-wrap \ 24 | --package-name=FilesMediaViewer \ 25 | --package-version=0.0.1 \ 26 | --output=files_mediaviewer.pot $(GETTEXT_JS_SOURCES) 27 | -------------------------------------------------------------------------------- /l10n/ar.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "إغلاق", 5 | "Download" : "تنزيل", 6 | "Fullscreen" : "شاشة كاملة", 7 | "Loading" : "تحميل", 8 | "Mute" : "كتم الصوت", 9 | "Next" : "التالي", 10 | "of" : "من", 11 | "Play" : "تشغيل", 12 | "Previous" : "السابق", 13 | "Replay" : "إعادة التشغيل", 14 | "Rotate 90° counterclockwise" : "تدوير 90° درجة عكس اتجاه عقارب الساعة", 15 | "Zoom in" : "تكبير", 16 | "Zoom out" : "تصغير", 17 | "Open in Media Viewer" : "فتح في عارض الوسائط" 18 | }, 19 | "nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;"); 20 | -------------------------------------------------------------------------------- /l10n/ar.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "إغلاق", 3 | "Download" : "تنزيل", 4 | "Fullscreen" : "شاشة كاملة", 5 | "Loading" : "تحميل", 6 | "Mute" : "كتم الصوت", 7 | "Next" : "التالي", 8 | "of" : "من", 9 | "Play" : "تشغيل", 10 | "Previous" : "السابق", 11 | "Replay" : "إعادة التشغيل", 12 | "Rotate 90° counterclockwise" : "تدوير 90° درجة عكس اتجاه عقارب الساعة", 13 | "Zoom in" : "تكبير", 14 | "Zoom out" : "تصغير", 15 | "Open in Media Viewer" : "فتح في عارض الوسائط" 16 | },"pluralForm" :"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;" 17 | } -------------------------------------------------------------------------------- /l10n/bg_BG.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Затваряне", 5 | "Download" : "Изтегляне", 6 | "Fullscreen" : "Цял екран", 7 | "Loading" : "Зареждане", 8 | "Mute" : "Без звук", 9 | "Next" : "Напред", 10 | "of" : "на", 11 | "Play" : "Възпроизвеждане", 12 | "Previous" : "Предишен", 13 | "Replay" : "Повторение", 14 | "Rotate 90° counterclockwise" : "Завъртане на 90° в посока, обратна на часовниковата стрелка", 15 | "Zoom in" : "Увеличаване", 16 | "Zoom out" : "Намаляване", 17 | "Open in Media Viewer" : "Отваряне в Media Viewer" 18 | }, 19 | "nplurals=2; plural=(n != 1);"); 20 | -------------------------------------------------------------------------------- /l10n/bg_BG.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Затваряне", 3 | "Download" : "Изтегляне", 4 | "Fullscreen" : "Цял екран", 5 | "Loading" : "Зареждане", 6 | "Mute" : "Без звук", 7 | "Next" : "Напред", 8 | "of" : "на", 9 | "Play" : "Възпроизвеждане", 10 | "Previous" : "Предишен", 11 | "Replay" : "Повторение", 12 | "Rotate 90° counterclockwise" : "Завъртане на 90° в посока, обратна на часовниковата стрелка", 13 | "Zoom in" : "Увеличаване", 14 | "Zoom out" : "Намаляване", 15 | "Open in Media Viewer" : "Отваряне в Media Viewer" 16 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 17 | } -------------------------------------------------------------------------------- /l10n/cs_CZ.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Zavřít", 5 | "Download" : "Stáhnout", 6 | "Fullscreen" : "Přes celou obrazovku", 7 | "Loading" : "Načítám", 8 | "Mute" : "Ztlumit", 9 | "Next" : "Další", 10 | "of" : "z", 11 | "Play" : "Přehrát", 12 | "Previous" : "Předchozí", 13 | "Replay" : "Přehrát znovu", 14 | "Rotate 90° counterclockwise" : "Otočit o 90° proti směru hod. ručiček", 15 | "Zoom in" : "Přiblížit", 16 | "Zoom out" : "Oddálit" 17 | }, 18 | "nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;"); 19 | -------------------------------------------------------------------------------- /l10n/cs_CZ.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Zavřít", 3 | "Download" : "Stáhnout", 4 | "Fullscreen" : "Přes celou obrazovku", 5 | "Loading" : "Načítám", 6 | "Mute" : "Ztlumit", 7 | "Next" : "Další", 8 | "of" : "z", 9 | "Play" : "Přehrát", 10 | "Previous" : "Předchozí", 11 | "Replay" : "Přehrát znovu", 12 | "Rotate 90° counterclockwise" : "Otočit o 90° proti směru hod. ručiček", 13 | "Zoom in" : "Přiblížit", 14 | "Zoom out" : "Oddálit" 15 | },"pluralForm" :"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;" 16 | } -------------------------------------------------------------------------------- /l10n/de.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Schließen", 5 | "Download" : "Herunterladen", 6 | "Fullscreen" : "Vollbildschirm", 7 | "Loading" : "Lade", 8 | "Mute" : "Ton aus", 9 | "Next" : "Weiter", 10 | "of" : "von", 11 | "Play" : "Abspielen", 12 | "Previous" : "Zurück", 13 | "Replay" : "Wiedergeben", 14 | "Rotate 90° counterclockwise" : "Um 90° im Uhrzeigersinn drehen", 15 | "Zoom in" : "Vergrößern", 16 | "Zoom out" : "Verkleinern", 17 | "Open in Media Viewer" : "Mit Media Viewer öffnen" 18 | }, 19 | "nplurals=2; plural=(n != 1);"); 20 | -------------------------------------------------------------------------------- /l10n/de.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Schließen", 3 | "Download" : "Herunterladen", 4 | "Fullscreen" : "Vollbildschirm", 5 | "Loading" : "Lade", 6 | "Mute" : "Ton aus", 7 | "Next" : "Weiter", 8 | "of" : "von", 9 | "Play" : "Abspielen", 10 | "Previous" : "Zurück", 11 | "Replay" : "Wiedergeben", 12 | "Rotate 90° counterclockwise" : "Um 90° im Uhrzeigersinn drehen", 13 | "Zoom in" : "Vergrößern", 14 | "Zoom out" : "Verkleinern", 15 | "Open in Media Viewer" : "Mit Media Viewer öffnen" 16 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 17 | } -------------------------------------------------------------------------------- /l10n/de_CH.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Schliessen", 5 | "Download" : "Herunterladen", 6 | "Fullscreen" : "Vollbildschirm", 7 | "Loading" : "Lade", 8 | "Mute" : "Ton aus", 9 | "Next" : "Weiter", 10 | "of" : "von", 11 | "Play" : "Abspielen", 12 | "Previous" : "Zurück", 13 | "Replay" : "Wiedergeben", 14 | "Rotate 90° counterclockwise" : "Um 90° im Uhrzeigersinn drehen", 15 | "Zoom in" : "Vergrössern", 16 | "Zoom out" : "Verkleinern", 17 | "Open in Media Viewer" : "Mit Media Viewer öffnen" 18 | }, 19 | "nplurals=2; plural=(n != 1);"); 20 | -------------------------------------------------------------------------------- /l10n/de_CH.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Schliessen", 3 | "Download" : "Herunterladen", 4 | "Fullscreen" : "Vollbildschirm", 5 | "Loading" : "Lade", 6 | "Mute" : "Ton aus", 7 | "Next" : "Weiter", 8 | "of" : "von", 9 | "Play" : "Abspielen", 10 | "Previous" : "Zurück", 11 | "Replay" : "Wiedergeben", 12 | "Rotate 90° counterclockwise" : "Um 90° im Uhrzeigersinn drehen", 13 | "Zoom in" : "Vergrössern", 14 | "Zoom out" : "Verkleinern", 15 | "Open in Media Viewer" : "Mit Media Viewer öffnen" 16 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 17 | } -------------------------------------------------------------------------------- /l10n/de_DE.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Schließen", 5 | "Download" : "Herunterladen", 6 | "Fullscreen" : "Vollbildschirm", 7 | "Loading" : "Laden", 8 | "Mute" : "Ton aus", 9 | "Next" : "Nächstes", 10 | "of" : "von", 11 | "Play" : "Abspielen", 12 | "Previous" : "Vorheriges", 13 | "Replay" : "Wiederholen", 14 | "Rotate 90° counterclockwise" : "90° gegen den Uhrzeigersinn drehen", 15 | "Zoom in" : "Vergrößern", 16 | "Zoom out" : "Verkleinern", 17 | "Open in Media Viewer" : "Mit Media Viewer öffnen" 18 | }, 19 | "nplurals=2; plural=(n != 1);"); 20 | -------------------------------------------------------------------------------- /l10n/de_DE.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Schließen", 3 | "Download" : "Herunterladen", 4 | "Fullscreen" : "Vollbildschirm", 5 | "Loading" : "Laden", 6 | "Mute" : "Ton aus", 7 | "Next" : "Nächstes", 8 | "of" : "von", 9 | "Play" : "Abspielen", 10 | "Previous" : "Vorheriges", 11 | "Replay" : "Wiederholen", 12 | "Rotate 90° counterclockwise" : "90° gegen den Uhrzeigersinn drehen", 13 | "Zoom in" : "Vergrößern", 14 | "Zoom out" : "Verkleinern", 15 | "Open in Media Viewer" : "Mit Media Viewer öffnen" 16 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 17 | } -------------------------------------------------------------------------------- /l10n/el.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Κλείσιμο", 5 | "Download" : "Λήψη", 6 | "Fullscreen" : "Πλήρης οθόνη", 7 | "Loading" : "Γίνεται φόρτωση", 8 | "Mute" : "Σίγαση", 9 | "Next" : "Επόμενο", 10 | "of" : "του", 11 | "Play" : "Αναπαραγωγή", 12 | "Previous" : "Προηγούμενο", 13 | "Replay" : "Επανάληψη", 14 | "Rotate 90° counterclockwise" : "Περιστροφή 90° αριστερόστροφα", 15 | "Zoom in" : "Μεγέθυνση", 16 | "Zoom out" : "Σμίκρυνση" 17 | }, 18 | "nplurals=2; plural=(n != 1);"); 19 | -------------------------------------------------------------------------------- /l10n/el.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Κλείσιμο", 3 | "Download" : "Λήψη", 4 | "Fullscreen" : "Πλήρης οθόνη", 5 | "Loading" : "Γίνεται φόρτωση", 6 | "Mute" : "Σίγαση", 7 | "Next" : "Επόμενο", 8 | "of" : "του", 9 | "Play" : "Αναπαραγωγή", 10 | "Previous" : "Προηγούμενο", 11 | "Replay" : "Επανάληψη", 12 | "Rotate 90° counterclockwise" : "Περιστροφή 90° αριστερόστροφα", 13 | "Zoom in" : "Μεγέθυνση", 14 | "Zoom out" : "Σμίκρυνση" 15 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 16 | } -------------------------------------------------------------------------------- /l10n/en_GB.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Close", 5 | "Download" : "Download", 6 | "Fullscreen" : "Fullscreen", 7 | "Loading" : "Loading", 8 | "Mute" : "Mute", 9 | "Next" : "Next", 10 | "of" : "of", 11 | "Play" : "Play", 12 | "Previous" : "Previous", 13 | "Replay" : "Replay", 14 | "Rotate 90° counterclockwise" : "Rotate 90° counterclockwise", 15 | "Zoom in" : "Zoom in", 16 | "Zoom out" : "Zoom out", 17 | "Open in Media Viewer" : "Open in Media Viewer" 18 | }, 19 | "nplurals=2; plural=(n != 1);"); 20 | -------------------------------------------------------------------------------- /l10n/en_GB.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Close", 3 | "Download" : "Download", 4 | "Fullscreen" : "Fullscreen", 5 | "Loading" : "Loading", 6 | "Mute" : "Mute", 7 | "Next" : "Next", 8 | "of" : "of", 9 | "Play" : "Play", 10 | "Previous" : "Previous", 11 | "Replay" : "Replay", 12 | "Rotate 90° counterclockwise" : "Rotate 90° counterclockwise", 13 | "Zoom in" : "Zoom in", 14 | "Zoom out" : "Zoom out", 15 | "Open in Media Viewer" : "Open in Media Viewer" 16 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 17 | } -------------------------------------------------------------------------------- /l10n/es.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Cerrar", 5 | "Download" : "Descargar", 6 | "Fullscreen" : "Pantalla completa", 7 | "Loading" : "Cargando", 8 | "Mute" : "Silenciar", 9 | "Next" : "Siguiente", 10 | "of" : "de", 11 | "Play" : "Reproducir", 12 | "Previous" : "Anterior", 13 | "Replay" : "Rehacer", 14 | "Rotate 90° counterclockwise" : "Rotar 90° en sentido antihorario", 15 | "Zoom in" : "Acercar", 16 | "Zoom out" : "Alejar", 17 | "Open in Media Viewer" : "Abrir con Media Viewer" 18 | }, 19 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 20 | -------------------------------------------------------------------------------- /l10n/es.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Cerrar", 3 | "Download" : "Descargar", 4 | "Fullscreen" : "Pantalla completa", 5 | "Loading" : "Cargando", 6 | "Mute" : "Silenciar", 7 | "Next" : "Siguiente", 8 | "of" : "de", 9 | "Play" : "Reproducir", 10 | "Previous" : "Anterior", 11 | "Replay" : "Rehacer", 12 | "Rotate 90° counterclockwise" : "Rotar 90° en sentido antihorario", 13 | "Zoom in" : "Acercar", 14 | "Zoom out" : "Alejar", 15 | "Open in Media Viewer" : "Abrir con Media Viewer" 16 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 17 | } -------------------------------------------------------------------------------- /l10n/es_AR.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Cerrar", 5 | "Download" : "Descargar", 6 | "Fullscreen" : "Pantalla completa", 7 | "Loading" : "Cargando", 8 | "Mute" : "Silenciar", 9 | "Next" : "Siguiente", 10 | "of" : "de", 11 | "Play" : "Reproducir", 12 | "Previous" : "Anterior", 13 | "Replay" : "Repetir", 14 | "Rotate 90° counterclockwise" : "Rotar 90º en sentido antihorario", 15 | "Zoom in" : "Acercar", 16 | "Zoom out" : "Alejar" 17 | }, 18 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 19 | -------------------------------------------------------------------------------- /l10n/es_AR.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Cerrar", 3 | "Download" : "Descargar", 4 | "Fullscreen" : "Pantalla completa", 5 | "Loading" : "Cargando", 6 | "Mute" : "Silenciar", 7 | "Next" : "Siguiente", 8 | "of" : "de", 9 | "Play" : "Reproducir", 10 | "Previous" : "Anterior", 11 | "Replay" : "Repetir", 12 | "Rotate 90° counterclockwise" : "Rotar 90º en sentido antihorario", 13 | "Zoom in" : "Acercar", 14 | "Zoom out" : "Alejar" 15 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 16 | } -------------------------------------------------------------------------------- /l10n/es_ES.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Cerrar", 5 | "Next" : "Siguiente", 6 | "Play" : "Reproducir", 7 | "Previous" : "Previo" 8 | }, 9 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 10 | -------------------------------------------------------------------------------- /l10n/es_ES.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Cerrar", 3 | "Next" : "Siguiente", 4 | "Play" : "Reproducir", 5 | "Previous" : "Previo" 6 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 7 | } -------------------------------------------------------------------------------- /l10n/et_EE.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Sulge", 5 | "Download" : "Laadi alla", 6 | "Fullscreen" : "äisekraanil", 7 | "Loading" : "Laadimine", 8 | "Mute" : "Vaigista", 9 | "Next" : "Järgmine", 10 | "Play" : "Esita", 11 | "Previous" : "Eelmine", 12 | "Replay" : "Esita uuesti" 13 | }, 14 | "nplurals=2; plural=(n != 1);"); 15 | -------------------------------------------------------------------------------- /l10n/et_EE.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Sulge", 3 | "Download" : "Laadi alla", 4 | "Fullscreen" : "äisekraanil", 5 | "Loading" : "Laadimine", 6 | "Mute" : "Vaigista", 7 | "Next" : "Järgmine", 8 | "Play" : "Esita", 9 | "Previous" : "Eelmine", 10 | "Replay" : "Esita uuesti" 11 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 12 | } -------------------------------------------------------------------------------- /l10n/fr.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Fermer", 5 | "Download" : "Télécharger", 6 | "Fullscreen" : "Plein écran", 7 | "Loading" : "Chargement", 8 | "Mute" : "Muet", 9 | "Next" : "Suivant", 10 | "of" : "sur", 11 | "Play" : "Lire", 12 | "Previous" : "Précédent", 13 | "Replay" : "Relire", 14 | "Rotate 90° counterclockwise" : "Rotation de 90° dans le sens anti-horaire", 15 | "Zoom in" : "Zoomer", 16 | "Zoom out" : "Dé-zoomer", 17 | "Open in Media Viewer" : "Ouvrir avec Media Viewer" 18 | }, 19 | "nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 20 | -------------------------------------------------------------------------------- /l10n/fr.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Fermer", 3 | "Download" : "Télécharger", 4 | "Fullscreen" : "Plein écran", 5 | "Loading" : "Chargement", 6 | "Mute" : "Muet", 7 | "Next" : "Suivant", 8 | "of" : "sur", 9 | "Play" : "Lire", 10 | "Previous" : "Précédent", 11 | "Replay" : "Relire", 12 | "Rotate 90° counterclockwise" : "Rotation de 90° dans le sens anti-horaire", 13 | "Zoom in" : "Zoomer", 14 | "Zoom out" : "Dé-zoomer", 15 | "Open in Media Viewer" : "Ouvrir avec Media Viewer" 16 | },"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 17 | } -------------------------------------------------------------------------------- /l10n/fr_FR.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Fermer", 5 | "Download" : "Télécharger", 6 | "Next" : "Suivant", 7 | "Play" : "Lecture", 8 | "Previous" : "Précédent" 9 | }, 10 | "nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 11 | -------------------------------------------------------------------------------- /l10n/fr_FR.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Fermer", 3 | "Download" : "Télécharger", 4 | "Next" : "Suivant", 5 | "Play" : "Lecture", 6 | "Previous" : "Précédent" 7 | },"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 8 | } -------------------------------------------------------------------------------- /l10n/gl.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Pechar", 5 | "Download" : "Descargar", 6 | "Fullscreen" : "Pantalla completa", 7 | "Loading" : "Cargando", 8 | "Mute" : "Silenciar", 9 | "Next" : "Seguinte", 10 | "of" : "de", 11 | "Play" : "Reproducir", 12 | "Previous" : "Anterior", 13 | "Replay" : "Repetir", 14 | "Rotate 90° counterclockwise" : "Rotar 90° no sentido contrario das agullas do reloxo", 15 | "Zoom in" : "Achegar", 16 | "Zoom out" : "Afastar" 17 | }, 18 | "nplurals=2; plural=(n != 1);"); 19 | -------------------------------------------------------------------------------- /l10n/gl.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Pechar", 3 | "Download" : "Descargar", 4 | "Fullscreen" : "Pantalla completa", 5 | "Loading" : "Cargando", 6 | "Mute" : "Silenciar", 7 | "Next" : "Seguinte", 8 | "of" : "de", 9 | "Play" : "Reproducir", 10 | "Previous" : "Anterior", 11 | "Replay" : "Repetir", 12 | "Rotate 90° counterclockwise" : "Rotar 90° no sentido contrario das agullas do reloxo", 13 | "Zoom in" : "Achegar", 14 | "Zoom out" : "Afastar" 15 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 16 | } -------------------------------------------------------------------------------- /l10n/he.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "סגירה", 5 | "Download" : "הורדה", 6 | "Fullscreen" : "מסך מלא", 7 | "Loading" : "טעינה", 8 | "Mute" : "השתקה", 9 | "Next" : "הבא", 10 | "of" : "מתוך", 11 | "Play" : "נגינה", 12 | "Previous" : "הקודם", 13 | "Replay" : "לנגן מחדש", 14 | "Rotate 90° counterclockwise" : "להטות ב־90° נגד כיוון השעון", 15 | "Zoom in" : "התקרבות", 16 | "Zoom out" : "התרחקות", 17 | "Open in Media Viewer" : "פתיחה במציג מדיה" 18 | }, 19 | "nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;"); 20 | -------------------------------------------------------------------------------- /l10n/he.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "סגירה", 3 | "Download" : "הורדה", 4 | "Fullscreen" : "מסך מלא", 5 | "Loading" : "טעינה", 6 | "Mute" : "השתקה", 7 | "Next" : "הבא", 8 | "of" : "מתוך", 9 | "Play" : "נגינה", 10 | "Previous" : "הקודם", 11 | "Replay" : "לנגן מחדש", 12 | "Rotate 90° counterclockwise" : "להטות ב־90° נגד כיוון השעון", 13 | "Zoom in" : "התקרבות", 14 | "Zoom out" : "התרחקות", 15 | "Open in Media Viewer" : "פתיחה במציג מדיה" 16 | },"pluralForm" :"nplurals=3; plural=(n == 1 && n % 1 == 0) ? 0 : (n == 2 && n % 1 == 0) ? 1: 2;" 17 | } -------------------------------------------------------------------------------- /l10n/is.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Loka", 5 | "Download" : "Sækja", 6 | "Fullscreen" : "Fullskjár", 7 | "Loading" : "Hleð", 8 | "Mute" : "Þagga", 9 | "Next" : "Næsta", 10 | "of" : "af", 11 | "Play" : "Spila", 12 | "Previous" : "Fyrri", 13 | "Replay" : "Endurspila", 14 | "Rotate 90° counterclockwise" : "Snua 90° andsælis", 15 | "Zoom in" : "Þysja inn", 16 | "Zoom out" : "Þysja út" 17 | }, 18 | "nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);"); 19 | -------------------------------------------------------------------------------- /l10n/is.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Loka", 3 | "Download" : "Sækja", 4 | "Fullscreen" : "Fullskjár", 5 | "Loading" : "Hleð", 6 | "Mute" : "Þagga", 7 | "Next" : "Næsta", 8 | "of" : "af", 9 | "Play" : "Spila", 10 | "Previous" : "Fyrri", 11 | "Replay" : "Endurspila", 12 | "Rotate 90° counterclockwise" : "Snua 90° andsælis", 13 | "Zoom in" : "Þysja inn", 14 | "Zoom out" : "Þysja út" 15 | },"pluralForm" :"nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);" 16 | } -------------------------------------------------------------------------------- /l10n/it.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Chiudi", 5 | "Download" : "Scarica", 6 | "Fullscreen" : "Schermo Intero", 7 | "Loading" : "Caricamento", 8 | "Mute" : "Silenzia", 9 | "Next" : "Successivo", 10 | "of" : "di", 11 | "Play" : "Riproduci", 12 | "Previous" : "Precedente", 13 | "Replay" : "Riavvia", 14 | "Rotate 90° counterclockwise" : "Ruotare di 90° in senso antiorario", 15 | "Zoom in" : "Ingrandire", 16 | "Zoom out" : "Rimpicciolire", 17 | "Open in Media Viewer" : "Apri in Media Viewer" 18 | }, 19 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 20 | -------------------------------------------------------------------------------- /l10n/it.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Chiudi", 3 | "Download" : "Scarica", 4 | "Fullscreen" : "Schermo Intero", 5 | "Loading" : "Caricamento", 6 | "Mute" : "Silenzia", 7 | "Next" : "Successivo", 8 | "of" : "di", 9 | "Play" : "Riproduci", 10 | "Previous" : "Precedente", 11 | "Replay" : "Riavvia", 12 | "Rotate 90° counterclockwise" : "Ruotare di 90° in senso antiorario", 13 | "Zoom in" : "Ingrandire", 14 | "Zoom out" : "Rimpicciolire", 15 | "Open in Media Viewer" : "Apri in Media Viewer" 16 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 17 | } -------------------------------------------------------------------------------- /l10n/ja.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "閉じる", 5 | "Download" : "ダウンロード", 6 | "Fullscreen" : "フルスクリーン", 7 | "Loading" : "読込中", 8 | "Mute" : "ミュート", 9 | "Next" : "次", 10 | "of" : "of", 11 | "Play" : "再生", 12 | "Previous" : "前", 13 | "Replay" : "リプレイ", 14 | "Rotate 90° counterclockwise" : "90°左回り", 15 | "Zoom in" : "ズームイン", 16 | "Zoom out" : "ズームアウト", 17 | "Open in Media Viewer" : "メディアビューアで開く" 18 | }, 19 | "nplurals=1; plural=0;"); 20 | -------------------------------------------------------------------------------- /l10n/ja.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "閉じる", 3 | "Download" : "ダウンロード", 4 | "Fullscreen" : "フルスクリーン", 5 | "Loading" : "読込中", 6 | "Mute" : "ミュート", 7 | "Next" : "次", 8 | "of" : "of", 9 | "Play" : "再生", 10 | "Previous" : "前", 11 | "Replay" : "リプレイ", 12 | "Rotate 90° counterclockwise" : "90°左回り", 13 | "Zoom in" : "ズームイン", 14 | "Zoom out" : "ズームアウト", 15 | "Open in Media Viewer" : "メディアビューアで開く" 16 | },"pluralForm" :"nplurals=1; plural=0;" 17 | } -------------------------------------------------------------------------------- /l10n/ko.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "닫기", 5 | "Download" : "다운로드", 6 | "Fullscreen" : "전체화면", 7 | "Loading" : "로딩", 8 | "Mute" : "음소거", 9 | "Next" : "다음", 10 | "Play" : "재생", 11 | "Previous" : "이전", 12 | "Replay" : "다시 재생", 13 | "Rotate 90° counterclockwise" : "시계방향으로 90도 회전", 14 | "Zoom in" : "확대", 15 | "Zoom out" : "축소", 16 | "Open in Media Viewer" : "미디어 뷰어로 열기" 17 | }, 18 | "nplurals=1; plural=0;"); 19 | -------------------------------------------------------------------------------- /l10n/ko.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "닫기", 3 | "Download" : "다운로드", 4 | "Fullscreen" : "전체화면", 5 | "Loading" : "로딩", 6 | "Mute" : "음소거", 7 | "Next" : "다음", 8 | "Play" : "재생", 9 | "Previous" : "이전", 10 | "Replay" : "다시 재생", 11 | "Rotate 90° counterclockwise" : "시계방향으로 90도 회전", 12 | "Zoom in" : "확대", 13 | "Zoom out" : "축소", 14 | "Open in Media Viewer" : "미디어 뷰어로 열기" 15 | },"pluralForm" :"nplurals=1; plural=0;" 16 | } -------------------------------------------------------------------------------- /l10n/l10n.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | use strict; 3 | use version; 4 | use Locale::PO; 5 | use Cwd; 6 | use Data::Dumper; 7 | use File::Path; 8 | use File::Basename; 9 | use File::Spec; 10 | use Digest::MD5 qw(md5 md5_hex md5_base64); 11 | 12 | sub crawlFiles{ 13 | my( $dir ) = @_; 14 | my @found = (); 15 | 16 | opendir( DIR, $dir ); 17 | my @files = readdir( DIR ); 18 | closedir( DIR ); 19 | @files = sort( @files ); 20 | 21 | foreach my $i ( @files ){ 22 | next if substr( $i, 0, 1 ) eq '.'; 23 | next if $i eq 'l10n'; 24 | 25 | if( -d $dir.'/'.$i ){ 26 | push( @found, crawlFiles( $dir.'/'.$i )); 27 | } 28 | else{ 29 | push(@found,$dir.'/'.$i) if $i =~ /.*(?){ 41 | my $line = $_; 42 | chomp($line); 43 | $ignore{"./$line"}++; 44 | } 45 | close(IN); 46 | return %ignore; 47 | } 48 | 49 | sub getPluralInfo { 50 | my( $info ) = @_; 51 | 52 | # get string 53 | $info =~ s/.*Plural-Forms: (.+)\\n.*/$1/; 54 | $info =~ s/^(.*)\\n.*/$1/g; 55 | 56 | return $info; 57 | } 58 | 59 | sub init() { 60 | # let's get the version from stdout of xgettext 61 | my $out = `xgettext --version`; 62 | # we assume the first line looks like this 'xgettext (GNU gettext-tools) 0.19.3' 63 | $out = substr $out, 29, index($out, "\n")-29; 64 | $out =~ s/^\s+|\s+$//g; 65 | $out = "v" . $out; 66 | my $actual = version->parse($out); 67 | # 0.18.3 introduced JavaScript as a language option 68 | my $expected = version->parse('v0.18.3'); 69 | if ($actual < $expected) { 70 | die( "Minimum expected version of xgettext is " . $expected . ". Detected: " . $actual ); 71 | } 72 | } 73 | 74 | init(); 75 | 76 | my $app = shift( @ARGV ); 77 | my $task = shift( @ARGV ); 78 | 79 | die( "Usage: l10n.pl app task\ntask: read, write\n" ) unless $task; 80 | 81 | # Our current position 82 | my $whereami = dirname(File::Spec->rel2abs( __FILE__ )); 83 | die( "Program must be executed in a l10n-folder called 'l10n'" ) unless $whereami =~ m/\/l10n$/; 84 | 85 | # Where are i18n-files? 86 | my $pwd = dirname(File::Spec->rel2abs( __FILE__ )); 87 | chdir($pwd); 88 | 89 | my @dirs = (); 90 | push(@dirs, $pwd); 91 | 92 | # Languages 93 | my @languages = (); 94 | opendir( DIR, '.' ); 95 | my @files = readdir( DIR ); 96 | closedir( DIR ); 97 | foreach my $i ( @files ){ 98 | push( @languages, $i ) if -d $i && substr( $i, 0, 1 ) ne '.'; 99 | } 100 | 101 | if( $task eq 'read' ){ 102 | rmtree( 'templates' ); 103 | mkdir( 'templates' ) unless -d 'templates'; 104 | print "Mode: reading\n"; 105 | foreach my $dir ( @dirs ){ 106 | my @temp = split( /\//, $dir ); 107 | chdir( $dir ); 108 | my @totranslate = crawlFiles('.'); 109 | my %ignore = readIgnorelist(); 110 | my $output = "${whereami}/templates/$app.pot"; 111 | my $packageName = "ownCloud $app"; 112 | print " Processing $app\n"; 113 | 114 | foreach my $file ( @totranslate ){ 115 | next if $ignore{$file}; 116 | my $keywords = ''; 117 | if( $file =~ /\.js$/ ){ 118 | $keywords = '--keyword=t:2 --keyword=n:2,3'; 119 | } 120 | else{ 121 | $keywords = '--keyword=t --keyword=n:1,2'; 122 | } 123 | my $language = ( $file =~ /\.js$/ ? 'Javascript' : 'PHP'); 124 | my $joinexisting = ( -e $output ? '--join-existing' : ''); 125 | print " Reading $file\n"; 126 | `xgettext --output="$output" $joinexisting $keywords --language=$language "$file" --add-comments=TRANSLATORS --from-code=UTF-8 --package-version="8.0.0" --package-name="$packageName" --msgid-bugs-address="translations\@owncloud.org"`; 127 | } 128 | chdir( $whereami ); 129 | } 130 | } 131 | elsif( $task eq 'write' ){ 132 | print "Mode: write\n"; 133 | foreach my $dir ( @dirs ){ 134 | my @temp = split( /\//, $dir ); 135 | chdir( $dir.'/l10n' ); 136 | print " Processing $app\n"; 137 | foreach my $language ( @languages ){ 138 | next if $language eq 'templates'; 139 | 140 | my $input = "${whereami}/$language/$app.po"; 141 | next unless -e $input; 142 | 143 | print " Language $language\n"; 144 | my $array = Locale::PO->load_file_asarray( $input ); 145 | # Create array 146 | my @strings = (); 147 | my @js_strings = (); 148 | my $plurals; 149 | 150 | TRANSLATIONS: foreach my $string ( @{$array} ){ 151 | if( $string->msgid() eq '""' ){ 152 | # Translator information 153 | $plurals = getPluralInfo( $string->msgstr()); 154 | } 155 | elsif( defined( $string->msgstr_n() )){ 156 | # plural translations 157 | my @variants = (); 158 | my $msgid = $string->msgid(); 159 | $msgid =~ s/^"(.*)"$/$1/; 160 | my $msgid_plural = $string->msgid_plural(); 161 | $msgid_plural =~ s/^"(.*)"$/$1/; 162 | my $identifier = "_" . $msgid."_::_".$msgid_plural . "_"; 163 | 164 | foreach my $variant ( sort { $a <=> $b} keys( %{$string->msgstr_n()} )){ 165 | next TRANSLATIONS if $string->msgstr_n()->{$variant} eq '""'; 166 | push( @variants, $string->msgstr_n()->{$variant} ); 167 | } 168 | 169 | push( @strings, "\"$identifier\" => array(".join(",", @variants).")"); 170 | push( @js_strings, "\"$identifier\" : [".join(",", @variants)."]"); 171 | } 172 | else{ 173 | # singular translations 174 | next TRANSLATIONS if $string->msgstr() eq '""'; 175 | push( @strings, $string->msgid()." => ".$string->msgstr()); 176 | push( @js_strings, $string->msgid()." : ".$string->msgstr()); 177 | } 178 | } 179 | next if $#strings == -1; # Skip empty files 180 | 181 | for (@strings) { 182 | s/\$/\\\$/g; 183 | } 184 | 185 | # delete old php file 186 | unlink "$language.php"; 187 | 188 | # Write js file 189 | open( OUT, ">$language.js" ); 190 | print OUT "OC.L10N.register(\n \"$app\",\n {\n "; 191 | print OUT join( ",\n ", @js_strings ); 192 | print OUT "\n},\n\"$plurals\");\n"; 193 | close( OUT ); 194 | 195 | # Write json file 196 | open( OUT, ">$language.json" ); 197 | print OUT "{ \"translations\": "; 198 | print OUT "{\n "; 199 | print OUT join( ",\n ", @js_strings ); 200 | print OUT "\n},\"pluralForm\" :\"$plurals\"\n}"; 201 | close( OUT ); 202 | 203 | } 204 | chdir( $whereami ); 205 | } 206 | } else { 207 | print "unknown task!\n"; 208 | } 209 | -------------------------------------------------------------------------------- /l10n/lt_LT.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Užverti", 5 | "Download" : "Atsisiųsti", 6 | "Fullscreen" : "Visas ekranas", 7 | "Loading" : "Įkeliama", 8 | "Mute" : "Nutildyti", 9 | "Next" : "Kitas", 10 | "of" : "iš", 11 | "Play" : "Atkurti", 12 | "Previous" : "Ankstesnis", 13 | "Replay" : "Atkurti iš naujo", 14 | "Rotate 90° counterclockwise" : "Pasukti 90° prieš laikrodžio rodyklę", 15 | "Zoom in" : "Didinti", 16 | "Zoom out" : "Mažinti" 17 | }, 18 | "nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);"); 19 | -------------------------------------------------------------------------------- /l10n/lt_LT.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Užverti", 3 | "Download" : "Atsisiųsti", 4 | "Fullscreen" : "Visas ekranas", 5 | "Loading" : "Įkeliama", 6 | "Mute" : "Nutildyti", 7 | "Next" : "Kitas", 8 | "of" : "iš", 9 | "Play" : "Atkurti", 10 | "Previous" : "Ankstesnis", 11 | "Replay" : "Atkurti iš naujo", 12 | "Rotate 90° counterclockwise" : "Pasukti 90° prieš laikrodžio rodyklę", 13 | "Zoom in" : "Didinti", 14 | "Zoom out" : "Mažinti" 15 | },"pluralForm" :"nplurals=4; plural=(n % 10 == 1 && (n % 100 > 19 || n % 100 < 11) ? 0 : (n % 10 >= 2 && n % 10 <=9) && (n % 100 > 19 || n % 100 < 11) ? 1 : n % 1 != 0 ? 2: 3);" 16 | } -------------------------------------------------------------------------------- /l10n/nb_NO.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Lukk", 5 | "Download" : "Last ned", 6 | "Fullscreen" : "Fullskjerm", 7 | "Loading" : "Laster", 8 | "Mute" : "Demp", 9 | "Next" : "Neste", 10 | "of" : "av", 11 | "Play" : "Spill", 12 | "Previous" : "Forrige", 13 | "Replay" : "Spill på nytt", 14 | "Rotate 90° counterclockwise" : "Roter 90° mot klokka", 15 | "Zoom in" : "Zoom inn", 16 | "Zoom out" : "Zoom ut" 17 | }, 18 | "nplurals=2; plural=(n != 1);"); 19 | -------------------------------------------------------------------------------- /l10n/nb_NO.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Lukk", 3 | "Download" : "Last ned", 4 | "Fullscreen" : "Fullskjerm", 5 | "Loading" : "Laster", 6 | "Mute" : "Demp", 7 | "Next" : "Neste", 8 | "of" : "av", 9 | "Play" : "Spill", 10 | "Previous" : "Forrige", 11 | "Replay" : "Spill på nytt", 12 | "Rotate 90° counterclockwise" : "Roter 90° mot klokka", 13 | "Zoom in" : "Zoom inn", 14 | "Zoom out" : "Zoom ut" 15 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 16 | } -------------------------------------------------------------------------------- /l10n/nl.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Sluiten", 5 | "Download" : "Downloaden", 6 | "Fullscreen" : "Volledig scherm", 7 | "Loading" : "Laden", 8 | "Mute" : "Dempen", 9 | "Next" : "Volgende", 10 | "of" : "van", 11 | "Play" : "Spelen", 12 | "Previous" : "Vorige", 13 | "Replay" : "Herhalen", 14 | "Rotate 90° counterclockwise" : "Draai 90 ° tegen de klok in", 15 | "Zoom in" : "Inzoomen", 16 | "Zoom out" : "Uitzoomen" 17 | }, 18 | "nplurals=2; plural=(n != 1);"); 19 | -------------------------------------------------------------------------------- /l10n/nl.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Sluiten", 3 | "Download" : "Downloaden", 4 | "Fullscreen" : "Volledig scherm", 5 | "Loading" : "Laden", 6 | "Mute" : "Dempen", 7 | "Next" : "Volgende", 8 | "of" : "van", 9 | "Play" : "Spelen", 10 | "Previous" : "Vorige", 11 | "Replay" : "Herhalen", 12 | "Rotate 90° counterclockwise" : "Draai 90 ° tegen de klok in", 13 | "Zoom in" : "Inzoomen", 14 | "Zoom out" : "Uitzoomen" 15 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 16 | } -------------------------------------------------------------------------------- /l10n/pl.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Zamknij", 5 | "Download" : "Pobierz", 6 | "Fullscreen" : "Pełny ekran", 7 | "Loading" : "Ładowanie", 8 | "Mute" : "Wycisz", 9 | "Next" : "Następny", 10 | "of" : "z", 11 | "Play" : "Odtwarzaj", 12 | "Previous" : "Poprzedni", 13 | "Replay" : "Powtarzaj", 14 | "Rotate 90° counterclockwise" : "Obróć o 90° przeciwnie do ruchu wskazówek zegara", 15 | "Zoom in" : "Przybliż", 16 | "Zoom out" : "Oddal" 17 | }, 18 | "nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);"); 19 | -------------------------------------------------------------------------------- /l10n/pl.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Zamknij", 3 | "Download" : "Pobierz", 4 | "Fullscreen" : "Pełny ekran", 5 | "Loading" : "Ładowanie", 6 | "Mute" : "Wycisz", 7 | "Next" : "Następny", 8 | "of" : "z", 9 | "Play" : "Odtwarzaj", 10 | "Previous" : "Poprzedni", 11 | "Replay" : "Powtarzaj", 12 | "Rotate 90° counterclockwise" : "Obróć o 90° przeciwnie do ruchu wskazówek zegara", 13 | "Zoom in" : "Przybliż", 14 | "Zoom out" : "Oddal" 15 | },"pluralForm" :"nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);" 16 | } -------------------------------------------------------------------------------- /l10n/pt_BR.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Fechar", 5 | "Download" : "Baixar", 6 | "Fullscreen" : "Tela cheia", 7 | "Loading" : "Carregando", 8 | "Mute" : "Mudar", 9 | "Next" : "Próximo", 10 | "of" : "de", 11 | "Play" : "Executar", 12 | "Previous" : "Anterior", 13 | "Replay" : "Responder", 14 | "Rotate 90° counterclockwise" : "Rotacionar 90º no sentido dos ponteiros do relógio", 15 | "Zoom in" : "Ampliar", 16 | "Zoom out" : "Diminuir", 17 | "Open in Media Viewer" : "Abrir no Visualizador de Mídia" 18 | }, 19 | "nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 20 | -------------------------------------------------------------------------------- /l10n/pt_BR.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Fechar", 3 | "Download" : "Baixar", 4 | "Fullscreen" : "Tela cheia", 5 | "Loading" : "Carregando", 6 | "Mute" : "Mudar", 7 | "Next" : "Próximo", 8 | "of" : "de", 9 | "Play" : "Executar", 10 | "Previous" : "Anterior", 11 | "Replay" : "Responder", 12 | "Rotate 90° counterclockwise" : "Rotacionar 90º no sentido dos ponteiros do relógio", 13 | "Zoom in" : "Ampliar", 14 | "Zoom out" : "Diminuir", 15 | "Open in Media Viewer" : "Abrir no Visualizador de Mídia" 16 | },"pluralForm" :"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 17 | } -------------------------------------------------------------------------------- /l10n/ru.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Закрыть", 5 | "Download" : "Скачать", 6 | "Fullscreen" : "В полный экран", 7 | "Loading" : "Загрузка", 8 | "Mute" : "Тишина", 9 | "Next" : "Следующее", 10 | "of" : "из", 11 | "Play" : "Играть", 12 | "Previous" : "Предыдущее", 13 | "Replay" : "Повтор", 14 | "Rotate 90° counterclockwise" : "Повернуть на 90° против часовой стрелки", 15 | "Zoom in" : "Приблизить", 16 | "Zoom out" : "Отдалить", 17 | "Open in Media Viewer" : "Открыть в просмотре медиа" 18 | }, 19 | "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"); 20 | -------------------------------------------------------------------------------- /l10n/ru.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Закрыть", 3 | "Download" : "Скачать", 4 | "Fullscreen" : "В полный экран", 5 | "Loading" : "Загрузка", 6 | "Mute" : "Тишина", 7 | "Next" : "Следующее", 8 | "of" : "из", 9 | "Play" : "Играть", 10 | "Previous" : "Предыдущее", 11 | "Replay" : "Повтор", 12 | "Rotate 90° counterclockwise" : "Повернуть на 90° против часовой стрелки", 13 | "Zoom in" : "Приблизить", 14 | "Zoom out" : "Отдалить", 15 | "Open in Media Viewer" : "Открыть в просмотре медиа" 16 | },"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);" 17 | } -------------------------------------------------------------------------------- /l10n/ru_RU.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Закрыть", 5 | "Download" : "Загрузка", 6 | "Fullscreen" : "В полный экран", 7 | "Loading" : "Загрузка", 8 | "Mute" : "Тишина", 9 | "Next" : "Следующее", 10 | "of" : "из", 11 | "Play" : "Играть", 12 | "Previous" : "Предыдущее", 13 | "Replay" : "Повтор", 14 | "Rotate 90° counterclockwise" : "Повернуть на 90° против часовой стрелки", 15 | "Zoom in" : "Приблизить", 16 | "Zoom out" : "Отдалить", 17 | "Open in Media Viewer" : "Открыть в просмотре медиа" 18 | }, 19 | "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"); 20 | -------------------------------------------------------------------------------- /l10n/ru_RU.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Закрыть", 3 | "Download" : "Загрузка", 4 | "Fullscreen" : "В полный экран", 5 | "Loading" : "Загрузка", 6 | "Mute" : "Тишина", 7 | "Next" : "Следующее", 8 | "of" : "из", 9 | "Play" : "Играть", 10 | "Previous" : "Предыдущее", 11 | "Replay" : "Повтор", 12 | "Rotate 90° counterclockwise" : "Повернуть на 90° против часовой стрелки", 13 | "Zoom in" : "Приблизить", 14 | "Zoom out" : "Отдалить", 15 | "Open in Media Viewer" : "Открыть в просмотре медиа" 16 | },"pluralForm" :"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);" 17 | } -------------------------------------------------------------------------------- /l10n/si.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "වසන්න", 5 | "Download" : "බාන්න", 6 | "Next" : "ඊලඟ", 7 | "of" : "ගේ", 8 | "Play" : "ධාවනය", 9 | "Previous" : "පෙර" 10 | }, 11 | "nplurals=2; plural=(n != 1);"); 12 | -------------------------------------------------------------------------------- /l10n/si.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "වසන්න", 3 | "Download" : "බාන්න", 4 | "Next" : "ඊලඟ", 5 | "of" : "ගේ", 6 | "Play" : "ධාවනය", 7 | "Previous" : "පෙර" 8 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 9 | } -------------------------------------------------------------------------------- /l10n/sq.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Mbylle", 5 | "Download" : "Shkarkoje", 6 | "Fullscreen" : "Sa krejt ekrani", 7 | "Loading" : "Po ngarkohet", 8 | "Mute" : "Heshtoje", 9 | "Next" : "Pasuesi", 10 | "of" : "nga", 11 | "Play" : "Luaje", 12 | "Previous" : "I mëparshmi", 13 | "Replay" : "Riluaje", 14 | "Rotate 90° counterclockwise" : "Rrotulloje 90° në kahun kundërorar", 15 | "Zoom in" : "Zmadhoje", 16 | "Zoom out" : "Zvogëloje", 17 | "Open in Media Viewer" : "Hape në Parës Mediash" 18 | }, 19 | "nplurals=2; plural=(n != 1);"); 20 | -------------------------------------------------------------------------------- /l10n/sq.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Mbylle", 3 | "Download" : "Shkarkoje", 4 | "Fullscreen" : "Sa krejt ekrani", 5 | "Loading" : "Po ngarkohet", 6 | "Mute" : "Heshtoje", 7 | "Next" : "Pasuesi", 8 | "of" : "nga", 9 | "Play" : "Luaje", 10 | "Previous" : "I mëparshmi", 11 | "Replay" : "Riluaje", 12 | "Rotate 90° counterclockwise" : "Rrotulloje 90° në kahun kundërorar", 13 | "Zoom in" : "Zmadhoje", 14 | "Zoom out" : "Zvogëloje", 15 | "Open in Media Viewer" : "Hape në Parës Mediash" 16 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 17 | } -------------------------------------------------------------------------------- /l10n/sv.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Stäng", 5 | "Download" : "Ladda ned", 6 | "Fullscreen" : "Fullskärm", 7 | "Loading" : "Laddar", 8 | "Mute" : "Ljudlös", 9 | "Next" : "Nästa", 10 | "of" : "av", 11 | "Play" : "Spela", 12 | "Previous" : "Föregående", 13 | "Replay" : "Repris", 14 | "Rotate 90° counterclockwise" : "Rotera 90° moturs", 15 | "Zoom in" : "Zooma in", 16 | "Zoom out" : "Zooma ut", 17 | "Open in Media Viewer" : "Öppna i Mediavisaren" 18 | }, 19 | "nplurals=2; plural=(n != 1);"); 20 | -------------------------------------------------------------------------------- /l10n/sv.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Stäng", 3 | "Download" : "Ladda ned", 4 | "Fullscreen" : "Fullskärm", 5 | "Loading" : "Laddar", 6 | "Mute" : "Ljudlös", 7 | "Next" : "Nästa", 8 | "of" : "av", 9 | "Play" : "Spela", 10 | "Previous" : "Föregående", 11 | "Replay" : "Repris", 12 | "Rotate 90° counterclockwise" : "Rotera 90° moturs", 13 | "Zoom in" : "Zooma in", 14 | "Zoom out" : "Zooma ut", 15 | "Open in Media Viewer" : "Öppna i Mediavisaren" 16 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 17 | } -------------------------------------------------------------------------------- /l10n/ta.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "மூடுக", 5 | "Download" : "பதிவிறக்குக", 6 | "Next" : "அடுத்த", 7 | "of" : "உடைய", 8 | "Play" : "Play", 9 | "Previous" : "முன்தைய" 10 | }, 11 | "nplurals=2; plural=(n != 1);"); 12 | -------------------------------------------------------------------------------- /l10n/ta.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "மூடுக", 3 | "Download" : "பதிவிறக்குக", 4 | "Next" : "அடுத்த", 5 | "of" : "உடைய", 6 | "Play" : "Play", 7 | "Previous" : "முன்தைய" 8 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 9 | } -------------------------------------------------------------------------------- /l10n/th_TH.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "ปิด", 5 | "Download" : "ดาวน์โหลด", 6 | "Fullscreen" : "เต็มจอ", 7 | "Loading" : "กำลังโหลด", 8 | "Mute" : "เงียบ", 9 | "Next" : "ต่อไป", 10 | "of" : "ของ", 11 | "Play" : "เล่น", 12 | "Previous" : "ก่อนหน้า", 13 | "Replay" : "เล่นใหม่", 14 | "Rotate 90° counterclockwise" : "หมุนทวนเข็ม 90°", 15 | "Zoom in" : "ซูมเข้า", 16 | "Zoom out" : "ซูมออก", 17 | "Open in Media Viewer" : "เปิดด้วย Media Viewer" 18 | }, 19 | "nplurals=1; plural=0;"); 20 | -------------------------------------------------------------------------------- /l10n/th_TH.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "ปิด", 3 | "Download" : "ดาวน์โหลด", 4 | "Fullscreen" : "เต็มจอ", 5 | "Loading" : "กำลังโหลด", 6 | "Mute" : "เงียบ", 7 | "Next" : "ต่อไป", 8 | "of" : "ของ", 9 | "Play" : "เล่น", 10 | "Previous" : "ก่อนหน้า", 11 | "Replay" : "เล่นใหม่", 12 | "Rotate 90° counterclockwise" : "หมุนทวนเข็ม 90°", 13 | "Zoom in" : "ซูมเข้า", 14 | "Zoom out" : "ซูมออก", 15 | "Open in Media Viewer" : "เปิดด้วย Media Viewer" 16 | },"pluralForm" :"nplurals=1; plural=0;" 17 | } -------------------------------------------------------------------------------- /l10n/tr.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "Kapat", 5 | "Download" : "İndir", 6 | "Fullscreen" : "Tam Ekran", 7 | "Loading" : "Yükleniyor", 8 | "Mute" : "Sessiz", 9 | "Next" : "Sonraki", 10 | "of" : "/", 11 | "Play" : "Oynat", 12 | "Previous" : "Önceki", 13 | "Replay" : "Yeniden Oynat", 14 | "Rotate 90° counterclockwise" : "90° saat yönünün tersine döndür", 15 | "Zoom in" : "Yakınlaştır", 16 | "Zoom out" : "uzaklaştır", 17 | "Open in Media Viewer" : "Medya Görüntüleyicide Aç" 18 | }, 19 | "nplurals=2; plural=(n > 1);"); 20 | -------------------------------------------------------------------------------- /l10n/tr.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "Kapat", 3 | "Download" : "İndir", 4 | "Fullscreen" : "Tam Ekran", 5 | "Loading" : "Yükleniyor", 6 | "Mute" : "Sessiz", 7 | "Next" : "Sonraki", 8 | "of" : "/", 9 | "Play" : "Oynat", 10 | "Previous" : "Önceki", 11 | "Replay" : "Yeniden Oynat", 12 | "Rotate 90° counterclockwise" : "90° saat yönünün tersine döndür", 13 | "Zoom in" : "Yakınlaştır", 14 | "Zoom out" : "uzaklaştır", 15 | "Open in Media Viewer" : "Medya Görüntüleyicide Aç" 16 | },"pluralForm" :"nplurals=2; plural=(n > 1);" 17 | } -------------------------------------------------------------------------------- /l10n/ug.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "تاقاش", 5 | "Download" : "چۈشۈرۈش", 6 | "Fullscreen" : "تولۇق ئېكران", 7 | "Loading" : "يۈكلەۋاتىدۇ", 8 | "Mute" : "Mute", 9 | "Next" : "كېيىنكى", 10 | "of" : "of", 11 | "Play" : "قوي", 12 | "Previous" : "ئالدىنقى", 13 | "Replay" : "Replay", 14 | "Rotate 90° counterclockwise" : "سائەتكە قارشى 90 ° ئايلاندۇرۇڭ", 15 | "Zoom in" : "چوڭايتىش", 16 | "Zoom out" : "چوڭايتىڭ", 17 | "Open in Media Viewer" : "Media Viewer دا ئېچىڭ" 18 | }, 19 | "nplurals=2; plural=(n != 1);"); 20 | -------------------------------------------------------------------------------- /l10n/ug.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "تاقاش", 3 | "Download" : "چۈشۈرۈش", 4 | "Fullscreen" : "تولۇق ئېكران", 5 | "Loading" : "يۈكلەۋاتىدۇ", 6 | "Mute" : "Mute", 7 | "Next" : "كېيىنكى", 8 | "of" : "of", 9 | "Play" : "قوي", 10 | "Previous" : "ئالدىنقى", 11 | "Replay" : "Replay", 12 | "Rotate 90° counterclockwise" : "سائەتكە قارشى 90 ° ئايلاندۇرۇڭ", 13 | "Zoom in" : "چوڭايتىش", 14 | "Zoom out" : "چوڭايتىڭ", 15 | "Open in Media Viewer" : "Media Viewer دا ئېچىڭ" 16 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 17 | } -------------------------------------------------------------------------------- /l10n/ur_PK.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "بند", 5 | "Download" : "ڈون لوڈ", 6 | "Fullscreen" : "فل سکرین ", 7 | "Loading" : "لوڈنگ ", 8 | "Mute" : "آواز بند ", 9 | "Next" : "آگے", 10 | "of" : "آف", 11 | "Play" : "پلے", 12 | "Previous" : "پیچھے", 13 | "Replay" : "دوبارہ پلے", 14 | "Rotate 90° counterclockwise" : "90° گھماوگھڑی کی سمت ", 15 | "Zoom in" : "زوم ان", 16 | "Zoom out" : "زوم آوٹ " 17 | }, 18 | "nplurals=2; plural=(n != 1);"); 19 | -------------------------------------------------------------------------------- /l10n/ur_PK.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "بند", 3 | "Download" : "ڈون لوڈ", 4 | "Fullscreen" : "فل سکرین ", 5 | "Loading" : "لوڈنگ ", 6 | "Mute" : "آواز بند ", 7 | "Next" : "آگے", 8 | "of" : "آف", 9 | "Play" : "پلے", 10 | "Previous" : "پیچھے", 11 | "Replay" : "دوبارہ پلے", 12 | "Rotate 90° counterclockwise" : "90° گھماوگھڑی کی سمت ", 13 | "Zoom in" : "زوم ان", 14 | "Zoom out" : "زوم آوٹ " 15 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 16 | } -------------------------------------------------------------------------------- /l10n/zh-Hans.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "关闭", 5 | "Next" : "下一首", 6 | "Play" : "播放", 7 | "Previous" : "上一首" 8 | }, 9 | "nplurals=1; plural=0;"); 10 | -------------------------------------------------------------------------------- /l10n/zh-Hans.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "关闭", 3 | "Next" : "下一首", 4 | "Play" : "播放", 5 | "Previous" : "上一首" 6 | },"pluralForm" :"nplurals=1; plural=0;" 7 | } -------------------------------------------------------------------------------- /l10n/zh.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Next" : "下一首", 5 | "Play" : "播放", 6 | "Previous" : "上一首" 7 | }, 8 | "nplurals=1; plural=0;"); 9 | -------------------------------------------------------------------------------- /l10n/zh.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Next" : "下一首", 3 | "Play" : "播放", 4 | "Previous" : "上一首" 5 | },"pluralForm" :"nplurals=1; plural=0;" 6 | } -------------------------------------------------------------------------------- /l10n/zh_CN.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "关闭", 5 | "Download" : "下载", 6 | "Fullscreen" : "全屏", 7 | "Loading" : "加载中", 8 | "Mute" : "静音", 9 | "Next" : "下一个", 10 | "of" : "在", 11 | "Play" : "播放", 12 | "Previous" : "上一个", 13 | "Replay" : "重播", 14 | "Rotate 90° counterclockwise" : "逆时针旋转 90°", 15 | "Zoom in" : "放大", 16 | "Zoom out" : "缩小", 17 | "Open in Media Viewer" : "使用媒体查看器打开" 18 | }, 19 | "nplurals=1; plural=0;"); 20 | -------------------------------------------------------------------------------- /l10n/zh_CN.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "关闭", 3 | "Download" : "下载", 4 | "Fullscreen" : "全屏", 5 | "Loading" : "加载中", 6 | "Mute" : "静音", 7 | "Next" : "下一个", 8 | "of" : "在", 9 | "Play" : "播放", 10 | "Previous" : "上一个", 11 | "Replay" : "重播", 12 | "Rotate 90° counterclockwise" : "逆时针旋转 90°", 13 | "Zoom in" : "放大", 14 | "Zoom out" : "缩小", 15 | "Open in Media Viewer" : "使用媒体查看器打开" 16 | },"pluralForm" :"nplurals=1; plural=0;" 17 | } -------------------------------------------------------------------------------- /l10n/zh_TW.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "files_mediaviewer", 3 | { 4 | "Close" : "關閉", 5 | "Download" : "下載", 6 | "Fullscreen" : "全螢幕", 7 | "Loading" : "載入中", 8 | "Mute" : "靜音", 9 | "Next" : "下一個", 10 | "of" : "的", 11 | "Play" : "播放", 12 | "Previous" : "上一個", 13 | "Replay" : "重播", 14 | "Rotate 90° counterclockwise" : "逆時針旋轉 90°", 15 | "Zoom in" : "放大", 16 | "Zoom out" : "縮小" 17 | }, 18 | "nplurals=1; plural=0;"); 19 | -------------------------------------------------------------------------------- /l10n/zh_TW.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Close" : "關閉", 3 | "Download" : "下載", 4 | "Fullscreen" : "全螢幕", 5 | "Loading" : "載入中", 6 | "Mute" : "靜音", 7 | "Next" : "下一個", 8 | "of" : "的", 9 | "Play" : "播放", 10 | "Previous" : "上一個", 11 | "Replay" : "重播", 12 | "Rotate 90° counterclockwise" : "逆時針旋轉 90°", 13 | "Zoom in" : "放大", 14 | "Zoom out" : "縮小" 15 | },"pluralForm" :"nplurals=1; plural=0;" 16 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "files_mediaviewer", 3 | "version": "1.0.1", 4 | "description": "Viewer for pictures and videos integrated in the files app", 5 | "dependencies": { 6 | "@types/moment-duration-format": "^2.2.6", 7 | "easygettext": "^2.17.0", 8 | "moment-duration-format": "^2.3.2", 9 | "svelte": "^3.x", 10 | "swiper": "^7.2.0", 11 | "vue": "^2.7.16", 12 | "vue-router": "^3.6.5", 13 | "vuex": "^3.6.2" 14 | }, 15 | "devDependencies": { 16 | "@babel/core": "^7.24.6", 17 | "@babel/preset-env": "^7.24.6", 18 | "babel-loader": "^8.2.5", 19 | "css-loader": "^6.11.0", 20 | "sass": "^1.77.5", 21 | "sass-loader": "^12.1.0", 22 | "style-loader": "^3.3.4", 23 | "vue-loader": "^15.11.1", 24 | "vue-template-compiler": "^2.7.16", 25 | "webpack": "^5.91.0", 26 | "webpack-cli": "^4.10.0" 27 | }, 28 | "scripts": { 29 | "build": "webpack --progress --mode=production", 30 | "watch": "webpack --watch --mode=development" 31 | }, 32 | "repository": { 33 | "type": "git", 34 | "url": "git+https://github.com/owncloud/files_mediaviewer.git" 35 | }, 36 | "keywords": [ 37 | "owncloud", 38 | "media", 39 | "gallery" 40 | ], 41 | "author": "Felix Heidecke", 42 | "license": "GPL-2.0", 43 | "bugs": { 44 | "url": "https://github.com/owncloud/files_mediaviewer/issues" 45 | }, 46 | "homepage": "https://github.com/owncloud/files_mediaviewer#readme" 47 | } 48 | -------------------------------------------------------------------------------- /src/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "swiper" : { 3 | "speed" : 300, 4 | "effect" : "slide" 5 | }, 6 | "mimetypes": [ 7 | "video/mp4", 8 | "video/ogg", 9 | "video/webm", 10 | "video/quicktime" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /src/scripts/Viewer.vue: -------------------------------------------------------------------------------- 1 | 19 | 261 | -------------------------------------------------------------------------------- /src/scripts/ViewerControls.vue: -------------------------------------------------------------------------------- 1 | 8 | 62 | -------------------------------------------------------------------------------- /src/scripts/ViewerControlsImage.vue: -------------------------------------------------------------------------------- 1 | 17 | 99 | -------------------------------------------------------------------------------- /src/scripts/ViewerControlsMeta.vue: -------------------------------------------------------------------------------- 1 | 7 | 47 | -------------------------------------------------------------------------------- /src/scripts/ViewerControlsNavigate.vue: -------------------------------------------------------------------------------- 1 | 8 | 28 | -------------------------------------------------------------------------------- /src/scripts/ViewerControlsVideo.vue: -------------------------------------------------------------------------------- 1 | 27 | 227 | -------------------------------------------------------------------------------- /src/scripts/ViewerSpinner.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /src/scripts/default.js: -------------------------------------------------------------------------------- 1 | require('../styles/default.scss') 2 | 3 | import app from './setup.js'; 4 | 5 | // Components 6 | 7 | import Viewer from './Viewer.vue'; 8 | import Spinner from './ViewerSpinner.vue'; 9 | 10 | // Libs 11 | 12 | import Swiper from 'swiper'; 13 | 14 | import Vue from 'vue'; 15 | import VueRouter from 'vue-router'; 16 | 17 | Vue.use(VueRouter); 18 | 19 | // --- Global Components 20 | 21 | import moment from 'moment'; 22 | import 'moment-duration-format'; 23 | 24 | import { 25 | helper, 26 | directive 27 | } from './helper.js'; 28 | 29 | 30 | Vue.mixin(helper); 31 | Vue.directive('translate', directive); 32 | Vue.component('spinner', Spinner); 33 | 34 | Vue.prototype.$bus = new Vue(); 35 | Vue.prototype.$wiper = Swiper; 36 | Vue.prototype.$app = app; 37 | 38 | const router = new VueRouter({ 39 | routes: [{ 40 | path: '/', 41 | component: { 42 | name: 'Hibernate', 43 | template : '' 44 | } 45 | }, { 46 | path: `/${app.name}/:file`, 47 | name: 'Viewer', 48 | component: Viewer 49 | }] 50 | }); 51 | 52 | // ------------------------------------------------------------------- store --- 53 | 54 | import Vuex from 'vuex'; 55 | Vue.use(Vuex); 56 | 57 | import store from './store.js'; 58 | const Store = new Vuex.Store(store); 59 | 60 | // --------------------------------------------------------------- app setup --- 61 | 62 | 63 | import IE11RouterFix from './ie11routerfix'; 64 | 65 | // Japp … we need to wait for a ready DOM 66 | $(document).ready(() => { 67 | new Vue({ 68 | el : '#files_mediaviewer > div', 69 | router, 70 | store : Store, 71 | template: 'Was geht hier?', 72 | mixins : [IE11RouterFix], 73 | data: { 74 | name: 'Mediaviewer' 75 | } 76 | }); 77 | }); 78 | -------------------------------------------------------------------------------- /src/scripts/getEventListeners.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | 'use strict'; 3 | 4 | // save the original methods before overwriting them 5 | Element.prototype._addEventListener = Element.prototype.addEventListener; 6 | Element.prototype._removeEventListener = Element.prototype.removeEventListener; 7 | 8 | /** 9 | * [addEventListener description] 10 | * @param {[type]} type [description] 11 | * @param {[type]} listener [description] 12 | * @param {Boolean} useCapture [description] 13 | */ 14 | Element.prototype.addEventListener = function(type,listener,useCapture=false) { 15 | // declare listener 16 | this._addEventListener(type,listener,useCapture); 17 | 18 | if(!this.eventListenerList) {this.eventListenerList = {};} 19 | if(!this.eventListenerList[type]) {this.eventListenerList[type] = [];} 20 | 21 | // add listener to event tracking list 22 | this.eventListenerList[type].push( {type, listener, useCapture} ); 23 | }; 24 | 25 | /** 26 | * [removeEventListener description] 27 | * @param {[type]} type [description] 28 | * @param {[type]} listener [description] 29 | * @param {Boolean} useCapture [description] 30 | * @return {[type]} [description] 31 | */ 32 | Element.prototype.removeEventListener = function(type,listener,useCapture=false) { 33 | // remove listener 34 | this._removeEventListener(type,listener,useCapture); 35 | 36 | if(!this.eventListenerList) {this.eventListenerList = {};} 37 | if(!this.eventListenerList[type]) {this.eventListenerList[type] = [];} 38 | 39 | // Find the event in the list, If a listener is registered twice, one 40 | // with capture and one without, remove each one separately. Removal of 41 | // a capturing listener does not affect a non-capturing version of the 42 | // same listener, and vice versa. 43 | for(let i=0; i= 0; --i) { 80 | var ev = el[i]; 81 | this.removeEventListener(a, ev.listener, ev.useCapture); 82 | } 83 | }; 84 | */ 85 | 86 | })(); 87 | -------------------------------------------------------------------------------- /src/scripts/helper.js: -------------------------------------------------------------------------------- 1 | const appName = require('../../package.json').name; 2 | var moment = require("moment"); 3 | 4 | const helper = { 5 | methods: { 6 | t(string, scope = appName) { 7 | return t(scope, string); 8 | }, 9 | 10 | $gettext(string, scope = appName) { 11 | return t(scope, string); 12 | }, 13 | 14 | pauseAllVideos () { 15 | $('.viewer__slide .viewer__media--video').each(function() { 16 | $(this).get(0).pause(); 17 | }); 18 | }, 19 | 20 | closeViewer () { 21 | this.$router.push('/'); 22 | }, 23 | 24 | getDisplayTime (time) { 25 | if (isNaN(time) || time === 0) { 26 | return "00:00"; 27 | } 28 | // when switching between previews, currentTime is not rounded somehow 29 | time = Math.round(time); 30 | var formatted = moment.duration(time, 'seconds').format("hh:mm:ss", { trim: "mid" }); 31 | return formatted; 32 | } 33 | }, 34 | computed : { 35 | isActive () { 36 | return (this.$route.params.file) ? true : false; 37 | }, 38 | isPublic () { 39 | return typeof OCA.Sharing.PublicApp === 'object'; 40 | }, 41 | sharingToken () { 42 | return (this.isPublic) ? $('#sharingToken').val() : null; 43 | }, 44 | documentFullscreenEnabled () { 45 | return document.fullscreenEnabled; 46 | } 47 | } 48 | }; 49 | 50 | const directive = { 51 | bind(el, binding) { 52 | console.log(binding.value, el.innerText.trim()); 53 | el.innerText = t('files_mediaviewer', el.innerText.trim()); 54 | } 55 | }; 56 | 57 | export { 58 | helper, 59 | directive 60 | }; 61 | -------------------------------------------------------------------------------- /src/scripts/ie11routerfix.js: -------------------------------------------------------------------------------- 1 | export default { 2 | methods: { 3 | hashChangeHandler () { 4 | this.$router.push(window.location.hash.substring(1, window.location.hash.length)); 5 | }, 6 | isIE11 () { 7 | return !!window.MSInputMethodContext && !!document.documentMode; 8 | } 9 | }, 10 | mounted () { 11 | if ( this.isIE11() ) { 12 | window.addEventListener('hashchange', this.hashChangeHandler); 13 | } 14 | }, 15 | destroyed () { 16 | if ( this.isIE11() ) { 17 | window.removeEventListener('hashchange', this.hashChangeHandler); 18 | } 19 | } 20 | }; -------------------------------------------------------------------------------- /src/scripts/init.js: -------------------------------------------------------------------------------- 1 | if (!OCA.Mediaviewer) { 2 | /** 3 | * @namespace 4 | */ 5 | OCA.Mediaviewer = {}; 6 | } 7 | 8 | OCA.Mediaviewer.app = require('./setup.js').default; 9 | 10 | $(document).ready(function () { 11 | const app = OCA.Mediaviewer.app; 12 | const mountPoint = $('
', { 13 | id: app.name, 14 | html: '
' 15 | }); 16 | 17 | if (!OCA.Files) { 18 | return; 19 | } 20 | 21 | // ---- Register fileactions ------- 22 | 23 | let actionHandler = (fileName, context) => { 24 | $('body').append(mountPoint); 25 | 26 | OCA.Mediaviewer.files = context.fileList.files; 27 | 28 | OC.addScript(app.name, app.name).then(() => { 29 | OC.redirect(OC.joinPaths('#', app.name, fileName)); 30 | }); 31 | }; 32 | 33 | app.config.mimetypes.forEach( (mimetype) => { 34 | 35 | // register only browser playable videotypes 36 | let n = mimetype.search("video"); 37 | if (n === 0) { 38 | let hasVideo = document.createElement('video').canPlayType && 39 | document.createElement('video').canPlayType(mimetype); 40 | if (!hasVideo) { 41 | return; 42 | } 43 | } 44 | 45 | let ViewMedia = { 46 | mime: mimetype, 47 | name: app.name, 48 | permissions: OC.PERMISSION_READ, 49 | displayName: t('files_mediaviewer', 'Open in Media Viewer'), 50 | iconClass: 'icon-toggle', 51 | actionHandler 52 | }; 53 | 54 | if (OCA.Files.fileActions) { 55 | OCA.Files.fileActions.registerAction(ViewMedia); 56 | OCA.Files.fileActions.setDefault(mimetype, app.name); 57 | } 58 | }); 59 | }); 60 | -------------------------------------------------------------------------------- /src/scripts/setup.js: -------------------------------------------------------------------------------- 1 | let pkg, config, enabledImages; 2 | 3 | pkg = require('../../package.json'); 4 | config = require('../config.json'); 5 | 6 | // Add enabledPreviewProviders to mimeType list 7 | enabledImages = _.filter(OC.appConfig.core.enabledPreviewProviders, mimeType => !mimeType.search('image')) 8 | enabledImages = _.map(enabledImages, mimeType => mimeType.replace(/\\/g, '')) // strip slashes 9 | 10 | config.mimetypes = config.mimetypes.concat(enabledImages); 11 | 12 | pkg['config'] = config; 13 | 14 | export default pkg; -------------------------------------------------------------------------------- /src/scripts/store.js: -------------------------------------------------------------------------------- 1 | export default { 2 | state: { 3 | activeIndex: 0, 4 | maxIndex : 0, 5 | activeMediaItem : {}, 6 | activeHTMLElement : null, 7 | isLoading : false, 8 | isInTransition : false, 9 | video : { 10 | isPaused : true, 11 | isMuted : false, 12 | isFullscreen : false 13 | } 14 | }, 15 | getters : { 16 | itemName (state) { 17 | if (state.activeMediaItem.length === 0) { 18 | return 'Loading ...'; 19 | } 20 | return state.activeMediaItem.name; 21 | }, 22 | itemType (state) { 23 | if (!state.activeMediaItem.mimetype) { 24 | return null; 25 | } 26 | return state.activeMediaItem.mimetype.split('/')[0]; 27 | }, 28 | HTMLImageElement (state) { 29 | if (state.activeHTMLElement === null) 30 | {return null;} 31 | 32 | return (state.activeHTMLElement.get(0) instanceof HTMLImageElement) ? state.activeHTMLElement.get(0) : false; 33 | }, 34 | HTMLVideoElement (state) { 35 | if (state.activeHTMLElement === null) 36 | {return null;} 37 | 38 | return (state.activeHTMLElement.get(0) instanceof HTMLVideoElement) ? state.activeHTMLElement.get(0) : false; 39 | } 40 | }, 41 | mutations: { 42 | setActiveIndex (state, index) { 43 | state.activeIndex = parseInt(index); 44 | }, 45 | setActiveMediaItem (state, item) { 46 | state.activeMediaItem = item; 47 | }, 48 | setActiveHTMLElement (state, node) { 49 | state.activeHTMLElement = (typeof node === 'object') ? node : null; 50 | }, 51 | setLoadingState(state, setTo) { 52 | state.isLoading = setTo; 53 | }, 54 | setMaxIndex(state, max) { 55 | state.maxIndex = (typeof max === 'number') ? max : parseInt(max); 56 | }, 57 | setVideoState(state, payload) { 58 | state.video = _.extend(state.video, payload); 59 | }, 60 | setTransitionState(state, setTo) { 61 | state.isInTransition = setTo; 62 | }, 63 | resetAll(state) { 64 | state.activeIndex= 0; 65 | state.maxIndex = 0; 66 | state.activeMediaItem = {}; 67 | state.isLoading = false; 68 | state.isInTransition = false; 69 | state.video = { 70 | isPaused : true, 71 | isMuted : false, 72 | isFullscreen : false 73 | }; 74 | } 75 | }, 76 | actions : { 77 | setActive(context, payload) { 78 | context.commit('setActiveIndex', payload.activeIndex); 79 | context.commit('setActiveMediaItem', payload.activeMediaItem); 80 | context.commit('setActiveHTMLElement', payload.activeHTMLElement); 81 | }, 82 | setLoading(context) { 83 | context.commit('setLoadingState', true); 84 | }, 85 | setInTransition(context) { 86 | context.commit('setTransitionState', true); 87 | }, 88 | setTransitionEnd(context) { 89 | context.commit('setTransitionState', false); 90 | }, 91 | setReady(context) { 92 | context.commit('setLoadingState', false); 93 | }, 94 | setMaxIndex(context, payload) { 95 | context.commit('setMaxIndex', payload); 96 | }, 97 | setVideoState(context, payload) { 98 | context.commit('setVideoState', payload); 99 | }, 100 | resetAll(context) { 101 | context.commit('resetAll'); 102 | } 103 | } 104 | }; -------------------------------------------------------------------------------- /src/styles/_base.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | position: absolute; 3 | width: 100vw; 4 | height: 100vh; 5 | z-index: 1000; 6 | overflow: hidden; 7 | user-select: none; 8 | 9 | background: { 10 | color: rgba(black, .75); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/styles/_helper.scss: -------------------------------------------------------------------------------- 1 | .-margin { 2 | &-left { 3 | margin-left: 24px; 4 | } 5 | 6 | &-right { 7 | margin-right: 24px; 8 | } 9 | } 10 | 11 | // --- transitions ---- 12 | 13 | 14 | .fade-enter-active, .fade-leave-active { 15 | transition: opacity .5s; 16 | } 17 | 18 | .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ { 19 | opacity: 0; 20 | } -------------------------------------------------------------------------------- /src/styles/_icons.scss: -------------------------------------------------------------------------------- 1 | $icon_map: ( 2 | prev : 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMTUuNDEgNy40MUwxNCA2bC02IDYgNiA2IDEuNDEtMS40MUwxMC44MyAxMnoiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPjwvc3ZnPg==', 3 | next : 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMTAgNkw4LjU5IDcuNDEgMTMuMTcgMTJsLTQuNTggNC41OUwxMCAxOGw2LTZ6IiBmaWxsPSJ3aGl0ZSIvPjxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz48L3N2Zz4=', 4 | close : 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMTkgNi40MUwxNy41OSA1IDEyIDEwLjU5IDYuNDEgNSA1IDYuNDEgMTAuNTkgMTIgNSAxNy41OSA2LjQxIDE5IDEyIDEzLjQxIDE3LjU5IDE5IDE5IDE3LjU5IDEzLjQxIDEyeiIgZmlsbD0id2hpdGUiLz48cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+PC9zdmc+', 5 | play : 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNOCA1djE0bDExLTd6IiBmaWxsPSJ3aGl0ZSIvPjxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz48L3N2Zz4=', 6 | pause : 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNNiAxOWg0VjVINnYxNHptOC0xNHYxNGg0VjVoLTR6IiBmaWxsPSJ3aGl0ZSIgLz48cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+PC9zdmc+', 7 | zoom_in : 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMTUuNSAxNGgtLjc5bC0uMjgtLjI3QzE1LjQxIDEyLjU5IDE2IDExLjExIDE2IDkuNSAxNiA1LjkxIDEzLjA5IDMgOS41IDNTMyA1LjkxIDMgOS41IDUuOTEgMTYgOS41IDE2YzEuNjEgMCAzLjA5LS41OSA0LjIzLTEuNTdsLjI3LjI4di43OWw1IDQuOTlMMjAuNDkgMTlsLTQuOTktNXptLTYgMEM3LjAxIDE0IDUgMTEuOTkgNSA5LjVTNy4wMSA1IDkuNSA1IDE0IDcuMDEgMTQgOS41IDExLjk5IDE0IDkuNSAxNHoiIGZpbGw9IndoaXRlIi8+PHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgyNHYyNEgwVjB6Ii8+PHBhdGggZD0iTTEyIDEwaC0ydjJIOXYtMkg3VjloMlY3aDF2MmgydjF6IiBmaWxsPSJ3aGl0ZSIvPjwvc3ZnPg==', 8 | zoom_out : 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBmaWxsPSJub25lIiBkPSJNMCAwaDI0djI0SDBWMHoiLz48cGF0aCBkPSJNMTUuNSAxNGgtLjc5bC0uMjgtLjI3QzE1LjQxIDEyLjU5IDE2IDExLjExIDE2IDkuNSAxNiA1LjkxIDEzLjA5IDMgOS41IDNTMyA1LjkxIDMgOS41IDUuOTEgMTYgOS41IDE2YzEuNjEgMCAzLjA5LS41OSA0LjIzLTEuNTdsLjI3LjI4di43OWw1IDQuOTlMMjAuNDkgMTlsLTQuOTktNXptLTYgMEM3LjAxIDE0IDUgMTEuOTkgNSA5LjVTNy4wMSA1IDkuNSA1IDE0IDcuMDEgMTQgOS41IDExLjk5IDE0IDkuNSAxNHpNNyA5aDV2MUg3eiIgZmlsbD0id2hpdGUiLz48L3N2Zz4=', 9 | rotate_90_degrees_ccw : 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNNy4zNCA2LjQxTC44NiAxMi45bDYuNDkgNi40OCA2LjQ5LTYuNDgtNi41LTYuNDl6TTMuNjkgMTIuOWwzLjY2LTMuNjZMMTEgMTIuOWwtMy42NiAzLjY2LTMuNjUtMy42NnptMTUuNjctNi4yNkMxNy42MSA0Ljg4IDE1LjMgNCAxMyA0Vi43Nkw4Ljc2IDUgMTMgOS4yNFY2YzEuNzkgMCAzLjU4LjY4IDQuOTUgMi4wNSAyLjczIDIuNzMgMi43MyA3LjE3IDAgOS45QzE2LjU4IDE5LjMyIDE0Ljc5IDIwIDEzIDIwYy0uOTcgMC0xLjk0LS4yMS0yLjg0LS42MWwtMS40OSAxLjQ5QzEwLjAyIDIxLjYyIDExLjUxIDIyIDEzIDIyYzIuMyAwIDQuNjEtLjg4IDYuMzYtMi42NCAzLjUyLTMuNTEgMy41Mi05LjIxIDAtMTIuNzJ6IiBmaWxsPSJ3aGl0ZSIvPjxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0wIDBoMjR2MjRIMHoiLz48L3N2Zz4=', 10 | replay : 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTEyIDVWMUw3IDZsNSA1VjdjMy4zMSAwIDYgMi42OSA2IDZzLTIuNjkgNi02IDYtNi0yLjY5LTYtNkg0YzAgNC40MiAzLjU4IDggOCA4czgtMy41OCA4LTgtMy41OC04LTgtOHoiLz48L3N2Zz4=', 11 | download : 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBmaWxsPSJub25lIiBkPSJNMCAwaDI0djI0SDBWMHoiLz48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMjAgMTJsLTEuNDEtMS40MUwxMyAxNi4xN1Y0aC0ydjEyLjE3bC01LjU4LTUuNTlMNCAxMmw4IDggOC04eiIvPjwvc3ZnPg==', 12 | volume_up : 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMyA5djZoNGw1IDVWNEw3IDlIM3ptMTMuNSAzYzAtMS43Ny0xLjAyLTMuMjktMi41LTQuMDN2OC4wNWMxLjQ4LS43MyAyLjUtMi4yNSAyLjUtNC4wMnpNMTQgMy4yM3YyLjA2YzIuODkuODYgNSAzLjU0IDUgNi43MXMtMi4xMSA1Ljg1LTUgNi43MXYyLjA2YzQuMDEtLjkxIDctNC40OSA3LTguNzdzLTIuOTktNy44Ni03LTguNzd6Ii8+PHBhdGggZD0iTTAgMGgyNHYyNEgweiIgZmlsbD0ibm9uZSIvPjwvc3ZnPg==', 13 | volume_down : 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBmaWxsPSIjZmZmIiBkPSJNMTYuNSAxMmMwLTEuNzctMS4wMi0zLjI5LTIuNS00LjAzdjIuMjFsMi40NSAyLjQ1Yy4wMy0uMi4wNS0uNDEuMDUtLjYzem0yLjUgMGMwIC45NC0uMiAxLjgyLS41NCAyLjY0bDEuNTEgMS41MUMyMC42MyAxNC45MSAyMSAxMy41IDIxIDEyYzAtNC4yOC0yLjk5LTcuODYtNy04Ljc3djIuMDZjMi44OS44NiA1IDMuNTQgNSA2Ljcxek00LjI3IDNMMyA0LjI3IDcuNzMgOUgzdjZoNGw1IDV2LTYuNzNsNC4yNSA0LjI1Yy0uNjcuNTItMS40Mi45My0yLjI1IDEuMTh2Mi4wNmMxLjM4LS4zMSAyLjYzLS45NSAzLjY5LTEuODFMMTkuNzMgMjEgMjEgMTkuNzNsLTktOUw0LjI3IDN6TTEyIDRMOS45MSA2LjA5IDEyIDguMThWNHoiLz48cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+PC9zdmc+', 14 | fullscreen : 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+PHBhdGggZmlsbD0iI2ZmZiIgZD0iTTcgMTRINXY1aDV2LTJIN3YtM3ptLTItNGgyVjdoM1Y1SDV2NXptMTIgN2gtM3YyaDV2LTVoLTJ2M3pNMTQgNXYyaDN2M2gyVjVoLTV6Ii8+PC9zdmc+', 15 | play_circle : 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+PHBhdGggZD0iTTEyIDJDNi40OCAyIDIgNi40OCAyIDEyczQuNDggMTAgMTAgMTAgMTAtNC40OCAxMC0xMFMxNy41MiAyIDEyIDJ6bS0yIDE0LjV2LTlsNiA0LjUtNiA0LjV6IiBmaWxsPSIjRkZGRkZGIi8+PC9zdmc+' 16 | ); 17 | 18 | // -- for usage in @media context 19 | @mixin icon($icon : '') { 20 | @if $icon != '' { 21 | background-image: url(map-get($icon_map, $icon)); 22 | } 23 | } 24 | 25 | // -- for usage in @extend and DOM env 26 | .icon { 27 | @each $icon, $image in $icon_map { 28 | &__#{$icon} { 29 | background-image: url($image); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/styles/_spinner.scss: -------------------------------------------------------------------------------- 1 | $viewer__spinner__dim : 60px; 2 | $viewer__spinner__border-width : 6px; 3 | 4 | .viewer__spinner { 5 | height: $viewer__spinner__dim; 6 | width: $viewer__spinner__dim; 7 | 8 | animation: rotation 1s infinite ease-in-out; 9 | border: $viewer__spinner__border-width solid rgba(white, .25); 10 | border-radius: 100%; 11 | z-index: 999; 12 | text-indent: -9999px; 13 | 14 | &:before { 15 | content: ""; 16 | display: block; 17 | position: absolute; 18 | left: -$viewer__spinner__border-width; 19 | top: -$viewer__spinner__border-width; 20 | height: 100%; 21 | width: 100%; 22 | border: { 23 | top: $viewer__spinner__border-width solid rgba(white, .75); 24 | left: $viewer__spinner__border-width solid transparent; 25 | bottom: $viewer__spinner__border-width solid transparent; 26 | right: $viewer__spinner__border-width solid transparent; 27 | radius: 100%; 28 | } 29 | } 30 | } 31 | 32 | .viewer__spinner__wrapper { 33 | position: absolute; 34 | top: 50%; 35 | left: 50%; 36 | transform: translate(-50%, -50%); 37 | } 38 | 39 | @keyframes rotation { 40 | from { 41 | transform: rotate(0deg); 42 | } 43 | to { 44 | transform: rotate(359deg); 45 | } 46 | } -------------------------------------------------------------------------------- /src/styles/_swiper.scss: -------------------------------------------------------------------------------- 1 | .swiper-wrapper { 2 | background: { 3 | position: center center; 4 | repeat: no-repeat; 5 | size: contain; 6 | } 7 | } -------------------------------------------------------------------------------- /src/styles/_transitions.scss: -------------------------------------------------------------------------------- 1 | .fade { 2 | &-enter-active, 3 | &-leave-active { 4 | transition: opacity .125s !important; 5 | } 6 | 7 | &-enter, 8 | &-leave-to { 9 | opacity: 0 !important; 10 | } 11 | } -------------------------------------------------------------------------------- /src/styles/_viewer.scss: -------------------------------------------------------------------------------- 1 | .viewer { 2 | position: absolute; 3 | top: 45px; 4 | right: 0; 5 | bottom: 0; 6 | left: 0; 7 | 8 | &__container { 9 | margin: 0 auto; 10 | position: relative; 11 | overflow: hidden; 12 | list-style: none; 13 | padding: 0; 14 | z-index: 1; 15 | } 16 | 17 | &__wrapper { 18 | position: relative; 19 | width: 100%; 20 | height: 100%; 21 | z-index: 1; 22 | display: flex; 23 | background: { 24 | position: center center; 25 | repeat: no-repeat; 26 | size: contain; 27 | } 28 | } 29 | 30 | &__slide { 31 | display: flex; 32 | justify-content: center; 33 | align-items: center; 34 | height: calc(100vh - 45px) !important; 35 | flex-shrink: 0; 36 | position: relative; 37 | 38 | // Only active mediaitem should animate 39 | &.swiper-slide-active { 40 | .viewer__media--image { 41 | transition: transform .25s ease-in-out; 42 | } 43 | } 44 | } 45 | 46 | &__play { 47 | position: absolute; 48 | } 49 | 50 | &__media { 51 | position: relative; 52 | 53 | &--image { 54 | max-width: 90vw; 55 | max-height: 80vh; 56 | 57 | &[alt$=".svg"] { 58 | background-color: rgba(white, .333); 59 | } 60 | } 61 | 62 | &--video { 63 | max-width: 90vw; 64 | max-height: 80vh; 65 | } 66 | } 67 | } 68 | 69 | -------------------------------------------------------------------------------- /src/styles/_viewerControls.scss: -------------------------------------------------------------------------------- 1 | .viewer__control { 2 | cursor: pointer; 3 | border: 0 none; 4 | width: 24px; 5 | height: 24px; 6 | text-indent: -9999px; 7 | background: { 8 | color: transparent; 9 | size: contain; 10 | repeat: no-repeat; 11 | cursor: pointer; 12 | } 13 | 14 | &[disabled] { 15 | opacity: .25; 16 | } 17 | 18 | &__nametag { 19 | display: block; 20 | position: absolute; 21 | color: white; 22 | transform: translate(-50%, -190%); 23 | top: 0; 24 | left: 50%; 25 | white-space: nowrap; 26 | font-size: 16px; 27 | text-shadow: 28 | 1px 1px 1px black, 29 | 1px -1px 1px black, 30 | -1px 1px 1px black, 31 | -1px -1px 1px black; 32 | } 33 | 34 | &__count { 35 | color: white; 36 | 37 | @media (max-width: 360px) { 38 | display: none; 39 | } 40 | } 41 | 42 | // -- Video controls 43 | 44 | &__scrubber { 45 | position: absolute; 46 | left: 0; 47 | right: 0; 48 | top: -1px; 49 | height: 10px; 50 | width: 100%; 51 | transform: translateY(-100%); 52 | transition: height .25s; 53 | background: rgba(0, 0, 0, 0.5); 54 | 55 | // Juicebar 56 | > div { 57 | position: absolute; 58 | top: 0; 59 | left: 0; 60 | bottom: 0; 61 | width: 0%; 62 | background-color: red; 63 | } 64 | } 65 | } 66 | 67 | .viewer__video-overlay { 68 | position: absolute; 69 | left: 50%; 70 | top: 50%; 71 | transform: translate(-50%, -50%); 72 | width: 10vw; 73 | height: 10vw; 74 | z-index: 1; 75 | border: 0 none; 76 | opacity: .5; 77 | border-radius: 50%; 78 | background: { 79 | color: rgba(black, .666); 80 | repeat: no-repeat; 81 | size: contain; 82 | position: center center; 83 | size: calc(100% + 12px); 84 | } 85 | } 86 | 87 | .viewer__controls { 88 | position: absolute; 89 | display: flex; 90 | background: rgba(black, .5); 91 | left: 50%; 92 | bottom: 0; 93 | transform: translate(-50%, -25%); 94 | z-index: 160; 95 | min-width: 600px; 96 | justify-content: space-between; 97 | align-items: center; 98 | transition: width .25s; 99 | box-sizing: border-box; 100 | 101 | padding: { 102 | left: 15px; 103 | right: 15px; 104 | } 105 | 106 | &:not(:hover) { 107 | opacity: .5; 108 | } 109 | 110 | &__subgroup { 111 | display: flex; 112 | justify-content: space-around; 113 | align-items: center; 114 | padding: 16px 0; 115 | 116 | > * { 117 | margin: 0 5px; 118 | } 119 | } 120 | 121 | // --- Enlarge juicebar on hovering over controlbar 122 | &:hover > .viewer__control__scrubber { 123 | height: 15px; 124 | } 125 | 126 | @media (max-width: 650px) { 127 | min-width: 100% 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/styles/default.scss: -------------------------------------------------------------------------------- 1 | $namespace : '#files_mediaviewer'; 2 | $grid-gutter: 10px; 3 | 4 | // Colors 5 | 6 | $color : ( 7 | primary: #1d2d44, 8 | secondary: #567298, 9 | 10 | gray: #DCDCDC, 11 | lightgray: #F1F1F1, 12 | 13 | error : red, 14 | error-border : #FED6D6, 15 | error-background : #FFF0F0, 16 | 17 | success :#3e5530, 18 | success-background :#def7de, 19 | success-border :#bbe2b7, 20 | ); 21 | 22 | $core-image-path : '../../../core/img'; 23 | $app-image-path : '../img'; 24 | 25 | #{$namespace} { 26 | @import "../../node_modules/swiper/dist/css/swiper.min.css"; 27 | 28 | @import "base"; 29 | @import "transitions"; 30 | @import "helper"; 31 | @import "icons"; 32 | @import "swiper"; 33 | 34 | @import "spinner"; 35 | @import "viewer"; 36 | @import "viewerControls"; 37 | } 38 | -------------------------------------------------------------------------------- /templates/settings.php: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 |
8 | 9 |
10 |
-------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const VueLoaderPlugin = require('vue-loader/lib/plugin') 3 | module.exports = [{ 4 | name: 'app', 5 | entry: './src/scripts/default.js', 6 | output: { 7 | filename: 'files_mediaviewer.js', 8 | path: path.resolve(__dirname, 'js') 9 | }, 10 | resolve: { 11 | alias: { 12 | 'vue$': 'vue/dist/vue.esm.js' 13 | }, 14 | extensions: ['*', '.js', '.vue', '.json'] 15 | }, 16 | module: { 17 | rules: [{ 18 | test: /\.vue$/, 19 | loader: 'vue-loader' 20 | }, { 21 | test: /\.js$/, 22 | loader: 'babel-loader' 23 | }, { 24 | test: /\.scss$/, 25 | use: ["style-loader", "css-loader", "sass-loader"] 26 | }] 27 | }, 28 | plugins: [ 29 | new VueLoaderPlugin() 30 | ] 31 | }, { 32 | name: 'init', 33 | entry: './src/scripts/init.js', 34 | output: { 35 | filename: 'files_mediaviewer_init.js', 36 | path: path.resolve(__dirname, 'js') 37 | }, 38 | module: { 39 | rules: [{ 40 | test: /\.js$/, 41 | loader: 'babel-loader' 42 | }] 43 | } 44 | }] --------------------------------------------------------------------------------