Merge branch 'release/0.7.0.0'
This commit is contained in:
commit
7153df5c86
605 changed files with 11175 additions and 7110 deletions
23
.gitignore
vendored
23
.gitignore
vendored
|
|
@ -10,27 +10,15 @@ app/assets/images/custom/
|
|||
|
||||
# Configuration files
|
||||
config/diaspora.yml
|
||||
config/heroku.yml
|
||||
config/initializers/secret_token.rb
|
||||
config/redis.conf
|
||||
config/deploy_config.yml
|
||||
config/schedule.rb
|
||||
.bundle
|
||||
vendor/bundle/
|
||||
vendor/cache/
|
||||
config/database.yml
|
||||
.rvmrc_custom
|
||||
.rvmrc.local
|
||||
config/oidc_key.pem
|
||||
|
||||
# Mailing list stuff
|
||||
config/email_offset
|
||||
config/mailing_list.csv
|
||||
|
||||
# Generated files
|
||||
log/
|
||||
public/stylesheets/*.css
|
||||
public/diaspora
|
||||
spec/fixtures/*.y*ml
|
||||
spec/fixtures/*.fixture.*
|
||||
coverage/
|
||||
|
|
@ -39,6 +27,12 @@ public/404.html
|
|||
public/422.html
|
||||
public/500.html
|
||||
|
||||
# the db/schema.rb. Although this is contrary to rails best-practises, we
|
||||
# cannot provide a schema.rb that works for both MySQL and PostgreSQL, so we
|
||||
# have no choice. Our migrations are maintained, so it should always be
|
||||
# possible to get back to a "clean" database schema anyway.
|
||||
db/schema.rb
|
||||
|
||||
# Sprites
|
||||
app/assets/images/branding-*.png
|
||||
app/assets/images/branding/logos-*.png
|
||||
|
|
@ -53,17 +47,13 @@ doc/
|
|||
public/uploads/
|
||||
public/assets/
|
||||
public/source.tar*
|
||||
public/.well-known
|
||||
tmp/**/
|
||||
tmp/
|
||||
*.sqlite3
|
||||
|
||||
# Temporary files of every sort
|
||||
.sass-cache/
|
||||
.DS_Store
|
||||
.idea
|
||||
.redcar
|
||||
.rvmrc
|
||||
.stgit*
|
||||
*.swap
|
||||
*.swo
|
||||
|
|
@ -76,7 +66,6 @@ tmp/
|
|||
nbproject
|
||||
patches-*
|
||||
capybara-*.html
|
||||
dump.rdb
|
||||
|
||||
# Rubinius's JIT
|
||||
*.rbc
|
||||
|
|
|
|||
12
.rubocop.yml
12
.rubocop.yml
|
|
@ -40,7 +40,7 @@ Metrics/BlockLength:
|
|||
|
||||
# No space makes the method definition shorter and differentiates
|
||||
# from a regular assignment.
|
||||
Style/SpaceAroundEqualsInParameterDefault:
|
||||
Layout/SpaceAroundEqualsInParameterDefault:
|
||||
EnforcedStyle: no_space
|
||||
|
||||
# Single quotes being faster is hardly measurable and only affects parse time.
|
||||
|
|
@ -55,7 +55,7 @@ Style/SymbolArray:
|
|||
Enabled: true
|
||||
|
||||
# Most readable form.
|
||||
Style/AlignHash:
|
||||
Layout/AlignHash:
|
||||
EnforcedHashRocketStyle: table
|
||||
EnforcedColonStyle: table
|
||||
|
||||
|
|
@ -92,7 +92,7 @@ Style/RaiseArgs:
|
|||
|
||||
# Indenting the chained dots beneath each other is not supported by this cop,
|
||||
# see https://github.com/bbatsov/rubocop/issues/1633
|
||||
Style/MultilineOperationIndentation:
|
||||
Layout/MultilineOperationIndentation:
|
||||
Enabled: false
|
||||
|
||||
# Fail is an alias of raise. Avoid aliases, it's more cognitive load for no gain.
|
||||
|
|
@ -107,7 +107,7 @@ Style/SignalException:
|
|||
Lint/HandleExceptions:
|
||||
Enabled: false
|
||||
|
||||
Style/SpaceInsideBlockBraces:
|
||||
Layout/SpaceInsideBlockBraces:
|
||||
# The space here provides no real gain in readability while consuming
|
||||
# horizontal space that could be used for a better parameter name.
|
||||
# Also {| differentiates better from a hash than { | does.
|
||||
|
|
@ -115,7 +115,7 @@ Style/SpaceInsideBlockBraces:
|
|||
|
||||
# No trailing space differentiates better from the block:
|
||||
# foo} means hash, foo } means block.
|
||||
Style/SpaceInsideHashLiteralBraces:
|
||||
Layout/SpaceInsideHashLiteralBraces:
|
||||
EnforcedStyle: no_space
|
||||
|
||||
# { ... } for multi-line blocks is okay, follow Weirichs rule instead:
|
||||
|
|
@ -165,7 +165,7 @@ Style/NumericPredicate:
|
|||
EnforcedStyle: comparison
|
||||
|
||||
# Reset some HoundCI changes back to Rubocop defaults
|
||||
Style/DotPosition:
|
||||
Layout/DotPosition:
|
||||
EnforcedStyle: leading
|
||||
|
||||
### backward compatibility
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
2.3
|
||||
2.4
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
language: ruby
|
||||
|
||||
rvm:
|
||||
- 2.3.1
|
||||
- 2.1
|
||||
- 2.4.1
|
||||
- 2.3.4
|
||||
|
||||
env:
|
||||
- DB=postgresql BUILD_TYPE=cucumber
|
||||
|
|
@ -15,6 +15,7 @@ cache:
|
|||
bundler: true
|
||||
directories:
|
||||
- app/assets/images
|
||||
- tmp/cache/assets
|
||||
|
||||
branches:
|
||||
only:
|
||||
|
|
@ -29,7 +30,7 @@ before_install:
|
|||
- tar -xvf $PWD/travis-phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2 -C $PWD/travis-phantomjs
|
||||
- export PATH=$PWD/travis-phantomjs/phantomjs-2.1.1-linux-x86_64/bin:$PATH
|
||||
|
||||
bundler_args: "--deployment --without development production --with mysql postgresql --jobs 3 --retry 3"
|
||||
bundler_args: "--deployment --without development --with mysql postgresql --jobs 3 --retry 3"
|
||||
|
||||
script: "./script/ci/build.sh"
|
||||
|
||||
|
|
|
|||
42
CONTRIBUTING.md
Normal file
42
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# Contributing to diaspora\*
|
||||
|
||||
First of all: thank you very much for helping us out!
|
||||
|
||||
## Things you need to know before contributing
|
||||
|
||||
If you want to get in touch with other diaspora\* developers, [check our wiki][how-we-communicate] for information on how we communicate. Feel free to ask if you have any questions!
|
||||
|
||||
Everyone interacting with our code, issue trackers, chat rooms, mailing lists, the wiki, and the discourse forum is expected to follow the [diaspora\* code of conduct][code-of-conduct].
|
||||
|
||||
## Report a security issue
|
||||
|
||||
Found a security issue? Please disclose it responsibly. We have a team of developers listening to [security@diasporafoundation.org][sec-mail]. The PGP fingerprint is [AB0D AB02 0FC5 D398 03AB 3CE1 6F70 243F 27AD 886A][pgp].
|
||||
|
||||
## Contributing to translations
|
||||
|
||||
We use [WebTranslateIt][webtranslateit] to manage translations of the app interface. Please read [our wiki page][translation-wiki] to find out more about this. If your language is featured on WebTranslateIt, please do **not** open a pull request to update translations. If it is not already featured on WebTranslateIt, please read the wiki article above to find out how to proceed.
|
||||
|
||||
## Contributing to the code
|
||||
|
||||
**Before opening a pull request** please read [how to contribute][contribute]. Doing things the right way from the start will save us time and mean that your contribution can be integrated quicker!
|
||||
- Follow our [git workflow][git-workflow] method. In particular, *do not* open a pull request from the `master` or the `develop` branch.
|
||||
- Follow our [styleguide][styleguide] and run pronto, our syntax analyzer, **locally before opening a pull request**. See [our wiki][pronto] for information on how to do this.
|
||||
- [Write tests][testing-workflow].
|
||||
- Use meaningful commit-messages and split larger tasks, e.g. refactoring, into separate commits. This makes the review process much easier.
|
||||
|
||||
## Other ways to contribute
|
||||
|
||||
You don’t know code? No worries, there are plenty other ways to help the diaspora* project! Please find out how you can help [on our wiki][other-ways].
|
||||
|
||||
[code-of-conduct]: https://github.com/diaspora/diaspora/blob/develop/CODE_OF_CONDUCT.md
|
||||
[how-we-communicate]: https://wiki.diasporafoundation.org/How_we_communicate
|
||||
[pgp]: https://pgp.mit.edu/pks/lookup?op=get&search=0x6F70243F27AD886A
|
||||
[sec-mail]: mailto:security@diasporafoundation.org
|
||||
[webtranslateit]: https://webtranslateit.com/en/projects/3020-Diaspora
|
||||
[translation-wiki]: https://wiki.diasporafoundation.org/Contribute_translations
|
||||
[contribute]: https://wiki.diasporafoundation.org/Getting_started_with_contributing
|
||||
[git-workflow]: https://wiki.diasporafoundation.org/Git_Workflow
|
||||
[styleguide]: https://wiki.diasporafoundation.org/Styleguide
|
||||
[pronto]: https://wiki.diasporafoundation.org/Styleguide#Automatic_local_review
|
||||
[testing-workflow]: https://wiki.diasporafoundation.org/Testing_Workflow
|
||||
[other-ways]: https://wiki.diasporafoundation.org/Other_ways_to_contribute
|
||||
60
Changelog.md
60
Changelog.md
|
|
@ -1,3 +1,63 @@
|
|||
# 0.7.0.0
|
||||
|
||||
## Supported Ruby versions
|
||||
|
||||
This release recommends using Ruby 2.4, while retaining Ruby 2.3 as an officially supported version.
|
||||
Ruby 2.1 is no longer officially supported.
|
||||
|
||||
## Delete public/.well-known/
|
||||
|
||||
Before upgrading, please check if your `public/` folder contains a hidden `.well-known/` folder.
|
||||
If so, please delete it since it will prevent the federation from working properly.
|
||||
|
||||
## Refactor
|
||||
|
||||
* Make the mention syntax more flexible [#7305](https://github.com/diaspora/diaspora/pull/7305)
|
||||
* Display @ before mentions [#7324](https://github.com/diaspora/diaspora/pull/7324)
|
||||
* Simplify mentions in the publisher [#7302](https://github.com/diaspora/diaspora/pull/7302)
|
||||
* Remove chartbeat and mixpanel support [#7280](https://github.com/diaspora/diaspora/pull/7280)
|
||||
* Upgrade to jQuery 3 [#7303](https://github.com/diaspora/diaspora/pull/7303)
|
||||
* Add i18n for color themes [#7369](https://github.com/diaspora/diaspora/pull/7369)
|
||||
* Remove deprecated statistics.json [#7399](https://github.com/diaspora/diaspora/pull/7399)
|
||||
* Always link comment count text on mobile [#7483](https://github.com/diaspora/diaspora/pull/7483)
|
||||
* Switch to new federation protocol [#7436](https://github.com/diaspora/diaspora/pull/7436)
|
||||
* Send public profiles publicly [#7501](https://github.com/diaspora/diaspora/pull/7501)
|
||||
* Change sender for mails [#7495](https://github.com/diaspora/diaspora/pull/7495)
|
||||
* Move back to top to the right to avoid misclicks [#7516](https://github.com/diaspora/diaspora/pull/7516)
|
||||
* Include count in mobile post action link [#7520](https://github.com/diaspora/diaspora/pull/7520)
|
||||
* Update the user data export archive format [#6726](https://github.com/diaspora/diaspora/pull/6726)
|
||||
* Use id as fallback when sorting posts [#7523](https://github.com/diaspora/diaspora/pull/7523)
|
||||
* Remove no-posts-info when adding posts to the stream [#7523](https://github.com/diaspora/diaspora/pull/7523)
|
||||
* Upgrade to rails 5.1 [#7514](https://github.com/diaspora/diaspora/pull/7514)
|
||||
* Refactoring single post view interactions [#7182](https://github.com/diaspora/diaspora/pull/7182)
|
||||
* Update help pages [#7528](https://github.com/diaspora/diaspora/pull/7528)
|
||||
* Disable rendering logging in production [#7529](https://github.com/diaspora/diaspora/pull/7529)
|
||||
* Add some missing indexes and cleanup the database if needed [#7533](https://github.com/diaspora/diaspora/pull/7533)
|
||||
* Remove avatar, name, timestamp and interactions from publisher preview [#7536](https://github.com/diaspora/diaspora/pull/7536)
|
||||
|
||||
## Bug fixes
|
||||
|
||||
* Fix height too high on mobile SPV [#7480](https://github.com/diaspora/diaspora/pull/7480)
|
||||
* Improve stream when ignoring a person who posts a lot of tagged posts [#7503](https://github.com/diaspora/diaspora/pull/7503)
|
||||
* Fix order of comments across pods [#7436](https://github.com/diaspora/diaspora/pull/7436)
|
||||
* Prevent publisher from closing in preview mode [#7518](https://github.com/diaspora/diaspora/pull/7518)
|
||||
* Increase reshare counter after reshare on mobile [#7520](https://github.com/diaspora/diaspora/pull/7520)
|
||||
* Reset stuck exports and handle errors [#7535](https://github.com/diaspora/diaspora/pull/7535)
|
||||
|
||||
## Features
|
||||
* Add support for mentions in comments to the backend [#6818](https://github.com/diaspora/diaspora/pull/6818)
|
||||
* Add support for new mention syntax [#7300](https://github.com/diaspora/diaspora/pull/7300) [#7394](https://github.com/diaspora/diaspora/pull/7394)
|
||||
* Render mentions as links in comments [#7327](https://github.com/diaspora/diaspora/pull/7327)
|
||||
* Add support for mentions in comments to the front-end [#7386](https://github.com/diaspora/diaspora/pull/7386)
|
||||
* Support direct links to comments on mobile [#7508](https://github.com/diaspora/diaspora/pull/7508)
|
||||
* Add inviter first and last name in the invitation e-mail [#7484](https://github.com/diaspora/diaspora/pull/7484)
|
||||
* Add markdown editor for comments and conversations [#7482](https://github.com/diaspora/diaspora/pull/7482)
|
||||
* Improve responsive header in desktop version [#7509](https://github.com/diaspora/diaspora/pull/7509)
|
||||
* Support cmd+enter to submit posts, comments and conversations [#7524](https://github.com/diaspora/diaspora/pull/7524)
|
||||
* Add markdown editor for posts, comments and conversations on mobile [#7235](https://github.com/diaspora/diaspora/pull/7235)
|
||||
* Mark as "Mobile Web App Capable" on Android [#7534](https://github.com/diaspora/diaspora/pull/7534)
|
||||
* Add support for receiving account migrations [#6750](https://github.com/diaspora/diaspora/pull/6750)
|
||||
|
||||
# 0.6.7.0
|
||||
|
||||
## Refactor
|
||||
|
|
|
|||
151
Gemfile
151
Gemfile
|
|
@ -1,29 +1,30 @@
|
|||
source "https://rubygems.org"
|
||||
|
||||
gem "rails", "4.2.8"
|
||||
gem "rails", "5.1.3"
|
||||
|
||||
# Legacy Rails features, remove me!
|
||||
# responders (class level)
|
||||
gem "responders", "2.3.0"
|
||||
gem "responders", "2.4.0"
|
||||
|
||||
# Appserver
|
||||
|
||||
gem "unicorn", "5.2.0", require: false
|
||||
gem "unicorn", "5.3.0", require: false
|
||||
gem "unicorn-worker-killer", "0.4.4"
|
||||
|
||||
# Federation
|
||||
|
||||
gem "diaspora_federation-rails", "0.1.9"
|
||||
gem "diaspora_federation-json_schema", "0.2.1"
|
||||
gem "diaspora_federation-rails", "0.2.1"
|
||||
|
||||
# API and JSON
|
||||
|
||||
gem "acts_as_api", "1.0.0"
|
||||
gem "json", "1.8.6"
|
||||
gem "acts_as_api", "1.0.1"
|
||||
gem "json", "2.1.0"
|
||||
gem "json-schema", "2.8.0"
|
||||
|
||||
# Authentication
|
||||
|
||||
gem "devise", "4.2.0"
|
||||
gem "devise", "4.3.0"
|
||||
gem "devise_lastseenable", "0.0.6"
|
||||
|
||||
# Captcha
|
||||
|
|
@ -32,15 +33,15 @@ gem "simple_captcha2", "0.4.3", require: "simple_captcha"
|
|||
|
||||
# Background processing
|
||||
|
||||
gem "sidekiq", "4.2.9"
|
||||
gem "sidekiq", "5.0.4"
|
||||
|
||||
# Scheduled processing
|
||||
|
||||
gem "sidekiq-cron", "0.4.5"
|
||||
gem "sidekiq-cron", "0.6.3"
|
||||
|
||||
# Compression
|
||||
|
||||
gem "uglifier", "3.1.2"
|
||||
gem "uglifier", "3.2.0"
|
||||
|
||||
# Configuration
|
||||
|
||||
|
|
@ -48,33 +49,34 @@ gem "configurate", "0.3.1"
|
|||
|
||||
# Cross-origin resource sharing
|
||||
|
||||
gem "rack-cors", "0.4.1", require: "rack/cors"
|
||||
gem "rack-cors", "1.0.1", require: "rack/cors"
|
||||
|
||||
# CSS
|
||||
|
||||
gem "autoprefixer-rails", "6.7.6"
|
||||
gem "autoprefixer-rails", "7.1.2.4"
|
||||
gem "bootstrap-sass", "3.3.7"
|
||||
gem "bootstrap-switch-rails", "3.3.3"
|
||||
gem "compass-rails", "2.0.5"
|
||||
gem "compass-rails", "3.0.2"
|
||||
gem "sass-rails", "5.0.6"
|
||||
gem "sprockets-rails", "3.2.0"
|
||||
|
||||
# Database
|
||||
|
||||
group :mysql, optional: true do
|
||||
gem "mysql2", "0.4.5"
|
||||
gem "mysql2", "0.4.9"
|
||||
end
|
||||
group :postgresql, optional: true do
|
||||
gem "pg", "0.19.0"
|
||||
gem "pg", "0.21.0"
|
||||
end
|
||||
|
||||
|
||||
gem "activerecord-import", "0.17.1"
|
||||
gem "activerecord-import", "0.19.1"
|
||||
|
||||
# File uploading
|
||||
|
||||
gem "fog-aws", "1.2.1"
|
||||
gem "carrierwave", "0.11.2"
|
||||
gem "mini_magick", "4.6.1"
|
||||
gem "carrierwave", "1.1.0"
|
||||
gem "fog-aws", "1.4.0"
|
||||
gem "mini_magick", "4.8.0"
|
||||
|
||||
# GUID generation
|
||||
gem "uuid", "2.3.8"
|
||||
|
|
@ -85,19 +87,19 @@ gem "entypo-rails", "3.0.0"
|
|||
|
||||
# JavaScript
|
||||
|
||||
gem "handlebars_assets", "0.23.1"
|
||||
gem "jquery-rails", "4.2.1"
|
||||
gem "jquery-ui-rails", "5.0.5"
|
||||
gem "handlebars_assets", "0.23.2"
|
||||
gem "jquery-rails", "4.3.1"
|
||||
gem "js-routes", "1.3.3"
|
||||
gem "js_image_paths", "0.1.0"
|
||||
gem "js_image_paths", "0.1.1"
|
||||
|
||||
source "https://rails-assets.org" do
|
||||
gem "rails-assets-jquery", "2.2.4" # Should be kept in sync with jquery-rails
|
||||
gem "rails-assets-jquery", "3.2.1" # Should be kept in sync with jquery-rails
|
||||
gem "rails-assets-jquery.ui", "1.11.4"
|
||||
|
||||
gem "rails-assets-highlightjs", "9.9.0"
|
||||
gem "rails-assets-markdown-it", "8.3.0"
|
||||
gem "rails-assets-highlightjs", "9.12.0"
|
||||
gem "rails-assets-markdown-it", "8.3.2"
|
||||
gem "rails-assets-markdown-it-hashtag", "0.4.0"
|
||||
gem "rails-assets-markdown-it-diaspora-mention", "1.1.1"
|
||||
gem "rails-assets-markdown-it-diaspora-mention", "1.2.0"
|
||||
gem "rails-assets-markdown-it-sanitizer", "0.4.3"
|
||||
gem "rails-assets-markdown-it--markdown-it-for-inline", "0.1.1"
|
||||
gem "rails-assets-markdown-it-sub", "1.0.0"
|
||||
|
|
@ -110,8 +112,8 @@ source "https://rails-assets.org" do
|
|||
|
||||
# jQuery plugins
|
||||
|
||||
gem "rails-assets-autosize", "3.0.20"
|
||||
gem "rails-assets-blueimp-gallery", "2.25.0"
|
||||
gem "rails-assets-autosize", "4.0.0"
|
||||
gem "rails-assets-blueimp-gallery", "2.25.2"
|
||||
gem "rails-assets-jquery.are-you-sure", "1.9.0"
|
||||
gem "rails-assets-jquery-placeholder", "2.3.1"
|
||||
gem "rails-assets-jquery-textchange", "0.2.3"
|
||||
|
|
@ -120,24 +122,24 @@ end
|
|||
|
||||
# Localization
|
||||
|
||||
gem "http_accept_language", "2.1.0"
|
||||
gem "http_accept_language", "2.1.1"
|
||||
gem "i18n-inflector-rails", "1.0.7"
|
||||
gem "rails-i18n", "4.0.8"
|
||||
gem "rails-i18n", "5.0.4"
|
||||
|
||||
# Mail
|
||||
|
||||
gem "markerb", "1.1.0"
|
||||
|
||||
# Map
|
||||
gem "leaflet-rails", "0.7.7"
|
||||
gem "leaflet-rails", "1.1.0"
|
||||
|
||||
# Parsing
|
||||
|
||||
gem "nokogiri", "1.7.2"
|
||||
gem "nokogiri", "1.8.0"
|
||||
gem "open_graph_reader", "0.6.2" # also update User-Agent in features/support/webmock.rb
|
||||
gem "redcarpet", "3.4.0"
|
||||
gem "ruby-oembed", "0.10.1"
|
||||
gem "twitter-text", "1.14.5"
|
||||
gem "ruby-oembed", "0.12.0"
|
||||
gem "twitter-text", "1.14.7"
|
||||
|
||||
# RTL support
|
||||
|
||||
|
|
@ -145,11 +147,11 @@ gem "string-direction", "1.2.0"
|
|||
|
||||
# Security Headers
|
||||
|
||||
gem "secure_headers", "3.6.1"
|
||||
gem "secure_headers", "3.6.7"
|
||||
|
||||
# Services
|
||||
|
||||
gem "omniauth", "1.4.2"
|
||||
gem "omniauth", "1.6.1"
|
||||
gem "omniauth-facebook", "4.0.0"
|
||||
gem "omniauth-tumblr", "1.2"
|
||||
gem "omniauth-twitter", "1.4.0"
|
||||
|
|
@ -157,11 +159,11 @@ gem "twitter", "6.1.0"
|
|||
gem "omniauth-wordpress", "0.2.2"
|
||||
|
||||
# OpenID Connect
|
||||
gem "openid_connect", "0.12.0"
|
||||
gem "openid_connect", "1.1.3"
|
||||
|
||||
# Serializers
|
||||
|
||||
gem "active_model_serializers", "0.9.5"
|
||||
gem "active_model_serializers", "0.9.7"
|
||||
|
||||
# XMPP chat dependencies
|
||||
gem "diaspora-prosody-config", "0.0.7"
|
||||
|
|
@ -169,11 +171,11 @@ gem "rails-assets-diaspora_jsxc", "0.1.5.develop.7", source: "https://rails-asse
|
|||
|
||||
# Tags
|
||||
|
||||
gem "acts-as-taggable-on", "3.5.0"
|
||||
gem "acts-as-taggable-on", "5.0.0"
|
||||
|
||||
# URIs and HTTP
|
||||
|
||||
gem "addressable", "2.5.0", require: "addressable/uri"
|
||||
gem "addressable", "2.5.1", require: "addressable/uri"
|
||||
gem "faraday", "0.11.0" # also update User-Agent in OpenID specs
|
||||
gem "faraday_middleware", "0.11.0.1"
|
||||
gem "faraday-cookie_jar", "0.0.6"
|
||||
|
|
@ -182,14 +184,14 @@ gem "typhoeus", "1.1.2"
|
|||
# Views
|
||||
|
||||
gem "gon", "6.1.0"
|
||||
gem "hamlit", "2.8.0"
|
||||
gem "mobile-fu", "1.3.1"
|
||||
gem "hamlit", "2.8.4"
|
||||
gem "mobile_fu", "1.4.0", require: "mobile-fu"
|
||||
gem "rails-timeago", "2.16.0"
|
||||
gem "will_paginate", "3.1.5"
|
||||
gem "will_paginate", "3.1.6"
|
||||
|
||||
# Logging
|
||||
|
||||
gem "logging-rails", "0.5.0", require: "logging/rails"
|
||||
gem "logging-rails", "0.6.0", require: "logging/rails"
|
||||
|
||||
# Reading and writing zip files
|
||||
|
||||
|
|
@ -202,13 +204,7 @@ gem "rubyzip", "1.2.1", require: "zip"
|
|||
# https://github.com/discourse/discourse/pull/238
|
||||
gem "minitest"
|
||||
|
||||
gem "versionist", "1.5.0"
|
||||
|
||||
# Prevent accidental upgrades of thor
|
||||
# TODO: remove this when either all gems depending on thor have fixed the warnings
|
||||
# or thor released a version where they are clearly marked as warnings
|
||||
# see: https://github.com/erikhuda/thor/issues/538
|
||||
gem "thor", "0.19.1"
|
||||
gem "versionist", "1.6.0"
|
||||
|
||||
# Windows and OSX have an execjs compatible runtime built-in, Linux users should
|
||||
# install Node.js or use "therubyracer".
|
||||
|
|
@ -225,7 +221,7 @@ group :production do # we don"t install these on travis to speed up test runs
|
|||
|
||||
# Process management
|
||||
|
||||
gem "eye", "0.9.1"
|
||||
gem "eye", "0.9.2"
|
||||
|
||||
# Redirects
|
||||
|
||||
|
|
@ -234,7 +230,7 @@ group :production do # we don"t install these on travis to speed up test runs
|
|||
|
||||
# Third party asset hosting
|
||||
|
||||
gem "asset_sync", "2.0.0", require: false
|
||||
gem "asset_sync", "2.2.0", require: false
|
||||
end
|
||||
|
||||
group :development do
|
||||
|
|
@ -242,22 +238,22 @@ group :development do
|
|||
gem "guard", "2.14.1", require: false
|
||||
gem "guard-cucumber", "2.1.2", require: false
|
||||
gem "guard-rspec", "4.7.3", require: false
|
||||
gem "guard-rubocop", "1.2.0", require: false
|
||||
gem "rb-fsevent", "0.9.8", require: false
|
||||
gem "rb-inotify", "0.9.8", require: false
|
||||
gem "guard-rubocop", "1.3.0", require: false
|
||||
gem "rb-fsevent", "0.10.2", require: false
|
||||
gem "rb-inotify", "0.9.10", require: false
|
||||
|
||||
# Linters
|
||||
gem "haml_lint", "0.24.0", require: false
|
||||
gem "pronto", "0.9.3", require: false
|
||||
gem "haml_lint", "0.26.0", require: false
|
||||
gem "pronto", "0.9.4", require: false
|
||||
gem "pronto-eslint", "0.9.1", require: false
|
||||
gem "pronto-haml", "0.9.0", require: false
|
||||
gem "pronto-rubocop", "0.9.0", require: false
|
||||
gem "pronto-scss", "0.9.1", require: false
|
||||
gem "rubocop", "0.48.1", require: false
|
||||
gem "rubocop", "0.49.1", require: false
|
||||
|
||||
# Preloading environment
|
||||
|
||||
gem "spring", "2.0.1"
|
||||
gem "spring", "2.0.2"
|
||||
gem "spring-commands-rspec", "1.0.4"
|
||||
gem "spring-commands-cucumber", "1.0.1"
|
||||
|
||||
|
|
@ -266,7 +262,7 @@ group :development do
|
|||
gem "pry-byebug"
|
||||
|
||||
# test coverage
|
||||
gem "simplecov", "0.12.0", require: false
|
||||
gem "simplecov", "0.14.1", require: false
|
||||
|
||||
gem "turbo_dev_assets", "0.0.2"
|
||||
end
|
||||
|
|
@ -274,44 +270,45 @@ end
|
|||
group :test do
|
||||
# RSpec (unit tests, some integration tests)
|
||||
|
||||
gem "fixture_builder", "0.4.1"
|
||||
gem "fixture_builder", "0.5.0"
|
||||
gem "fuubar", "2.2.0"
|
||||
gem "test_after_commit", "1.1.0"
|
||||
gem "json-schema-rspec", "0.0.4"
|
||||
gem "rspec-json_expectations", "~> 2.1"
|
||||
|
||||
# Cucumber (integration tests)
|
||||
|
||||
gem "capybara", "2.12.1"
|
||||
gem "database_cleaner", "1.5.3"
|
||||
gem "poltergeist", "1.13.0"
|
||||
gem "capybara", "2.15.1"
|
||||
gem "database_cleaner", "1.6.1"
|
||||
gem "poltergeist", "1.16.0"
|
||||
|
||||
gem "cucumber-api-steps", "0.13", require: false
|
||||
|
||||
# General helpers
|
||||
|
||||
gem "factory_girl_rails", "4.8.0"
|
||||
gem "timecop", "0.8.1"
|
||||
gem "webmock", "2.3.2", require: false
|
||||
gem "shoulda-matchers", "3.1.1"
|
||||
gem "shoulda-matchers", "3.1.2"
|
||||
gem "timecop", "0.9.1"
|
||||
gem "webmock", "3.0.1", require: false
|
||||
|
||||
gem "diaspora_federation-test", "0.1.9"
|
||||
gem "diaspora_federation-test", "0.2.1"
|
||||
|
||||
# Coverage
|
||||
gem 'coveralls', require: false
|
||||
gem "coveralls", "0.8.21", require: false
|
||||
end
|
||||
|
||||
group :development, :test do
|
||||
# RSpec (unit tests, some integration tests)
|
||||
gem "rspec-rails", "3.5.2"
|
||||
gem "rspec-rails", "3.6.1"
|
||||
|
||||
# Cucumber (integration tests)
|
||||
gem "cucumber-rails", "1.4.5", require: false
|
||||
gem "cucumber-rails", "1.5.0", require: false
|
||||
|
||||
# Jasmine (client side application tests (JS))
|
||||
gem "jasmine", "2.5.2"
|
||||
gem "jasmine", "2.7.0"
|
||||
gem "jasmine-jquery-rails", "2.0.3"
|
||||
gem "rails-assets-jasmine-ajax", "3.3.1", source: "https://rails-assets.org"
|
||||
gem "sinon-rails", "1.15.0"
|
||||
|
||||
# silence assets
|
||||
gem "quiet_assets", "1.1.0"
|
||||
# For `assigns` in controller specs
|
||||
gem "rails-controller-testing", "1.0.2"
|
||||
end
|
||||
|
|
|
|||
626
Gemfile.lock
626
Gemfile.lock
File diff suppressed because it is too large
Load diff
|
|
@ -121,12 +121,6 @@ var app = {
|
|||
app.flashMessages = new app.views.FlashMessages({el: $("#flash-container")});
|
||||
},
|
||||
|
||||
/* mixpanel wrapper function */
|
||||
instrument : function(type, name, object, callback) {
|
||||
if(!window.mixpanel) { return; }
|
||||
window.mixpanel[type](name, object, callback);
|
||||
},
|
||||
|
||||
setupDisabledLinks: function() {
|
||||
$("a.disabled").click(function(event) {
|
||||
event.preventDefault();
|
||||
|
|
|
|||
|
|
@ -48,12 +48,6 @@ app.models.Post = Backbone.Model.extend(_.extend({}, app.models.formatDateMixin,
|
|||
var body = this.get("text").trim()
|
||||
, newlineIdx = body.indexOf("\n");
|
||||
return (newlineIdx > 0 ) ? body.substr(newlineIdx+1, body.length) : "";
|
||||
},
|
||||
|
||||
//returns a promise
|
||||
preloadOrFetch : function(){
|
||||
var action = app.hasPreload("post") ? this.set(app.parsePreload("post")) : this.fetch();
|
||||
return $.when(action);
|
||||
}
|
||||
}));
|
||||
// @license-end
|
||||
|
|
|
|||
|
|
@ -3,10 +3,6 @@
|
|||
//require ../post
|
||||
|
||||
app.models.Post.Interactions = Backbone.Model.extend({
|
||||
url : function(){
|
||||
return this.post.url() + "/interactions";
|
||||
},
|
||||
|
||||
initialize : function(options){
|
||||
this.post = options.post;
|
||||
this.comments = new app.collections.Comments(this.get("comments"), {post : this.post});
|
||||
|
|
@ -14,33 +10,16 @@ app.models.Post.Interactions = Backbone.Model.extend({
|
|||
this.reshares = new app.collections.Reshares(this.get("reshares"), {post : this.post});
|
||||
},
|
||||
|
||||
parse : function(resp){
|
||||
this.comments.reset(resp.comments);
|
||||
this.likes.reset(resp.likes);
|
||||
this.reshares.reset(resp.reshares);
|
||||
|
||||
var comments = this.comments
|
||||
, likes = this.likes
|
||||
, reshares = this.reshares;
|
||||
|
||||
return {
|
||||
comments : comments,
|
||||
likes : likes,
|
||||
reshares : reshares,
|
||||
fetched : true
|
||||
};
|
||||
},
|
||||
|
||||
likesCount : function(){
|
||||
return this.get("fetched") ? this.likes.models.length : this.get("likes_count");
|
||||
return this.get("likes_count");
|
||||
},
|
||||
|
||||
resharesCount : function(){
|
||||
return this.get("fetched") ? this.reshares.models.length : this.get("reshares_count");
|
||||
return this.get("reshares_count");
|
||||
},
|
||||
|
||||
commentsCount : function(){
|
||||
return this.get("fetched") ? this.comments.models.length : this.get("comments_count");
|
||||
return this.get("comments_count");
|
||||
},
|
||||
|
||||
userLike : function(){
|
||||
|
|
@ -76,8 +55,6 @@ app.models.Post.Interactions = Backbone.Model.extend({
|
|||
app.flashMessages.handleAjaxError(response);
|
||||
}
|
||||
});
|
||||
|
||||
app.instrument("track", "Like");
|
||||
},
|
||||
|
||||
unlike : function() {
|
||||
|
|
@ -87,8 +64,6 @@ app.models.Post.Interactions = Backbone.Model.extend({
|
|||
self.set({"likes_count" : self.get("likes_count") - 1});
|
||||
self.likes.trigger("change");
|
||||
}});
|
||||
|
||||
app.instrument("track", "Unlike");
|
||||
},
|
||||
|
||||
comment: function(text, options) {
|
||||
|
|
@ -104,8 +79,6 @@ app.models.Post.Interactions = Backbone.Model.extend({
|
|||
self.trigger('change'); //updates after sync
|
||||
if (options.success) { options.success(); }
|
||||
});
|
||||
|
||||
app.instrument("track", "Comment");
|
||||
},
|
||||
|
||||
reshare : function(){
|
||||
|
|
@ -126,8 +99,6 @@ app.models.Post.Interactions = Backbone.Model.extend({
|
|||
.fail(function(response) {
|
||||
app.flashMessages.handleAjaxError(response);
|
||||
});
|
||||
|
||||
app.instrument("track", "Reshare");
|
||||
},
|
||||
|
||||
userCanReshare : function(){
|
||||
|
|
|
|||
|
|
@ -13,8 +13,16 @@ app.models.Stream = Backbone.Collection.extend({
|
|||
},
|
||||
|
||||
collectionOptions :function(){
|
||||
var order = this.sortOrder();
|
||||
return { comparator : function(item) { return -item[order](); } };
|
||||
var order = this.sortOrder();
|
||||
return {
|
||||
comparator: function(item1, item2) {
|
||||
if (item1[order]() < item2[order]()) { return 1; }
|
||||
if (item1[order]() > item2[order]()) { return -1; }
|
||||
if (item1.id < item2.id) { return 1; }
|
||||
if (item1.id > item2.id) { return -1; }
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
url : function(){
|
||||
|
|
|
|||
|
|
@ -9,9 +9,8 @@ app.pages.SinglePostViewer = app.views.Base.extend({
|
|||
},
|
||||
|
||||
initialize : function() {
|
||||
this.model = new app.models.Post({ id : gon.post.id });
|
||||
this.model.preloadOrFetch().done(_.bind(this.initViews, this));
|
||||
this.model.interactions.fetch(); //async, yo, might want to throttle this later.
|
||||
this.model = new app.models.Post(gon.post);
|
||||
this.initViews();
|
||||
},
|
||||
|
||||
initViews : function() {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ app.Router = Backbone.Router.extend({
|
|||
"commented(/)": "stream",
|
||||
"community_spotlight(/)": "spotlight",
|
||||
"contacts(/)": "contacts",
|
||||
"conversations(/)(:id)(/)": "conversations",
|
||||
"conversations(/)(:id)(?conversation_id=:conversation_id)(/)": "conversations",
|
||||
"followed_tags(/)": "followed_tags",
|
||||
"getting_started(/)": "gettingStarted",
|
||||
"help(/)": "help",
|
||||
|
|
@ -93,8 +93,8 @@ app.Router = Backbone.Router.extend({
|
|||
app.page = new app.pages.Contacts({stream: stream});
|
||||
},
|
||||
|
||||
conversations: function(id) {
|
||||
app.conversations = app.conversations || new app.views.ConversationsInbox();
|
||||
conversations: function(id, conversationId) {
|
||||
app.conversations = app.conversations || new app.views.ConversationsInbox(conversationId);
|
||||
if (parseInt("" + id, 10)) {
|
||||
app.conversations.renderConversation(id);
|
||||
}
|
||||
|
|
@ -182,7 +182,7 @@ app.Router = Backbone.Router.extend({
|
|||
},
|
||||
|
||||
singlePost: function(id) {
|
||||
this.renderPage(function() { return new app.pages.SinglePostViewer({id: id}); });
|
||||
this.renderPage(function() { return new app.pages.SinglePostViewer({id: id, el: $("#container")}); });
|
||||
},
|
||||
|
||||
spotlight: function() {
|
||||
|
|
|
|||
10
app/assets/javascripts/app/views/comment_mention_view.js
Normal file
10
app/assets/javascripts/app/views/comment_mention_view.js
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
|
||||
//= require ./publisher/mention_view
|
||||
|
||||
app.views.CommentMention = app.views.PublisherMention.extend({
|
||||
initialize: function(opts) {
|
||||
opts.url = Routes.mentionablePost(opts.postId);
|
||||
app.views.PublisherMention.prototype.initialize.call(this, opts);
|
||||
}
|
||||
});
|
||||
// @license-end
|
||||
|
|
@ -9,8 +9,8 @@ app.views.CommentStream = app.views.Base.extend({
|
|||
events: {
|
||||
"keydown .comment_box": "keyDownOnCommentBox",
|
||||
"submit form": "createComment",
|
||||
"focus .comment_box": "commentTextareaFocused",
|
||||
"click .toggle_post_comments": "expandComments"
|
||||
"click .toggle_post_comments": "expandComments",
|
||||
"click form": "openForm"
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
|
|
@ -21,12 +21,22 @@ app.views.CommentStream = app.views.Base.extend({
|
|||
setupBindings: function() {
|
||||
this.model.comments.bind("add", this.appendComment, this);
|
||||
this.model.comments.bind("remove", this.removeComment, this);
|
||||
$(document.body).click(this.onFormBlur.bind(this));
|
||||
},
|
||||
|
||||
postRenderTemplate : function() {
|
||||
this.model.comments.each(this.appendComment, this);
|
||||
this.commentBox = this.$(".comment_box");
|
||||
this.commentSubmitButton = this.$("input[name='commit']");
|
||||
this.mentions = new app.views.CommentMention({el: this.$el, postId: this.model.get("id")});
|
||||
|
||||
this.mdEditor = new Diaspora.MarkdownEditor(this.$(".comment_box"), {
|
||||
onPreview: function($mdInstance) {
|
||||
var renderedText = app.helpers.textFormatter($mdInstance.getContent(), this.mentions.getMentionedPeople());
|
||||
return "<div class='preview-content'>" + renderedText + "</div>";
|
||||
}.bind(this),
|
||||
onFocus: this.openForm.bind(this)
|
||||
});
|
||||
},
|
||||
|
||||
presenter: function(){
|
||||
|
|
@ -52,11 +62,14 @@ app.views.CommentStream = app.views.Base.extend({
|
|||
success: function() {
|
||||
this.commentBox.val("");
|
||||
this.enableCommentBox();
|
||||
this.mdEditor.hidePreview();
|
||||
this.closeForm();
|
||||
autosize.update(this.commentBox);
|
||||
}.bind(this),
|
||||
error: function() {
|
||||
this.enableCommentBox();
|
||||
this.commentBox.focus();
|
||||
this.mdEditor.hidePreview();
|
||||
this.openForm();
|
||||
}.bind(this)
|
||||
});
|
||||
},
|
||||
|
|
@ -72,7 +85,7 @@ app.views.CommentStream = app.views.Base.extend({
|
|||
},
|
||||
|
||||
keyDownOnCommentBox: function(evt) {
|
||||
if(evt.which === Keycodes.ENTER && evt.ctrlKey) {
|
||||
if (evt.which === Keycodes.ENTER && (evt.metaKey || evt.ctrlKey)) {
|
||||
this.$("form").submit();
|
||||
return false;
|
||||
}
|
||||
|
|
@ -105,7 +118,8 @@ app.views.CommentStream = app.views.Base.extend({
|
|||
// on post ownership in the Comment view.
|
||||
comment.set({parent : this.model.toJSON()});
|
||||
|
||||
var commentHtml = new this.CommentView({model: comment}).render().el;
|
||||
var commentView = new this.CommentView({model: comment});
|
||||
var commentHtml = commentView.render().el;
|
||||
var commentBlocks = this.$(".comments div.comment.media");
|
||||
this._moveInsertPoint(comment.get("created_at"), commentBlocks);
|
||||
if (this._insertPoint >= commentBlocks.length) {
|
||||
|
|
@ -115,16 +129,13 @@ app.views.CommentStream = app.views.Base.extend({
|
|||
} else {
|
||||
commentBlocks.eq(this._insertPoint).before(commentHtml);
|
||||
}
|
||||
commentView.renderPluginWidgets();
|
||||
},
|
||||
|
||||
removeComment: function(comment) {
|
||||
this.$("#" + comment.get("guid")).closest(".comment.media").remove();
|
||||
},
|
||||
|
||||
commentTextareaFocused: function(){
|
||||
this.$("form").removeClass('hidden').addClass("open");
|
||||
},
|
||||
|
||||
expandComments: function(evt){
|
||||
this.$(".loading-comments").removeClass("hidden");
|
||||
if(evt){ evt.preventDefault(); }
|
||||
|
|
@ -134,6 +145,37 @@ app.views.CommentStream = app.views.Base.extend({
|
|||
this.$(".loading-comments").addClass("hidden");
|
||||
}.bind(this)
|
||||
});
|
||||
},
|
||||
|
||||
openForm: function() {
|
||||
this.$("form").addClass("open");
|
||||
this.$(".md-editor").addClass("active");
|
||||
},
|
||||
|
||||
closeForm: function() {
|
||||
this.$("form").removeClass("open");
|
||||
this.$(".md-editor").removeClass("active");
|
||||
this.commentBox.blur();
|
||||
autosize.update(this.commentBox);
|
||||
},
|
||||
|
||||
isCloseAllowed: function() {
|
||||
if (this.mdEditor === undefined) {
|
||||
return true;
|
||||
}
|
||||
return !this.mdEditor.isPreviewMode() && this.mdEditor.userInputEmpty();
|
||||
},
|
||||
|
||||
onFormBlur: function(evt) {
|
||||
if (!this.isCloseAllowed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $target = $(evt.target);
|
||||
var isForm = $target.hasClass("new-comment") || $target.parents(".new-comment").length !== 0;
|
||||
if (!isForm && !$target.hasClass("focus_comment_textarea")) {
|
||||
this.closeForm();
|
||||
}
|
||||
}
|
||||
});
|
||||
// @license-end
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
app.views.Comment = app.views.Content.extend({
|
||||
templateName: "comment",
|
||||
className : "comment media",
|
||||
tooltipSelector: "time",
|
||||
|
||||
events : function() {
|
||||
return _.extend({}, app.views.Content.prototype.events, {
|
||||
|
|
@ -20,7 +21,7 @@ app.views.Comment = app.views.Content.extend({
|
|||
presenter : function() {
|
||||
return _.extend(this.defaultPresenter(), {
|
||||
canRemove: this.canRemove(),
|
||||
text : app.helpers.textFormatter(this.model.get("text"))
|
||||
text: app.helpers.textFormatter(this.model.get("text"), this.model.get("mentioned_people"))
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -17,15 +17,14 @@ app.views.Content = app.views.Base.extend({
|
|||
|
||||
largePhoto : function() {
|
||||
var photos = this.model.get("photos");
|
||||
if(!photos || photos.length === 0) { return }
|
||||
if (!photos || photos.length === 0) { return false; }
|
||||
return photos[0];
|
||||
},
|
||||
|
||||
smallPhotos : function() {
|
||||
var photos = this.model.get("photos");
|
||||
if(!photos || photos.length < 2) { return }
|
||||
photos.splice(0, 1); // remove first photo as it is already shown as largePhoto
|
||||
return photos;
|
||||
if (!photos || photos.length < 2) { return false; }
|
||||
return photos.slice(1); // remove first photo as it is already shown as largePhoto
|
||||
},
|
||||
|
||||
expandPost: function(evt) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ app.views.ConversationsForm = app.views.Base.extend({
|
|||
remoteRoute: {url: "/contacts", extraParameters: "mutual=true"}
|
||||
});
|
||||
|
||||
this.newConversationMdEditor = this.renderMarkdownEditor("#new-message-text");
|
||||
|
||||
this.bindTypeaheadEvents();
|
||||
|
||||
this.tagListElement.empty();
|
||||
|
|
@ -31,10 +33,16 @@ app.views.ConversationsForm = app.views.Base.extend({
|
|||
this.prefill(opts.prefill);
|
||||
}
|
||||
|
||||
this.$("form#new-conversation").on("ajax:success", this.conversationCreateSuccess);
|
||||
this.$("form#new-conversation").on("ajax:success", this.conversationCreateSuccess.bind(this));
|
||||
this.$("form#new-conversation").on("ajax:error", this.conversationCreateError);
|
||||
},
|
||||
|
||||
renderMarkdownEditor: function(element) {
|
||||
return new Diaspora.MarkdownEditor($(element), {
|
||||
onPreview: Diaspora.MarkdownEditor.simplePreview
|
||||
});
|
||||
},
|
||||
|
||||
addRecipient: function(person) {
|
||||
this.conversationRecipients.push(person);
|
||||
this.updateContactIdsListInput();
|
||||
|
|
@ -66,7 +74,7 @@ app.views.ConversationsForm = app.views.Base.extend({
|
|||
},
|
||||
|
||||
keyDown: function(evt) {
|
||||
if (evt.which === Keycodes.ENTER && evt.ctrlKey) {
|
||||
if (evt.which === Keycodes.ENTER && (evt.metaKey || evt.ctrlKey)) {
|
||||
$(evt.target).parents("form").submit();
|
||||
}
|
||||
},
|
||||
|
|
@ -84,6 +92,7 @@ app.views.ConversationsForm = app.views.Base.extend({
|
|||
},
|
||||
|
||||
conversationCreateSuccess: function(evt, data) {
|
||||
this.newConversationMdEditor.hidePreview();
|
||||
app._changeLocation(Routes.conversation(data.id));
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -8,11 +8,21 @@ app.views.ConversationsInbox = app.views.Base.extend({
|
|||
"click .new-conversation-btn": "displayNewConversation"
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
new app.views.ConversationsForm();
|
||||
initialize: function(conversationId) {
|
||||
this.conversationForm = new app.views.ConversationsForm();
|
||||
|
||||
// Creates markdown editor in case of displaying preloaded conversation
|
||||
if (conversationId != null) {
|
||||
this.renderMarkdownEditor();
|
||||
}
|
||||
|
||||
this.setupConversation();
|
||||
},
|
||||
|
||||
renderMarkdownEditor: function() {
|
||||
this.conversationForm.renderMarkdownEditor("#conversation-show .conversation-message-text");
|
||||
},
|
||||
|
||||
renderConversation: function(conversationId) {
|
||||
var self = this;
|
||||
$.ajax({
|
||||
|
|
@ -23,6 +33,8 @@ app.views.ConversationsInbox = app.views.Base.extend({
|
|||
self.$el.find("#conversation-show").removeClass("hidden").html(data);
|
||||
self.selectConversation(conversationId);
|
||||
self.setupConversation();
|
||||
self.renderMarkdownEditor();
|
||||
autosize(self.$("#conversation-show textarea"));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -4,27 +4,29 @@ app.views.Help = app.views.StaticContentView.extend({
|
|||
templateName : "help",
|
||||
|
||||
events : {
|
||||
"click .faq-link" : "sectionClicked",
|
||||
"click .faq-link-getting-help" : "gettingHelp",
|
||||
"click .faq-link-sharing" : "sharing",
|
||||
"click .faq-link-posts-and-posting" : "postsAndPosting",
|
||||
"click .faq-link": "sectionClicked",
|
||||
"click .faq-link-getting-help": "gettingHelp",
|
||||
"click .faq-link-sharing": "sharing",
|
||||
"click .faq-link-posts-and-posting": "postsAndPosting",
|
||||
"click .faq-link-tags": "tags",
|
||||
"click .faq-link-keyboard-shortcuts" : "keyboardShortcuts",
|
||||
"click .faq-link-chat" : "chat"
|
||||
"click .faq-link-keyboard-shortcuts": "keyboardShortcuts",
|
||||
"click .faq-link-chat": "chat"
|
||||
},
|
||||
|
||||
initialize : function() {
|
||||
this.GETTING_HELP_SUBS = {
|
||||
getting_started_a: { tutorial_series: this.linkHtml("http://diasporafoundation.org/getting_started/sign_up", Diaspora.I18n.t( 'getting_started_tutorial' )) },
|
||||
get_support_a_website: { link: this.linkHtml("https://diasporafoundation.org/", Diaspora.I18n.t( 'foundation_website' ))},
|
||||
get_support_a_tutorials: { tutorials: this.linkHtml("https://diasporafoundation.org/tutorials", Diaspora.I18n.t( 'tutorials' ))},
|
||||
get_support_a_wiki: { link: this.linkHtml("https://wiki.diasporafoundation.org/Special:Search", Diaspora.I18n.t( 'wiki' ))},
|
||||
get_support_a_irc: { irc: this.linkHtml("https://wiki.diasporafoundation.org/How_We_Communicate#IRC", Diaspora.I18n.t( 'irc' ))},
|
||||
get_support_a_faq: { faq: this.linkHtml("https://wiki.diasporafoundation.org/FAQ_for_users", Diaspora.I18n.t( 'faq' ))},
|
||||
get_support_a_hashtag: { question: this.linkHtml("/tags/question", "#question")}
|
||||
getting_started_a: {tutorial_series: this.linkHtml("http://diasporafoundation.org/getting_started/sign_up", Diaspora.I18n.t("getting_started_tutorial"))},
|
||||
get_support_a_website: {link: this.linkHtml("https://diasporafoundation.org/", Diaspora.I18n.t("foundation_website"))},
|
||||
get_support_a_tutorials: {tutorials: this.linkHtml("https://diasporafoundation.org/tutorials", Diaspora.I18n.t("tutorials"))},
|
||||
get_support_a_wiki: {link: this.linkHtml("https://wiki.diasporafoundation.org/Special:Search", Diaspora.I18n.t("wiki"))},
|
||||
get_support_a_irc: {irc: this.linkHtml("https://wiki.diasporafoundation.org/How_We_Communicate#IRC", Diaspora.I18n.t("irc"))},
|
||||
get_support_a_faq: {faq: this.linkHtml("https://wiki.diasporafoundation.org/FAQ_for_users", Diaspora.I18n.t("faq"))},
|
||||
get_support_a_hashtag: {question: this.linkHtml("/tags/question", "#question")},
|
||||
get_support_a_discourse: {discourse: this.linkHtml("https://discourse.diasporafoundation.org/c/support", "discussions & support")}
|
||||
};
|
||||
|
||||
this.POSTS_AND_POSTING_SUBS = {
|
||||
post_report_a: {community_guidelines: this.linkHtml("https://diasporafoundation.org/community_guidelines", Diaspora.I18n.t("community_guidelines"))},
|
||||
format_text_a: {
|
||||
markdown: this.linkHtml("http://diasporafoundation.org/formatting", Diaspora.I18n.t( 'markdown' )),
|
||||
here: this.linkHtml("http://daringfireball.net/projects/markdown/syntax", Diaspora.I18n.t( 'here' ))
|
||||
|
|
@ -53,10 +55,9 @@ app.views.Help = app.views.StaticContentView.extend({
|
|||
title_pods: Diaspora.I18n.t( 'pods.title' ),
|
||||
title_posts_and_posting: Diaspora.I18n.t( 'posts_and_posting.title' ),
|
||||
title_private_posts: Diaspora.I18n.t( 'private_posts.title' ),
|
||||
title_private_profiles: Diaspora.I18n.t( 'private_profiles.title' ),
|
||||
title_public_posts: Diaspora.I18n.t( 'public_posts.title' ),
|
||||
title_public_profiles: Diaspora.I18n.t( 'public_profiles.title' ),
|
||||
title_resharing_posts: Diaspora.I18n.t( 'resharing_posts.title' ),
|
||||
title_profile: Diaspora.I18n.t("profile.title"),
|
||||
title_sharing: Diaspora.I18n.t( 'sharing.title' ),
|
||||
title_tags: Diaspora.I18n.t( 'tags.title' ),
|
||||
title_keyboard_shortcuts: Diaspora.I18n.t( 'keyboard_shortcuts.title' ),
|
||||
|
|
|
|||
|
|
@ -51,6 +51,12 @@ app.views.InfScroll = app.views.Base.extend({
|
|||
}
|
||||
},
|
||||
|
||||
postRenderTemplate: function() {
|
||||
if (this.postViews.length > 0) {
|
||||
this.$(".no-posts-info").closest(".stream-element").remove();
|
||||
}
|
||||
},
|
||||
|
||||
showNoPostsInfo: function() {
|
||||
if (this.postViews.length === 0) {
|
||||
var noPostsInfo = new app.views.NoPostsInfo();
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ app.views.NotificationDropdown = app.views.Base.extend({
|
|||
|
||||
toggleDropdown: function(evt){
|
||||
evt.stopPropagation();
|
||||
if (!$("#notifications-link .entypo-bell:visible").length) { return true; }
|
||||
evt.preventDefault();
|
||||
if(this.dropdownShowing()){ this.hideDropdown(evt); }
|
||||
else{ this.showDropdown(); }
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ app.views.PreviewPost = app.views.Post.extend({
|
|||
className: "stream-element loaded",
|
||||
|
||||
subviews: {
|
||||
".feedback": "feedbackView",
|
||||
".post-content": "postContentView",
|
||||
".oembed": "oEmbedView",
|
||||
".opengraph": "openGraphView",
|
||||
|
|
@ -13,12 +12,6 @@ app.views.PreviewPost = app.views.Post.extend({
|
|||
".status-message-location": "postLocationStreamView"
|
||||
},
|
||||
|
||||
tooltipSelector: [
|
||||
".timeago",
|
||||
".delete",
|
||||
".permalink"
|
||||
].join(", "),
|
||||
|
||||
initialize: function() {
|
||||
this.model.set("preview", true);
|
||||
this.oEmbedView = new app.views.OEmbed({model: this.model});
|
||||
|
|
@ -26,10 +19,6 @@ app.views.PreviewPost = app.views.Post.extend({
|
|||
this.pollView = new app.views.Poll({model: this.model});
|
||||
},
|
||||
|
||||
feedbackView: function() {
|
||||
return new app.views.Feedback({model: this.model});
|
||||
},
|
||||
|
||||
postContentView: function() {
|
||||
return new app.views.StatusMessage({model: this.model});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,29 +2,20 @@
|
|||
|
||||
app.views.PublisherMention = app.views.SearchBase.extend({
|
||||
triggerChar: "@",
|
||||
invisibleChar: "\u200B", // zero width space
|
||||
mentionRegex: /@([^@\s]+)$/,
|
||||
|
||||
templates: {
|
||||
mentionItemSyntax: _.template("@{<%= name %> ; <%= handle %>}"),
|
||||
mentionItemHighlight: _.template("<strong><span><%= name %></span></strong>")
|
||||
},
|
||||
mentionSyntaxTemplate: function(person) { return "@{" + person.handle + "}"; },
|
||||
|
||||
events: {
|
||||
"keydown #status_message_fake_text": "onInputBoxKeyDown",
|
||||
"input #status_message_fake_text": "onInputBoxInput",
|
||||
"click #status_message_fake_text": "onInputBoxClick",
|
||||
"blur #status_message_fake_text": "onInputBoxBlur"
|
||||
"keydown .mention-textarea": "onInputBoxKeyDown",
|
||||
"input .mention-textarea": "updateTypeaheadInput",
|
||||
"click .mention-textarea": "onInputBoxClick",
|
||||
"blur .mention-textarea": "onInputBoxBlur"
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
initialize: function(opts) {
|
||||
this.mentionedPeople = [];
|
||||
|
||||
// contains the 'fake text' displayed to the user
|
||||
// also has a data-messageText attribute with the original text
|
||||
this.inputBox = this.$("#status_message_fake_text");
|
||||
// contains the mentions displayed to the user
|
||||
this.mentionsBox = this.$(".mentions-box");
|
||||
var url = (opts && opts.url) || "/contacts";
|
||||
this.inputBox = this.$(".mention-textarea");
|
||||
this.typeaheadInput = this.$(".typeahead-mention-box");
|
||||
this.bindTypeaheadEvents();
|
||||
|
||||
|
|
@ -32,7 +23,7 @@ app.views.PublisherMention = app.views.SearchBase.extend({
|
|||
typeaheadInput: this.typeaheadInput,
|
||||
customSearch: true,
|
||||
autoselect: true,
|
||||
remoteRoute: {url: "/contacts"}
|
||||
remoteRoute: {url: url}
|
||||
});
|
||||
},
|
||||
|
||||
|
|
@ -55,8 +46,8 @@ app.views.PublisherMention = app.views.SearchBase.extend({
|
|||
cleanMentionedPeople: function() {
|
||||
var inputText = this.inputBox.val();
|
||||
this.mentionedPeople = this.mentionedPeople.filter(function(person) {
|
||||
return person.name && inputText.indexOf(person.name) > -1;
|
||||
});
|
||||
return person.handle && inputText.indexOf(this.mentionSyntaxTemplate(person)) > -1;
|
||||
}.bind(this));
|
||||
this.ignoreDiasporaIds = this.mentionedPeople.map(function(person) { return person.handle; });
|
||||
},
|
||||
|
||||
|
|
@ -70,41 +61,16 @@ app.views.PublisherMention = app.views.SearchBase.extend({
|
|||
this.addPersonToMentions(person);
|
||||
this.closeSuggestions();
|
||||
|
||||
messageText = messageText.substring(0, triggerCharPosition) +
|
||||
this.invisibleChar + person.name + messageText.substring(caretPosition);
|
||||
var mentionText = this.mentionSyntaxTemplate(person);
|
||||
|
||||
messageText = messageText.substring(0, triggerCharPosition) + mentionText + messageText.substring(caretPosition);
|
||||
|
||||
this.inputBox.val(messageText);
|
||||
this.updateMessageTexts();
|
||||
|
||||
this.inputBox.focus();
|
||||
var newCaretPosition = triggerCharPosition + person.name.length + 1;
|
||||
var newCaretPosition = triggerCharPosition + mentionText.length;
|
||||
this.inputBox[0].setSelectionRange(newCaretPosition, newCaretPosition);
|
||||
},
|
||||
|
||||
/**
|
||||
* Replaces every combination of this.invisibleChar + mention.name by the
|
||||
* correct syntax for both hidden text and visible one.
|
||||
*
|
||||
* For instance, the text "Hello \u200Buser1" will be tranformed to
|
||||
* "Hello @{user1 ; user1@pod.tld}" in the hidden element and
|
||||
* "Hello <strong><span>user1</span></strong>" in the element visible to the user.
|
||||
*/
|
||||
updateMessageTexts: function() {
|
||||
var fakeMessageText = this.inputBox.val(),
|
||||
mentionBoxText = _.escape(fakeMessageText),
|
||||
messageText = fakeMessageText;
|
||||
|
||||
this.mentionedPeople.forEach(function(person) {
|
||||
var mentionName = this.invisibleChar + person.name;
|
||||
messageText = messageText.replace(mentionName, this.templates.mentionItemSyntax(person));
|
||||
var textHighlight = this.templates.mentionItemHighlight({name: _.escape(person.name)});
|
||||
mentionBoxText = mentionBoxText.replace(mentionName, textHighlight);
|
||||
}, this);
|
||||
|
||||
this.inputBox.data("messageText", messageText);
|
||||
this.mentionsBox.find(".mentions").html(mentionBoxText);
|
||||
},
|
||||
|
||||
updateTypeaheadInput: function() {
|
||||
var messageText = this.inputBox.val();
|
||||
var caretPosition = this.inputBox[0].selectionStart;
|
||||
|
|
@ -115,6 +81,8 @@ app.views.PublisherMention = app.views.SearchBase.extend({
|
|||
return;
|
||||
}
|
||||
|
||||
this.cleanMentionedPeople();
|
||||
|
||||
// result[1] is the string between the last '@' and the current caret position
|
||||
this.typeaheadInput.typeahead("val", result[1]);
|
||||
this.typeaheadInput.typeahead("open");
|
||||
|
|
@ -128,12 +96,11 @@ app.views.PublisherMention = app.views.SearchBase.extend({
|
|||
prefillMention: function(persons) {
|
||||
persons.forEach(function(person) {
|
||||
this.addPersonToMentions(person);
|
||||
var text = this.invisibleChar + person.name;
|
||||
var text = this.mentionSyntaxTemplate(person);
|
||||
if(this.inputBox.val().length !== 0) {
|
||||
text = this.inputBox.val() + " " + text;
|
||||
}
|
||||
this.inputBox.val(text);
|
||||
this.updateMessageTexts();
|
||||
}, this);
|
||||
},
|
||||
|
||||
|
|
@ -154,15 +121,6 @@ app.views.PublisherMention = app.views.SearchBase.extend({
|
|||
this.typeaheadInput.trigger($.Event("keydown", {keyCode: e.keyCode, which: e.which}));
|
||||
},
|
||||
|
||||
/**
|
||||
* Listens for user input and opens results dropdown when input contains the trigger char
|
||||
*/
|
||||
onInputBoxInput: function() {
|
||||
this.cleanMentionedPeople();
|
||||
this.updateMessageTexts();
|
||||
this.updateTypeaheadInput();
|
||||
},
|
||||
|
||||
onInputBoxKeyDown: function(e) {
|
||||
// This also matches HOME/END on OSX which is CMD+LEFT, CMD+RIGHT
|
||||
if(e.which === Keycodes.LEFT || e.which === Keycodes.RIGHT ||
|
||||
|
|
@ -205,7 +163,7 @@ app.views.PublisherMention = app.views.SearchBase.extend({
|
|||
|
||||
reset: function() {
|
||||
this.inputBox.val("");
|
||||
this.onInputBoxInput();
|
||||
this.updateTypeaheadInput();
|
||||
},
|
||||
|
||||
closeSuggestions: function() {
|
||||
|
|
@ -217,7 +175,8 @@ app.views.PublisherMention = app.views.SearchBase.extend({
|
|||
return this.$(".tt-menu").is(":visible");
|
||||
},
|
||||
|
||||
getTextForSubmit: function() {
|
||||
return this.mentionedPeople.length ? this.inputBox.data("messageText") : this.inputBox.val();
|
||||
getMentionedPeople: function() {
|
||||
this.cleanMentionedPeople();
|
||||
return this.mentionedPeople;
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@ app.views.Publisher = Backbone.View.extend({
|
|||
el : "#publisher",
|
||||
|
||||
events : {
|
||||
"keydown #status_message_fake_text" : "keyDown",
|
||||
"keydown #status_message_text": "keyDown",
|
||||
"focus textarea" : "open",
|
||||
"submit form" : "createStatusMessage",
|
||||
"click #submit" : "createStatusMessage",
|
||||
"textchange #status_message_fake_text": "handleTextchange",
|
||||
"textchange #status_message_text": "checkSubmitAvailability",
|
||||
"click #locator" : "showLocation",
|
||||
"click #poll_creator" : "togglePollCreator",
|
||||
"click #hide_location" : "destroyLocation",
|
||||
|
|
@ -35,8 +35,7 @@ app.views.Publisher = Backbone.View.extend({
|
|||
this.disabled = false;
|
||||
|
||||
// init shortcut references to the various elements
|
||||
this.inputEl = this.$("#status_message_fake_text");
|
||||
this.hiddenInputEl = this.$("#status_message_text");
|
||||
this.inputEl = this.$("#status_message_text");
|
||||
this.wrapperEl = this.$("#publisher_textarea_wrapper");
|
||||
this.submitEl = this.$("input[type=submit], button#submit");
|
||||
this.photozoneEl = this.$("#photodropzone");
|
||||
|
|
@ -46,14 +45,6 @@ app.views.Publisher = Backbone.View.extend({
|
|||
$(window).on("beforeunload", _.bind(this._beforeUnload, this));
|
||||
$(window).on("unload", this.clear.bind(this));
|
||||
|
||||
// sync textarea content
|
||||
if( this.hiddenInputEl.val() === "" ) {
|
||||
this.hiddenInputEl.val( this.inputEl.val() );
|
||||
}
|
||||
if( this.inputEl.val() === "" ) {
|
||||
this.inputEl.val( this.hiddenInputEl.val() );
|
||||
}
|
||||
|
||||
// hide close and preview buttons and manage services link
|
||||
// in case publisher is standalone
|
||||
// (e.g. bookmarklet, mentions popup)
|
||||
|
|
@ -163,7 +154,7 @@ app.views.Publisher = Backbone.View.extend({
|
|||
this.viewPollCreator.render();
|
||||
|
||||
if (this.prefillMention) {
|
||||
this.handleTextchange();
|
||||
this.checkSubmitAvailability();
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -175,12 +166,11 @@ app.views.Publisher = Backbone.View.extend({
|
|||
// inject content into the publisher textarea
|
||||
setText: function(txt) {
|
||||
this.inputEl.val(txt);
|
||||
this.hiddenInputEl.val(txt);
|
||||
this.prefillText = txt;
|
||||
|
||||
this.inputEl.trigger("input");
|
||||
autosize.update(this.inputEl);
|
||||
this.handleTextchange();
|
||||
this.checkSubmitAvailability();
|
||||
},
|
||||
|
||||
// show the "getting started" popups around the publisher
|
||||
|
|
@ -202,9 +192,6 @@ app.views.Publisher = Backbone.View.extend({
|
|||
// empty poll answer and failing validation.
|
||||
this.viewPollCreator.removeLastAnswer();
|
||||
|
||||
//add missing mentions at end of post:
|
||||
this.handleTextchange();
|
||||
|
||||
var serializedForm = $(evt.target).closest("form").serializeObject();
|
||||
// disable input while posting, must be after the form is serialized
|
||||
this.setInputEnabled(false);
|
||||
|
|
@ -255,7 +242,7 @@ app.views.Publisher = Backbone.View.extend({
|
|||
self.setButtonsEnabled(true);
|
||||
self.setInputEnabled(true);
|
||||
self.wrapperEl.removeClass("submitting");
|
||||
self.handleTextchange();
|
||||
self.checkSubmitAvailability();
|
||||
autosize.update(self.inputEl);
|
||||
}
|
||||
});
|
||||
|
|
@ -330,13 +317,8 @@ app.views.Publisher = Backbone.View.extend({
|
|||
},
|
||||
|
||||
createPostPreview: function() {
|
||||
//add missing mentions at end of post:
|
||||
this.handleTextchange();
|
||||
|
||||
var serializedForm = $("#new_status_message").serializeObject();
|
||||
var text = this.mention.getTextForSubmit();
|
||||
var photos = this.getUploadedPhotos();
|
||||
var mentionedPeople = this.mention.mentionedPeople;
|
||||
var poll = this.getPollData(serializedForm);
|
||||
var locationCoords = serializedForm["location[coords]"];
|
||||
if(!locationCoords || locationCoords === "") {
|
||||
|
|
@ -352,12 +334,12 @@ app.views.Publisher = Backbone.View.extend({
|
|||
|
||||
var previewMessage = {
|
||||
"id": 0,
|
||||
"text": text,
|
||||
"text": serializedForm["status_message[text]"],
|
||||
"public": serializedForm["aspect_ids[]"] === "public",
|
||||
"created_at": new Date().toISOString(),
|
||||
"interacted_at": new Date().toISOString(),
|
||||
"author": app.currentUser ? app.currentUser.attributes : {},
|
||||
"mentioned_people": mentionedPeople,
|
||||
"mentioned_people": this.mention.getMentionedPeople(),
|
||||
"photos": photos,
|
||||
"title": serializedForm["status_message[text]"],
|
||||
"location": location,
|
||||
|
|
@ -370,7 +352,7 @@ app.views.Publisher = Backbone.View.extend({
|
|||
},
|
||||
|
||||
keyDown : function(evt) {
|
||||
if(evt.which === Keycodes.ENTER && evt.ctrlKey) {
|
||||
if (evt.which === Keycodes.ENTER && (evt.metaKey || evt.ctrlKey)) {
|
||||
this.$("form").submit();
|
||||
this.open();
|
||||
return false;
|
||||
|
|
@ -381,11 +363,10 @@ app.views.Publisher = Backbone.View.extend({
|
|||
// remove mentions
|
||||
this.mention.reset();
|
||||
|
||||
// clear text(s)
|
||||
// clear text
|
||||
this.inputEl.val("");
|
||||
this.hiddenInputEl.val("");
|
||||
this.inputEl.trigger("keyup")
|
||||
.trigger("keydown");
|
||||
.trigger("keydown");
|
||||
autosize.update(this.inputEl);
|
||||
|
||||
// remove photos
|
||||
|
|
@ -421,14 +402,13 @@ app.views.Publisher = Backbone.View.extend({
|
|||
|
||||
// force textchange plugin to update lastValue
|
||||
this.inputEl.data("lastValue", "");
|
||||
this.hiddenInputEl.data("lastValue", "");
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
tryClose : function(){
|
||||
// if it is not submittable, close it.
|
||||
if( !this._submittable() ){
|
||||
// if it is not submittable and not in preview mode, close it.
|
||||
if (!this._submittable() && !this.markdownEditor.isPreviewMode()) {
|
||||
this.close();
|
||||
}
|
||||
},
|
||||
|
|
@ -472,8 +452,7 @@ app.views.Publisher = Backbone.View.extend({
|
|||
setEnabled: function(bool) {
|
||||
this.setInputEnabled(bool);
|
||||
this.disabled = !bool;
|
||||
|
||||
this.handleTextchange();
|
||||
this.checkSubmitAvailability();
|
||||
},
|
||||
|
||||
setButtonsEnabled: function(bool) {
|
||||
|
|
@ -487,10 +466,8 @@ app.views.Publisher = Backbone.View.extend({
|
|||
setInputEnabled: function(bool) {
|
||||
if (bool) {
|
||||
this.inputEl.removeAttr("disabled");
|
||||
this.hiddenInputEl.removeAttr("disabled");
|
||||
} else {
|
||||
this.inputEl.prop("disabled", true);
|
||||
this.hiddenInputEl.prop("disabled", true);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -503,11 +480,6 @@ app.views.Publisher = Backbone.View.extend({
|
|||
return (!onlyWhitespaces || isPhotoAttached) && isValidPoll && !this.disabled;
|
||||
},
|
||||
|
||||
handleTextchange: function() {
|
||||
this.checkSubmitAvailability();
|
||||
this.hiddenInputEl.val(this.mention.getTextForSubmit());
|
||||
},
|
||||
|
||||
_beforeUnload: function(e) {
|
||||
if(this._submittable() && this.inputEl.val() !== this.prefillText){
|
||||
var confirmationMessage = Diaspora.I18n.t("confirm_unload");
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ app.views.SinglePostCommentStream = app.views.CommentStream.extend({
|
|||
this.CommentView = app.views.ExpandedComment;
|
||||
$(window).on('hashchange',this.highlightPermalinkComment);
|
||||
this.setupBindings();
|
||||
this.model.comments.on("reset", this.render, this);
|
||||
this.model.comments.fetch({success: function() {
|
||||
setTimeout(this.highlightPermalinkComment, 0);
|
||||
}.bind(this)});
|
||||
},
|
||||
|
||||
highlightPermalinkComment: function() {
|
||||
|
|
@ -17,14 +19,13 @@ app.views.SinglePostCommentStream = app.views.CommentStream.extend({
|
|||
$(".highlighted").removeClass("highlighted");
|
||||
element.addClass("highlighted");
|
||||
var pos = element.offset().top - headerSize;
|
||||
window.scroll(0, pos);
|
||||
$("html,body").animate({scrollTop: pos});
|
||||
}
|
||||
},
|
||||
|
||||
postRenderTemplate: function() {
|
||||
app.views.CommentStream.prototype.postRenderTemplate.apply(this);
|
||||
this.$(".new-comment-form-wrapper").removeClass("hidden");
|
||||
_.defer(this.highlightPermalinkComment);
|
||||
},
|
||||
|
||||
presenter: function(){
|
||||
|
|
|
|||
|
|
@ -4,8 +4,15 @@ app.views.SinglePostInteractionCounts = app.views.Base.extend({
|
|||
templateName: "single-post-viewer/single-post-interaction-counts",
|
||||
tooltipSelector: ".avatar.micro",
|
||||
|
||||
events: {
|
||||
"click #show-all-likes": "showAllLikes",
|
||||
"click #show-all-reshares": "showAllReshares"
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
this.model.interactions.on("change", this.render, this);
|
||||
this.model.interactions.likes.on("change", this.render, this);
|
||||
this.model.interactions.reshares.on("change", this.render, this);
|
||||
},
|
||||
|
||||
presenter: function() {
|
||||
|
|
@ -15,8 +22,28 @@ app.views.SinglePostInteractionCounts = app.views.Base.extend({
|
|||
reshares: interactions.reshares.toJSON(),
|
||||
commentsCount: interactions.commentsCount(),
|
||||
likesCount: interactions.likesCount(),
|
||||
resharesCount: interactions.resharesCount()
|
||||
resharesCount: interactions.resharesCount(),
|
||||
showMoreLikes: interactions.likes.length < interactions.likesCount(),
|
||||
showMoreReshares: interactions.reshares.length < interactions.resharesCount()
|
||||
};
|
||||
},
|
||||
|
||||
_showAll: function(interactionType, models) {
|
||||
this.$("#show-all-" + interactionType).addClass("hidden");
|
||||
this.$("#" + interactionType + " .loader").removeClass("hidden");
|
||||
models.fetch({success: function() {
|
||||
models.trigger("change");
|
||||
}});
|
||||
},
|
||||
|
||||
showAllLikes: function(evt) {
|
||||
evt.preventDefault();
|
||||
this._showAll("likes", this.model.interactions.likes);
|
||||
},
|
||||
|
||||
showAllReshares: function(evt) {
|
||||
evt.preventDefault();
|
||||
this._showAll("reshares", this.model.interactions.reshares);
|
||||
}
|
||||
});
|
||||
// @license-end
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ Diaspora.MarkdownEditor.prototype = {
|
|||
this.options = {
|
||||
resize: "none",
|
||||
onHidePreview: $.noop,
|
||||
onPostPreview: $.noop
|
||||
onPostPreview: $.noop,
|
||||
onChange: function(e) { autosize.update(e.$textarea); }
|
||||
};
|
||||
|
||||
$.extend(this.options, opts);
|
||||
|
|
@ -130,6 +131,14 @@ Diaspora.MarkdownEditor.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
isPreviewMode: function() {
|
||||
return this.instance !== undefined && this.instance.$editor.find(".md-preview").length > 0;
|
||||
},
|
||||
|
||||
userInputEmpty: function() {
|
||||
return this.instance === undefined || this.instance.getContent().length === 0;
|
||||
},
|
||||
|
||||
localize: function() {
|
||||
var locale = Diaspora.I18n.language;
|
||||
|
||||
|
|
@ -160,3 +169,7 @@ Diaspora.MarkdownEditor.prototype = {
|
|||
return locale;
|
||||
}
|
||||
};
|
||||
|
||||
Diaspora.MarkdownEditor.simplePreview = function($mdInstance) {
|
||||
return "<div class='preview-content'>" + app.helpers.textFormatter($mdInstance.getContent()) + "</div>";
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//= require jquery2
|
||||
//= require jquery3
|
||||
//= require handlebars.runtime
|
||||
//= require templates
|
||||
//= require main
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
//= require emojione
|
||||
//= require favico.js
|
||||
//= require favico.js/favico
|
||||
|
||||
//= require jquery.ui/ui/resizable
|
||||
//= require jquery.ui/ui/draggable
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@
|
|||
//= require charcount
|
||||
//= require jquery-placeholder
|
||||
//= require jquery.timeago
|
||||
//= require jquery-ui/core
|
||||
//= require jquery-ui/widget
|
||||
//= require jquery-ui/mouse
|
||||
//= require jquery-ui/sortable
|
||||
//= require jquery.ui/ui/core
|
||||
//= require jquery.ui/ui/widget
|
||||
//= require jquery.ui/ui/mouse
|
||||
//= require jquery.ui/ui/sortable
|
||||
//= require keycodes
|
||||
//= require jquery.autoSuggest.custom
|
||||
//= require fine-uploader/fine-uploader.core
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
|
||||
|
||||
/* Copyright (c) 2010-2011, Diaspora Inc. This file is
|
||||
* licensed under the Affero General Public License version 3 or later. See
|
||||
* the COPYRIGHT file.
|
||||
*/
|
||||
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
|
||||
|
||||
//= require jquery-textchange
|
||||
//= require charcount
|
||||
//= require js-routes
|
||||
|
|
@ -18,6 +18,8 @@
|
|||
//= require helpers/i18n
|
||||
//= require helpers/profile_photo_uploader
|
||||
//= require helpers/tags_autocomplete
|
||||
//= require bootstrap-markdown/bootstrap-markdown
|
||||
//= require helpers/markdown_editor
|
||||
//= require widgets/timeago
|
||||
//= require mobile/mobile_application
|
||||
//= require mobile/mobile_file_uploader
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@
|
|||
initialize: function() {
|
||||
var self = this;
|
||||
|
||||
new Diaspora.MarkdownEditor(".comment_box");
|
||||
|
||||
this.stream().on("tap click", "a.show-comments", function(evt){
|
||||
evt.preventDefault();
|
||||
self.toggleComments($(this));
|
||||
|
|
@ -35,7 +37,7 @@
|
|||
self.scrollToOffset(commentContainer);
|
||||
});
|
||||
|
||||
this.stream().on("submit", ".new_comment", this.submitComment);
|
||||
this.stream().on("submit", ".new-comment", this.submitComment);
|
||||
},
|
||||
|
||||
submitComment: function(evt){
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
(function() {
|
||||
Diaspora.Mobile.Conversations = {
|
||||
initialize: function() {
|
||||
new Diaspora.MarkdownEditor(".conversation-message-text");
|
||||
if (Diaspora.Page !== "ConversationsNew") { return; }
|
||||
$(document).on("ajax:success", "form#new-conversation", this.conversationCreateSuccess);
|
||||
$(document).on("ajax:error", "form#new-conversation", this.conversationCreateError);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ function createUploader(){
|
|||
$("#fileInfo-publisher").text(fileName + " " + progress + "%");
|
||||
},
|
||||
onSubmit: function() {
|
||||
$("#file-upload-publisher").addClass("loading");
|
||||
$("#publisher_textarea_wrapper").addClass("with_attachments");
|
||||
$("#photodropzone").append(
|
||||
"<li class='publisher_photo loading' style='position:relative;'>" +
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@
|
|||
|
||||
onLike: function(evt){
|
||||
evt.preventDefault();
|
||||
var link = $(evt.target),
|
||||
var link = $(evt.target).closest(".like-action"),
|
||||
likeCounter = $(evt.target).closest(".stream-element").find(".like-count");
|
||||
|
||||
if(!link.hasClass("loading") && link.hasClass("inactive")) {
|
||||
|
|
@ -89,7 +89,7 @@
|
|||
onReshare: function(evt) {
|
||||
evt.preventDefault();
|
||||
|
||||
var link = $(this),
|
||||
var link = $(this).closest(".reshare-action"),
|
||||
href = link.attr("href"),
|
||||
confirmText = link.attr("title");
|
||||
|
||||
|
|
@ -103,6 +103,10 @@
|
|||
},
|
||||
success: function() {
|
||||
Diaspora.Mobile.PostActions.toggleActive(link);
|
||||
var reshareCounter = $(evt.target).closest(".stream-element").find(".reshare-count");
|
||||
if (reshareCounter) {
|
||||
reshareCounter.text(parseInt(reshareCounter.text(), 10) + 1);
|
||||
}
|
||||
},
|
||||
error: function(response) {
|
||||
Diaspora.Mobile.Alert.handleAjaxError(response);
|
||||
|
|
|
|||
|
|
@ -46,4 +46,6 @@ $(document).ready(function(){
|
|||
evt.preventDefault();
|
||||
$("#new_status_message").submit();
|
||||
});
|
||||
|
||||
new Diaspora.MarkdownEditor("#status_message_text");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
@import 'media-box';
|
||||
@import 'entypo';
|
||||
@import 'icons';
|
||||
@import 'mentions';
|
||||
@import 'animations';
|
||||
@import 'flash_messages';
|
||||
@import 'sprites';
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ pre { word-wrap: break-word; }
|
|||
line-height: 50px;
|
||||
opacity: 0;
|
||||
position: fixed;
|
||||
right: 54px;
|
||||
right: 20px;
|
||||
transition: opacity ease 400ms;
|
||||
width: 50px;
|
||||
z-index: 49;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Calling this file bootstrap would cause an infinite recursion during asset compilation.
|
||||
@import "bootstrap-sprockets";
|
||||
@import "bootstrap-variables"; //our overwrites of bootstrap variables
|
||||
@import "bootstrap";
|
||||
@import "_bootstrap";
|
||||
|
||||
// Plugins
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,20 @@
|
|||
// Only overriding existing selectors here, so disable some lint rules
|
||||
// scss-lint:disable IdSelector, SelectorFormat, NestingDepth, SelectorDepth, QualifyingElement
|
||||
body {
|
||||
.navbar.navbar-fixed-top #user_menu .dropdown-menu > li > a {
|
||||
color: $text-color;
|
||||
&:hover { color: $white; }
|
||||
}
|
||||
|
||||
.publisher {
|
||||
.mentions-input-box { background-color: $gray; }
|
||||
form {
|
||||
#publisher_textarea_wrapper { background-color: $gray; }
|
||||
.btn.btn-link.question_mark:hover .entypo-cog { color: $gray-light; }
|
||||
}
|
||||
|
||||
.write-preview-tabs > li.active * { color: $text-color; }
|
||||
.md-preview { background-color: $gray; }
|
||||
.md-cancel:hover .entypo-cross { color: $gray-light; }
|
||||
.publisher-buttonbar .btn.btn-link:hover i { color: $gray-light; }
|
||||
}
|
||||
|
||||
.write-preview-tabs > li.active * { color: $text-color; }
|
||||
.md-cancel:hover .entypo-cross { color: $gray-light; }
|
||||
|
||||
.md-input,
|
||||
.md-preview { background-color: $gray; }
|
||||
|
||||
.aspect_dropdown li a .text { color: $dropdown-link-color; }
|
||||
|
||||
.info .tag { background-color: $gray-light; }
|
||||
|
|
@ -96,6 +92,7 @@ body {
|
|||
|
||||
#welcome-to-diaspora { background: $orange; }
|
||||
|
||||
.md-editor,
|
||||
.block-form fieldset .form-control:focus { border-color: $input-border; }
|
||||
|
||||
&.page-registrations.action-new,
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ $dropdown-link-hover-color: $dropdown-link-color;
|
|||
|
||||
//== Navbar
|
||||
$navbar-inverse-bg: $gray-darker;
|
||||
$navbar-inverse-link-hover-color: $text-color;
|
||||
$navbar-inverse-link-color: $gray-lighter;
|
||||
$navbar-inverse-link-hover-color: $white;
|
||||
$navbar-inverse-brand-hover-color: $navbar-inverse-link-hover-color;
|
||||
|
||||
//== Tabs
|
||||
|
|
|
|||
|
|
@ -46,13 +46,12 @@
|
|||
|
||||
.comment.new-comment-form-wrapper { padding-bottom: 0; }
|
||||
|
||||
.submit_button {
|
||||
.submit-button {
|
||||
margin-top: 10px;
|
||||
input {
|
||||
float: right;
|
||||
}
|
||||
padding-left: 12px;
|
||||
display: none;
|
||||
}
|
||||
.comment_box {
|
||||
height: 35px;
|
||||
|
|
@ -60,8 +59,27 @@
|
|||
}
|
||||
textarea.comment_box:focus, textarea.comment_box:valid, textarea.comment_box:active {
|
||||
border-color: $border-dark-grey;
|
||||
& + .submit_button { display: block; }
|
||||
min-height: 35px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.twitter-typeahead {
|
||||
// typeahead sets this to `display: inline-block` which adds additional space between
|
||||
// the comment textarea and the submit button.
|
||||
// scss-lint:disable ImportantRule
|
||||
display: block !important;
|
||||
// scss-lint:enable ImportantRule
|
||||
}
|
||||
}
|
||||
|
||||
.new-comment {
|
||||
&:not(.open) .submit-button,
|
||||
&:not(.open) .md-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// The rule for .md-preview is required until we switch to the newer release of bootstrap-markdown with
|
||||
// the following commit in:
|
||||
// https://github.com/toopay/bootstrap-markdown/commit/14a21c3837140144b27efc19c795d1a37fad70fb
|
||||
.md-preview,
|
||||
&.open .md-editor textarea { min-height: 70px; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -238,3 +238,9 @@
|
|||
}
|
||||
|
||||
.new-conversation.form-horizontal .form-group:last-of-type { margin-bottom: 0; }
|
||||
|
||||
// This rule is required until we switch to the newer release of bootstrap-markdown with
|
||||
// the following commit in: https://github.com/toopay/bootstrap-markdown/commit/14a21c3837140144b27efc19c795d1a37fad70fb
|
||||
.conversations-form-container .md-preview {
|
||||
min-height: 105px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,68 +1,68 @@
|
|||
.not-connected-menu {
|
||||
.navbar-left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.navbar-right,
|
||||
.navbar-right li {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar.navbar-fixed-top {
|
||||
border-bottom: none;
|
||||
box-shadow: 1px 0 2px $black;
|
||||
a:focus {outline: 0 none; }
|
||||
a:focus { outline: 0 none; }
|
||||
|
||||
.in {
|
||||
overflow-y: visible; // Avoid search result dropdown to be hidden
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-weight: bold;
|
||||
font-size: $font-size-h3;
|
||||
margin-left: -15px;
|
||||
}
|
||||
|
||||
@media (max-width: $grid-float-breakpoint-max) {
|
||||
.navbar-header > .nav li { display: inline-block !important; }
|
||||
.nav-badge {
|
||||
color: $navbar-inverse-link-color;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
&:hover { color: $navbar-inverse-link-hover-color; }
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: transparent;
|
||||
}
|
||||
.header-title {
|
||||
margin: (($navbar-height - 32px - 2 * $navbar-padding-vertical) / 2) 0;
|
||||
|
||||
img {
|
||||
height: 32px;
|
||||
opacity: .7;
|
||||
}
|
||||
#navbar-collapse {
|
||||
.form-group, .twitter-typeahead {
|
||||
display: block !important;
|
||||
margin-bottom: 0;
|
||||
&, & input { width: 100% }
|
||||
}
|
||||
|
||||
img:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@media (min-width: $grid-float-breakpoint) {
|
||||
input[type="search"] {
|
||||
@include transition(width);
|
||||
margin-top: 2px;
|
||||
width: 200px;
|
||||
&:not(.active) {
|
||||
background-color: $navbar-inverse-bg;
|
||||
border-color: $gray-light;
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
#user_menu {
|
||||
&.open .dropdown-toggle { background-color: darken($navbar-inverse-bg, 7%); }
|
||||
.dropdown-toggle {
|
||||
margin: 0 1px;
|
||||
min-width: 160px;
|
||||
}
|
||||
.dropdown-menu {
|
||||
background-color: darken($navbar-inverse-bg, 7%);
|
||||
border-top: none;
|
||||
width: 100%;
|
||||
& > li > a {
|
||||
color: $gray-light;
|
||||
padding-left: 55px;
|
||||
&:hover {
|
||||
background-color: $brand-primary;
|
||||
color: $gray-lighter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-header > ul,
|
||||
.navbar-header > ul li {
|
||||
float: left;
|
||||
}
|
||||
|
||||
[class^="entypo-"],
|
||||
[class*="entypo-"] {
|
||||
color: inherit;
|
||||
font-size: $font-size-h3;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.nav-badge {
|
||||
padding: $navbar-padding-vertical 12px;
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-nav:not(.nav-badges) > li > a { font-weight: bold; }
|
||||
.nav-badges {
|
||||
margin: 0;
|
||||
|
||||
li { height: $navbar-height; }
|
||||
.dropdown-open {
|
||||
background-color: $dropdown-bg;
|
||||
|
|
@ -118,31 +118,141 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
[class^="entypo-"], [class*="entypo-"] {
|
||||
color: inherit;
|
||||
font-size: $font-size-h3;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.nav-badge {
|
||||
margin-bottom: -2px;
|
||||
.badge {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
}
|
||||
|
||||
.user-menu-dropdown {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#user_menu {
|
||||
.user-avatar {
|
||||
height: $navbar-height;
|
||||
margin-bottom: -$navbar-padding-vertical;
|
||||
margin-right: 10px;
|
||||
margin-top: -$navbar-padding-vertical;
|
||||
padding: ($navbar-height - 30px) / 2 0;
|
||||
|
||||
.avatar {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
}
|
||||
.user-avatar {
|
||||
height: $navbar-height;
|
||||
padding: ($navbar-height - 30px)/2 0;
|
||||
margin-bottom: -$navbar-padding-vertical;
|
||||
margin-top: -$navbar-padding-vertical;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.navbar-form .form-control { display: inline-block; }
|
||||
|
||||
@media (max-width: $grid-float-breakpoint-max) {
|
||||
|
||||
.navbar-nav.hidden-xs {
|
||||
margin: 0;
|
||||
|
||||
a {
|
||||
padding-bottom: $navbar-padding-vertical;
|
||||
padding-top: $navbar-padding-vertical;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-badge {
|
||||
color: $navbar-inverse-link-color;
|
||||
&:hover { color: $navbar-inverse-link-hover-color; }
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.form-group,
|
||||
.twitter-typeahead {
|
||||
margin-bottom: 0;
|
||||
|
||||
&,
|
||||
input { width: 100%; }
|
||||
}
|
||||
|
||||
.nav-badges .dropdown-menu {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.navbar-collapse {
|
||||
padding-top: $navbar-padding-vertical / 2;
|
||||
|
||||
.navbar-nav {
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.user-menu-dropdown {
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
display: block;
|
||||
padding: 0;
|
||||
position: static;
|
||||
width: 100%;
|
||||
|
||||
a {
|
||||
color: $navbar-inverse-link-color;
|
||||
font-weight: bold;
|
||||
padding: $nav-link-padding;
|
||||
|
||||
&:hover {
|
||||
background-color: $navbar-inverse-link-hover-bg;
|
||||
color: $navbar-inverse-link-hover-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: $grid-float-breakpoint) {
|
||||
|
||||
.navbar-form { // set correct margin for small inputs
|
||||
margin-bottom: ($navbar-height - $input-height-small) / 2;
|
||||
margin-top: ($navbar-height - $input-height-small) / 2;
|
||||
}
|
||||
|
||||
[type="search"] {
|
||||
@include transition(width);
|
||||
width: 200px;
|
||||
|
||||
&:not(.active) {
|
||||
background-color: $navbar-inverse-bg;
|
||||
border-color: $gray-light;
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
.user-menu {
|
||||
&.open .dropdown-toggle { background-color: darken($navbar-inverse-bg, 7%); }
|
||||
.dropdown-toggle {
|
||||
margin: 0 1px;
|
||||
min-width: 160px;
|
||||
}
|
||||
}
|
||||
|
||||
.user-menu-dropdown {
|
||||
background-color: darken($navbar-inverse-bg, 7%);
|
||||
border-top: 0;
|
||||
width: 100%;
|
||||
|
||||
a {
|
||||
color: $navbar-inverse-link-color;
|
||||
padding-left: 55px;
|
||||
|
||||
&:hover {
|
||||
background-color: $list-group-hover-bg;
|
||||
color: $list-group-link-hover-color;
|
||||
}
|
||||
}
|
||||
|
||||
li:last-child a {
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $screen-xs-max) {
|
||||
.nav-badges .dropdown-menu {
|
||||
position: fixed;
|
||||
top: $navbar-height;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,18 @@
|
|||
.md-editor {
|
||||
border: 1px solid $border-grey;
|
||||
border-radius: $border-radius-small;
|
||||
overflow: hidden;
|
||||
|
||||
&.active { border: 1px solid $border-dark-grey; }
|
||||
|
||||
textarea,
|
||||
textarea:focus {
|
||||
border: 0;
|
||||
box-shadow: none;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.md-footer,
|
||||
.md-header {
|
||||
background: $white;
|
||||
|
|
@ -27,6 +42,7 @@
|
|||
|
||||
.btn-group {
|
||||
margin-bottom: 8px;
|
||||
&:first-child { margin-left: 0; }
|
||||
|
||||
[class^="entypo-"],
|
||||
[class*="entypo-"] {
|
||||
|
|
@ -77,13 +93,11 @@
|
|||
|
||||
|
||||
.md-preview {
|
||||
background: $white;
|
||||
color: $text-color;
|
||||
// !important is needed to override the CSS rules dynamically added to the element
|
||||
// scss-lint:disable ImportantRule
|
||||
height: auto !important;
|
||||
// scss-lint:enable ImportantRule
|
||||
min-height: 90px;
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
// !important is needed to override the CSS rules dynamically added to the element
|
||||
|
|
@ -91,6 +105,8 @@
|
|||
width: 100% !important;
|
||||
// scss-lint:enable ImportantRule
|
||||
z-index: 10;
|
||||
|
||||
.preview-content { padding: 10px; }
|
||||
}
|
||||
|
||||
.md-controls {
|
||||
|
|
|
|||
|
|
@ -1,91 +0,0 @@
|
|||
.mentions-input-box {
|
||||
border-radius: 3px;
|
||||
|
||||
background: #fff;
|
||||
position: relative;
|
||||
|
||||
textarea {
|
||||
display: block;
|
||||
background: transparent;
|
||||
border: 1px solid #dcdcdc;
|
||||
border-radius: 3px;
|
||||
outline: 0;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
resize: none;
|
||||
width: 100%;
|
||||
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.form-control[disabled] { background-color: transparent; }
|
||||
|
||||
.mentions-autocomplete-list {
|
||||
background: white;
|
||||
display: none;
|
||||
left: 0;
|
||||
margin-left: -1px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
z-index: 10000;
|
||||
|
||||
ul {
|
||||
border: 1px solid $border-dark-grey;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
border-radius: 0px 0px 5px 5px;
|
||||
|
||||
li {
|
||||
color: #444;
|
||||
background: white;
|
||||
border-bottom: 1px solid #ccc;
|
||||
cursor: pointer;
|
||||
font-size: 15px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
padding: 5px;
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover, &.active { background: $background-grey; }
|
||||
&:last-child { border-radius: 0px 0px 5px 5px; }
|
||||
|
||||
img, div.icon {
|
||||
float: left;
|
||||
height: 25px;
|
||||
margin-right: 5px;
|
||||
width: 25px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mentions-box {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
padding: $padding-base-vertical $padding-base-horizontal;
|
||||
}
|
||||
|
||||
.mentions {
|
||||
color: transparent;
|
||||
font-size: $font-size-base;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
|
||||
> strong {
|
||||
background: $background-blue;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -43,16 +43,15 @@
|
|||
display: flex;
|
||||
|
||||
.count {
|
||||
color: $text-color;
|
||||
font-family: $font-family-base;
|
||||
font-size: $font-size-base;
|
||||
line-height: 22px;
|
||||
margin-left: 5px;
|
||||
vertical-align: top;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.icon-count-group {
|
||||
display: flex;
|
||||
margin: 0 7px;
|
||||
}
|
||||
|
||||
[class^="entypo"] {
|
||||
color: $text-grey;
|
||||
font-size: 24px;
|
||||
|
|
@ -73,6 +72,9 @@
|
|||
}
|
||||
|
||||
.post-action {
|
||||
display: flex;
|
||||
margin: 0 7px;
|
||||
|
||||
.disabled { color: $medium-gray; }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,10 +33,15 @@ $mobile-navbar-height: 46px;
|
|||
li { float: left; }
|
||||
}
|
||||
|
||||
#header-title {
|
||||
.header-title {
|
||||
padding: 7px 15px;
|
||||
margin: 0 0 0 -15px;
|
||||
height: $mobile-navbar-height;
|
||||
|
||||
img {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
#nav-badges {
|
||||
|
|
@ -87,12 +92,6 @@ $mobile-navbar-height: 46px;
|
|||
background-color: $red;
|
||||
}
|
||||
}
|
||||
#header-title{
|
||||
img {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#drawer {
|
||||
|
|
|
|||
6
app/assets/stylesheets/mobile/markdown_editor.scss
Normal file
6
app/assets/stylesheets/mobile/markdown_editor.scss
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
.md-editor {
|
||||
border: 1px solid $light-grey;
|
||||
border-radius: $btn-border-radius-base;
|
||||
|
||||
&.active { border-color: $text-grey; }
|
||||
}
|
||||
|
|
@ -16,6 +16,8 @@
|
|||
@import "mobile/stream_element";
|
||||
@import "mobile/comments";
|
||||
@import 'mobile/openid_connect_error_page';
|
||||
@import 'markdown-editor';
|
||||
@import 'mobile/markdown_editor';
|
||||
|
||||
@import 'typography';
|
||||
|
||||
|
|
@ -42,8 +44,6 @@ h3 { margin-top: 0; }
|
|||
.clear { clear: both; }
|
||||
#main { padding: 56px 10px 0 10px; }
|
||||
|
||||
textarea { resize: vertical; }
|
||||
|
||||
.avatar {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
|
@ -55,7 +55,6 @@ textarea { resize: vertical; }
|
|||
overflow: auto;
|
||||
position: relative;
|
||||
text-align: left;
|
||||
min-height: 34px;
|
||||
padding: 10px 0 0 0;
|
||||
list-style: none;
|
||||
|
||||
|
|
@ -404,11 +403,6 @@ footer {
|
|||
.counter {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
textarea {
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
select {
|
||||
|
|
@ -539,13 +533,6 @@ form#new_conversation.new_conversation {
|
|||
}
|
||||
}
|
||||
|
||||
textarea#conversation_text {
|
||||
font-size: larger;
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.registrations_error,
|
||||
.registrations_notice {
|
||||
color: #DF0101;
|
||||
|
|
@ -714,33 +701,6 @@ select#aspect_ids_ {
|
|||
position: relative;
|
||||
padding-right: 10px;
|
||||
|
||||
#hide_publisher {
|
||||
opacity: 0.3;
|
||||
z-index: 5;
|
||||
padding: 3px;
|
||||
position: absolute;
|
||||
right: 6px;
|
||||
top: 0;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
border: 1px solid $border-dark-grey;
|
||||
}
|
||||
|
||||
textarea {
|
||||
z-index: 2;
|
||||
border: none;
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
&.with_attachments {
|
||||
padding-bottom: 55px;
|
||||
border: 1px solid $border-medium-grey;
|
||||
|
|
|
|||
|
|
@ -14,21 +14,11 @@
|
|||
display: none !important;
|
||||
}
|
||||
|
||||
.mentions-box {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
#publisher_textarea_wrapper { border: 1px solid $border-grey !important; }
|
||||
}
|
||||
|
||||
.container-fluid{ padding: 0; }
|
||||
|
||||
.twitter-typeahead {
|
||||
width: calc(100% + 2px);
|
||||
|
||||
.tt-menu { width: 100%; }
|
||||
}
|
||||
|
||||
form {
|
||||
margin: 0;
|
||||
#fileInfo { display: none !important; }
|
||||
|
|
@ -86,11 +76,10 @@
|
|||
}
|
||||
|
||||
textarea {
|
||||
background: transparent;
|
||||
border: 0 solid $light-grey;
|
||||
margin: 0;
|
||||
box-shadow: none;
|
||||
resize: none;
|
||||
height: 50px;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
&.active textarea {
|
||||
|
|
@ -202,9 +191,27 @@
|
|||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.md-editor,
|
||||
.md-editor.active {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.md-preview {
|
||||
// This rule is required until we switch to the newer release of bootstrap-markdown with
|
||||
// the following commit in:
|
||||
// https://github.com/toopay/bootstrap-markdown/commit/14a21c3837140144b27efc19c795d1a37fad70fb
|
||||
min-height: 90px;
|
||||
|
||||
.stream-element .post-content .markdown-content {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.publisher-textarea-wrapper {
|
||||
position: relative;
|
||||
|
||||
&:not(.with-location) .location-container,
|
||||
&.markdown-preview .location-container,
|
||||
&:not(.with-poll) .poll-creator-container,
|
||||
|
|
@ -248,20 +255,12 @@
|
|||
.locator { display: none; }
|
||||
}
|
||||
|
||||
&.submitting .mentions-box { display: none; }
|
||||
|
||||
.twitter-typeahead {
|
||||
left: -1px;
|
||||
// Override inline rule of Typeahead
|
||||
// scss-lint:disable ImportantRule
|
||||
position: absolute !important;
|
||||
// scss-lint:enable ImportantRule
|
||||
}
|
||||
|
||||
.mentions-box {
|
||||
// Leave space for markdown editor header
|
||||
margin-top: 42px;
|
||||
}
|
||||
}
|
||||
|
||||
.publisher-buttonbar {
|
||||
|
|
|
|||
|
|
@ -152,5 +152,16 @@
|
|||
|
||||
.interaction-avatars {
|
||||
overflow: hidden;
|
||||
|
||||
.author-name:focus,
|
||||
.author-name:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.loader {
|
||||
height: $line-height-computed;
|
||||
vertical-align: text-bottom;
|
||||
width: $line-height-computed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,3 +43,21 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.typeahead-mention-box-wrap .twitter-typeahead {
|
||||
left: -1px;
|
||||
width: calc(100% + 2px);
|
||||
|
||||
.tt-menu {
|
||||
// Override inline rule of Typeahead
|
||||
// If this is not overridden (`position: absolute` by default in Typeahead) then
|
||||
// the box is cut when opened because of the `overflow: hidden` from parent classes of comment form styles. By
|
||||
// having `position: relative` here we make it visible by inserting it in the flow.
|
||||
// This has a side effect of "Comment" button move down when box is open, but it feels like the least evil.
|
||||
// scss-lint:disable ImportantRule
|
||||
position: relative !important;
|
||||
// scss-lint:enable ImportantRule
|
||||
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,9 +25,16 @@
|
|||
{{/with}}
|
||||
|
||||
<div class="bd">
|
||||
<form accept-charset="UTF-8" action="/posts/{{id}}/comments" class="new_comment" id="new_comment_on_{{id}}" method="post">
|
||||
<textarea class="comment_box form-control" id="comment_text_on_{{id}}" name="text" rows="1" required placeholder="{{t "stream.comment"}}" />
|
||||
<div class="submit_button">
|
||||
<form accept-charset="UTF-8" action="/posts/{{id}}/comments"
|
||||
class="new-comment" id="new-comment-on-{{id}}" method="post">
|
||||
|
||||
<textarea class="comment_box form-control mention-textarea"
|
||||
id="comment_text_on_{{id}}" name="text" rows="1" required placeholder="{{t "stream.comment"}}" />
|
||||
<div class="typeahead-mention-box-wrap">
|
||||
<input class="typeahead-mention-box hidden" type="text">
|
||||
</div>
|
||||
|
||||
<div class="submit-button">
|
||||
<input class="btn btn-primary" id="comment_submit_{{id}}" name="commit" type="submit" value="{{t "stream.comment"}}" />
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
<li>{{{ get_support_a_irc }}}</li>
|
||||
<li>{{{ get_support_a_faq }}}</li>
|
||||
<li>{{{ get_support_a_hashtag }}}</li>
|
||||
<li>{{{ get_support_a_discourse }}}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
<a class='toggle' href='#'>
|
||||
<h4>{{ post_report_q }}</h4>
|
||||
</a>
|
||||
<div class='answer hideable'>{{ post_report_a }}</div>
|
||||
<div class='answer hideable'>{{{ post_report_a }}}</div>
|
||||
</div>
|
||||
<div class='question opened collapsible'>
|
||||
<a class='toggle' href='#'>
|
||||
|
|
@ -59,9 +59,7 @@
|
|||
<h4>{{ insert_images_comments_q }}</h4>
|
||||
</a>
|
||||
<div class='answer hideable'>
|
||||
{{ insert_images_comments_a1 }}
|
||||
<pre></pre>
|
||||
{{ insert_images_comments_a2 }}
|
||||
{{ insert_images_comments_a }}
|
||||
</div>
|
||||
</div>
|
||||
<div class='question opened collapsible'>
|
||||
|
|
|
|||
|
|
@ -13,29 +13,17 @@
|
|||
–
|
||||
</span>
|
||||
|
||||
|
||||
{{#if preview}}
|
||||
<span>{{t "stream.like"}}</span>
|
||||
{{else}}
|
||||
<a href="#" class="like" rel='nofollow'>
|
||||
{{~#if userLike~}}
|
||||
{{~t "stream.unlike"~}}
|
||||
{{~else~}}
|
||||
{{~t "stream.like"~}}
|
||||
{{~/if~}}
|
||||
</a>
|
||||
{{/if}}
|
||||
<a href="#" class="like" rel='nofollow'>
|
||||
{{~#if userLike~}}
|
||||
{{~t "stream.unlike"~}}
|
||||
{{~else~}}
|
||||
{{~t "stream.like"~}}
|
||||
{{~/if~}}
|
||||
</a>
|
||||
·
|
||||
{{#if preview}}
|
||||
<span>{{t "stream.reshare"}}</span>
|
||||
·
|
||||
{{else if userCanReshare}}
|
||||
{{#if userCanReshare}}
|
||||
<a href="#" class="reshare" rel='nofollow'>{{t "stream.reshare"}}</a>
|
||||
·
|
||||
{{/if}}
|
||||
|
||||
{{#if preview}}
|
||||
<span>{{t "stream.comment"}}</span>
|
||||
{{else}}
|
||||
<a href="#" class="focus_comment_textarea" rel="nofollow">{{t "stream.comment"}}</a>
|
||||
{{/if}}
|
||||
<a href="#" class="focus_comment_textarea" rel="nofollow">{{t "stream.comment"}}</a>
|
||||
|
|
|
|||
|
|
@ -10,46 +10,24 @@
|
|||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a href="/stream" class="navbar-brand" data-stream-title="{{t "my_stream"}}">
|
||||
{{ podname }}
|
||||
<span class="hidden-xs">{{ podname }}</span>
|
||||
<div class="visible-xs-block header-title">
|
||||
<img src="{{imageUrl 'branding/logos/asterisk_white_mobile.png'}}" alt="{{ podname }}" />
|
||||
</div>
|
||||
</a>
|
||||
<ul class="nav nav-badges visible-sm">
|
||||
<li>
|
||||
<a href="/notifications" title="{{t "header.notifications"}}" class="notifications-link nav-badge">
|
||||
<i class="entypo-bell"></i>
|
||||
<span class="badge badge-important {{#unless current_user.notifications_count}} hidden {{/unless}}">
|
||||
{{current_user.notifications_count}}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/conversations" title="{{t "header.conversations"}}" class="conversations-link nav-badge">
|
||||
<i class="entypo-mail"></i>
|
||||
<span class="badge badge-important {{#unless current_user.unread_messages_count}} hidden {{/unless}}">
|
||||
{{current_user.unread_messages_count}}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbar-collapse">
|
||||
<ul class="nav navbar-nav navbar-left">
|
||||
<ul class="nav navbar-nav hidden-xs">
|
||||
<li><a href="/stream">{{t "my_stream"}}</a></li>
|
||||
<li><a href="/activity">{{t "my_activity"}}</a></li>
|
||||
<li class="visible-xs"><a href="/notifications">{{t "header.notifications"}}</a></li>
|
||||
<li class="visible-xs"><a href="/conversations">{{t "header.conversations"}}</a></li>
|
||||
<li class="visible-sm visible-xs"><a href="/mobile/toggle">{{t "header.toggle_mobile"}}</a></li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav navbar-nav navbar-left nav-badges hidden-sm hidden-xs">
|
||||
<ul class="nav navbar-nav nav-badges">
|
||||
<li class="dropdown" id="notification-dropdown">
|
||||
<a id="notifications-link" href="/notifications" title="{{t "header.notifications"}}" class="notifications-link nav-badge hidden-sm hidden-xs" role="button" data-toggle="dropdown" aria-expanded="false" data-target=" ">
|
||||
<a id="notifications-link" href="/notifications" title="{{t "header.notifications"}}" class="notifications-link nav-badge"
|
||||
role="button" data-toggle="dropdown" aria-expanded="false" data-target=" ">
|
||||
<i class="entypo-bell"></i>
|
||||
<span class="badge badge-important {{#unless current_user.notifications_count}} hidden {{/unless}}">
|
||||
{{current_user.notifications_count}}
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<div class="header">
|
||||
<div class="pull-right">
|
||||
|
|
@ -71,11 +49,9 @@
|
|||
</a>
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a id="conversations-link" href="/conversations" title="{{t "header.conversations"}}" class="conversations-link nav-badge hidden-sm hidden-xs">
|
||||
<a id="conversations-link" href="/conversations" title="{{t "header.conversations"}}" class="conversations-link nav-badge">
|
||||
<i class="entypo-mail"></i>
|
||||
<span class="badge badge-important {{#unless current_user.unread_messages_count}} hidden {{/unless}}">
|
||||
{{current_user.unread_messages_count}}
|
||||
|
|
@ -83,10 +59,17 @@
|
|||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse" id="navbar-collapse">
|
||||
<ul class="nav navbar-nav navbar-left visible-sm-block visible-xs-block">
|
||||
<li class="visible-xs-block"><a href="/stream">{{t "my_stream"}}</a></li>
|
||||
<li class="visible-xs-block"><a href="/activity">{{t "my_activity"}}</a></li>
|
||||
<li><a href="/mobile/toggle">{{t "header.toggle_mobile"}}</a></li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li class="dropdown" id="user_menu">
|
||||
<a href="{{urlTo "person" current_user.guid}}" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
|
||||
<li class="dropdown user-menu" id="user-menu">
|
||||
<a href="{{urlTo "person" current_user.guid}}" class="dropdown-toggle hidden-xs hidden-sm" data-toggle="dropdown" role="button" aria-expanded="false">
|
||||
<span class="user-avatar pull-left">
|
||||
{{{personImage current_user "small"}}}
|
||||
</span>
|
||||
|
|
@ -94,7 +77,7 @@
|
|||
<span class="caret"></span>
|
||||
</a>
|
||||
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<ul class="dropdown-menu user-menu-dropdown" role="menu">
|
||||
<li><a href="/people/{{current_user.guid}}">{{t "header.profile"}}</a></li>
|
||||
<li><a href="/contacts">{{t "header.contacts"}}</a></li>
|
||||
<li><a href="/user/edit">{{t "header.settings"}}</a></li>
|
||||
|
|
|
|||
|
|
@ -36,22 +36,18 @@
|
|||
<a href="#" class="section-unselected faq-link" data-section="private_posts" data-items="who_sees_post can_comment can_reshare see_comment">{{ title_private_posts }}</a>
|
||||
<span class="section-selected">{{ title_private_posts }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="section-unselected faq-link" data-section="private_profiles" data-items="who_sees_profile whats_in_profile who_sees_updates">{{ title_private_profiles }}</a>
|
||||
<span class="section-selected">{{ title_private_profiles }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="section-unselected faq-link" data-section="public_posts" data-items="who_sees_post find_public_post can_comment_reshare_like see_comment_reshare_like deselect_aspect_posting">{{ title_public_posts }}</a>
|
||||
<span class="section-selected">{{ title_public_posts }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="section-unselected faq-link" data-section="public_profiles" data-items="who_sees_profile whats_in_profile who_sees_updates what_do_tags_do">{{ title_public_profiles }}</a>
|
||||
<span class="section-selected">{{ title_public_profiles }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="section-unselected faq-link" data-section="resharing_posts" data-items="reshare_public_post_aspects reshare_private_post_aspects">{{ title_resharing_posts }}</a>
|
||||
<span class="section-selected">{{ title_resharing_posts }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="section-unselected faq-link" data-section="profile" data-items="whats_in_profile who_sees_profile what_do_tags_do">{{ title_profile }}</a>
|
||||
<span class="section-selected">{{ title_profile }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#" class="section-unselected faq-link-sharing" data-section="sharing" data-items="">{{ title_sharing }}</a>
|
||||
<span class="section-selected">{{ title_sharing }}</span>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,12 @@
|
|||
{{{personImage this "small" "micro"}}}
|
||||
{{/linkToAuthor}}
|
||||
{{/each}}
|
||||
{{#if showMoreReshares}}
|
||||
<div class="loader hidden">
|
||||
<div class="spinner"></div>
|
||||
</div>
|
||||
<div id="show-all-reshares" class="btn btn-sm btn-link">{{t "show_all"}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
@ -25,6 +31,12 @@
|
|||
{{{personImage this "small" "micro"}}}
|
||||
{{/linkToAuthor}}
|
||||
{{/each}}
|
||||
{{#if showMoreLikes}}
|
||||
<div class="loader hidden">
|
||||
<div class="spinner"></div>
|
||||
</div>
|
||||
<div id="show-all-likes" class="btn btn-sm btn-link">{{t "show_all"}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,26 @@
|
|||
<div class="media {{#if showPost}} {{#if nsfw}} shield-off {{/if}} {{else}} shield-active {{/if}}">
|
||||
{{#with author}}
|
||||
<a href="/people/{{guid}}" class="img {{{hovercardable this}}}">
|
||||
{{{personImage this}}}
|
||||
</a>
|
||||
{{/with}}
|
||||
|
||||
{{#unless preview}}
|
||||
{{#with author}}
|
||||
<a href="/people/{{guid}}" class="img {{{hovercardable this}}}">
|
||||
{{{personImage this}}}
|
||||
</a>
|
||||
{{/with}}
|
||||
{{/unless}}
|
||||
|
||||
<div class="bd">
|
||||
{{#if loggedIn}}
|
||||
<div class="post-controls"></div>
|
||||
{{/if}}
|
||||
{{#unless preview}}
|
||||
{{#if loggedIn}}
|
||||
<div class="post-controls"></div>
|
||||
{{/if}}
|
||||
|
||||
<div>
|
||||
{{#linkToAuthor author}}
|
||||
{{~name~}}
|
||||
{{/linkToAuthor}}
|
||||
<div>
|
||||
{{#linkToAuthor author}}
|
||||
{{~name~}}
|
||||
{{/linkToAuthor}}
|
||||
|
||||
<span class="details gray">
|
||||
-
|
||||
{{#if preview}}
|
||||
<time class="timeago" data-original-title="{{{localTime created_at}}}" datetime="{{created_at}}" />
|
||||
{{else}}
|
||||
<span class="details gray">
|
||||
-
|
||||
<a href="/posts/{{id}}">
|
||||
<time class="timeago" data-original-title="{{{localTime created_at}}}" datetime="{{created_at}}" />
|
||||
</a>
|
||||
|
|
@ -27,16 +28,18 @@
|
|||
<a href="/posts/{{guid}}" class="permalink" title="{{t "stream.permalink"}}">
|
||||
<i class="entypo-link"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
</span>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
{{/unless}}
|
||||
|
||||
<div class="post-content"> </div>
|
||||
<div class="status-message-location nsfw-hidden"> </div>
|
||||
|
||||
<div class="feedback nsfw-hidden"> </div>
|
||||
<div class="likes nsfw-hidden"> </div>
|
||||
<div class="reshares nsfw-hidden"> </div>
|
||||
<div class="comments nsfw-hidden"> </div>
|
||||
{{#unless preview}}
|
||||
<div class="feedback nsfw-hidden"> </div>
|
||||
<div class="likes nsfw-hidden"> </div>
|
||||
<div class="reshares nsfw-hidden"> </div>
|
||||
<div class="comments nsfw-hidden"> </div>
|
||||
{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
module Admin
|
||||
class AdminController < ApplicationController
|
||||
|
||||
before_filter :authenticate_user!
|
||||
before_filter :redirect_unless_admin
|
||||
|
||||
before_action :authenticate_user!
|
||||
before_action :redirect_unless_admin
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ module Api
|
|||
if prompt && prompt.include?("none")
|
||||
handle_prompt_none
|
||||
elsif prompt && prompt.include?("login")
|
||||
new_params = params.except("controller", "action").merge(prompt: prompt.remove("login"))
|
||||
new_params = params.except("controller", "action").permit!.to_h.merge(prompt: prompt.remove("login"))
|
||||
reauthenticate(new_params)
|
||||
else
|
||||
authenticate_user!
|
||||
|
|
|
|||
|
|
@ -24,17 +24,6 @@
|
|||
module Api
|
||||
module OpenidConnect
|
||||
class DiscoveryController < ApplicationController
|
||||
def webfinger
|
||||
jrd = {
|
||||
links: [{
|
||||
rel: OpenIDConnect::Discovery::Provider::Issuer::REL_VALUE,
|
||||
href: root_url
|
||||
}]
|
||||
}
|
||||
jrd[:subject] = params[:resource] if params[:resource].present?
|
||||
render json: jrd, content_type: "application/jrd+json"
|
||||
end
|
||||
|
||||
def configuration
|
||||
render json: OpenIDConnect::Discovery::Provider::Config::Response.new(
|
||||
issuer: root_url,
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@ module Api
|
|||
if req["client_assertion_type"] == "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
|
||||
handle_jwt_bearer(req)
|
||||
end
|
||||
self.status, response.headers, self.response_body = Api::OpenidConnect::TokenEndpoint.new.call(request.env)
|
||||
self.status, headers, self.response_body = Api::OpenidConnect::TokenEndpoint.new.call(request.env)
|
||||
headers.each {|name, value| response.headers[name] = value }
|
||||
nil
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
class ApplicationController < ActionController::Base
|
||||
before_action :force_tablet_html
|
||||
has_mobile_fu
|
||||
protect_from_forgery except: :receive, with: :exception
|
||||
protect_from_forgery except: :receive, with: :exception, prepend: true
|
||||
|
||||
rescue_from ActionController::InvalidAuthenticityToken do
|
||||
if user_signed_in?
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
class AspectMembershipsController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
|
||||
respond_to :html, :json
|
||||
respond_to :json
|
||||
|
||||
def destroy
|
||||
aspect = current_user.aspects.joins(:aspect_memberships).where(aspect_memberships: {id: params[:id]}).first
|
||||
|
|
@ -30,18 +30,9 @@ class AspectMembershipsController < ApplicationController
|
|||
if success
|
||||
render json: AspectMembershipPresenter.new(membership).base_hash
|
||||
else
|
||||
render text: membership.errors.full_messages, status: 403
|
||||
render plain: membership.errors.full_messages, status: 403
|
||||
end
|
||||
end
|
||||
|
||||
format.all do
|
||||
if success
|
||||
flash.now[:notice] = I18n.t "aspect_memberships.destroy.success"
|
||||
else
|
||||
flash.now[:error] = I18n.t "aspect_memberships.destroy.failure"
|
||||
end
|
||||
redirect_to :back
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -58,35 +49,25 @@ class AspectMembershipsController < ApplicationController
|
|||
AspectMembership.where(contact_id: @contact.id, aspect_id: @aspect.id).first)
|
||||
.base_hash
|
||||
end
|
||||
|
||||
format.all do
|
||||
flash.now[:notice] = I18n.t("aspects.add_to_aspect.success")
|
||||
redirect_to :back
|
||||
end
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
render text: I18n.t("aspects.add_to_aspect.failure"), status: 409
|
||||
end
|
||||
|
||||
format.all do
|
||||
flash.now[:error] = I18n.t("aspects.add_to_aspect.failure")
|
||||
render nothing: true, status: 409
|
||||
render plain: I18n.t("aspects.add_to_aspect.failure"), status: 409
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
rescue_from ActiveRecord::StatementInvalid do
|
||||
render text: I18n.t("aspect_memberships.destroy.invalid_statement"), status: 400
|
||||
render plain: I18n.t("aspect_memberships.destroy.invalid_statement"), status: 400
|
||||
end
|
||||
|
||||
rescue_from ActiveRecord::RecordNotFound do
|
||||
render text: I18n.t("aspect_memberships.destroy.no_membership"), status: 404
|
||||
render plain: I18n.t("aspect_memberships.destroy.no_membership"), status: 404
|
||||
end
|
||||
|
||||
rescue_from Diaspora::NotMine do
|
||||
render text: I18n.t("aspect_memberships.destroy.forbidden"), status: 403
|
||||
render plain: I18n.t("aspect_memberships.destroy.forbidden"), status: 403
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class AspectsController < ApplicationController
|
|||
|
||||
render json: result
|
||||
else
|
||||
render nothing: true, status: 422
|
||||
head :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -71,7 +71,7 @@ class AspectsController < ApplicationController
|
|||
params[:ordered_aspect_ids].each_with_index do |id, i|
|
||||
current_user.aspects.find(id).update_attributes(order_id: i)
|
||||
end
|
||||
render nothing: true
|
||||
head :no_content
|
||||
end
|
||||
|
||||
def toggle_chat_privilege
|
||||
|
|
@ -79,7 +79,7 @@ class AspectsController < ApplicationController
|
|||
|
||||
@aspect.chat_enabled = !@aspect.chat_enabled
|
||||
@aspect.save
|
||||
render :nothing => true
|
||||
head :no_content
|
||||
end
|
||||
|
||||
def toggle_contact_visibility
|
||||
|
|
@ -91,7 +91,7 @@ class AspectsController < ApplicationController
|
|||
@aspect.contacts_visible = true
|
||||
end
|
||||
@aspect.save
|
||||
render :nothing => true
|
||||
head :no_content
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
|||
|
|
@ -1,34 +1,26 @@
|
|||
class BlocksController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
|
||||
respond_to :html, :json
|
||||
|
||||
def create
|
||||
block = current_user.blocks.new(block_params)
|
||||
|
||||
if block.save
|
||||
disconnect_if_contact(block.person)
|
||||
notice = {:notice => t('blocks.create.success')}
|
||||
else
|
||||
notice = {:error => t('blocks.create.failure')}
|
||||
end
|
||||
disconnect_if_contact(block.person) if block.save
|
||||
|
||||
respond_with do |format|
|
||||
format.html{ redirect_to :back, notice }
|
||||
format.json{ render :nothing => true, :status => 204 }
|
||||
respond_to do |format|
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if current_user.blocks.find(params[:id]).delete
|
||||
notice = {:notice => t('blocks.destroy.success')}
|
||||
else
|
||||
notice = {:error => t('blocks.destroy.failure')}
|
||||
end
|
||||
notice = if current_user.blocks.find_by(id: params[:id])&.delete
|
||||
{notice: t("blocks.destroy.success")}
|
||||
else
|
||||
{error: t("blocks.destroy.failure")}
|
||||
end
|
||||
|
||||
respond_with do |format|
|
||||
format.html{ redirect_to :back, notice }
|
||||
format.json{ render :nothing => true, :status => 204 }
|
||||
respond_to do |format|
|
||||
format.json { head :no_content }
|
||||
format.any { redirect_back fallback_location: privacy_settings_path, flash: notice }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -8,21 +8,21 @@ class CommentsController < ApplicationController
|
|||
respond_to :html, :mobile, :json
|
||||
|
||||
rescue_from ActiveRecord::RecordNotFound do
|
||||
render nothing: true, status: 404
|
||||
head :not_found
|
||||
end
|
||||
|
||||
def create
|
||||
begin
|
||||
comment = comment_service.create(params[:post_id], params[:text])
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
render text: I18n.t("comments.create.error"), status: 404
|
||||
render plain: I18n.t("comments.create.error"), status: 404
|
||||
return
|
||||
end
|
||||
|
||||
if comment
|
||||
respond_create_success(comment)
|
||||
else
|
||||
render text: I18n.t("comments.create.error"), status: 422
|
||||
render plain: I18n.t("comments.create.error"), status: 422
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -57,24 +57,24 @@ class CommentsController < ApplicationController
|
|||
def respond_create_success(comment)
|
||||
respond_to do |format|
|
||||
format.json { render json: CommentPresenter.new(comment), status: 201 }
|
||||
format.html { render nothing: true, status: 201 }
|
||||
format.html { head :created }
|
||||
format.mobile { render partial: "comment", locals: {comment: comment} }
|
||||
end
|
||||
end
|
||||
|
||||
def respond_destroy_success
|
||||
respond_to do |format|
|
||||
format.mobile { redirect_to :back }
|
||||
format.js { render nothing: true, status: 204 }
|
||||
format.json { render nothing: true, status: 204 }
|
||||
format.mobile { redirect_back fallback_location: stream_path }
|
||||
format.js { head :no_content }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
end
|
||||
|
||||
def respond_destroy_error
|
||||
respond_to do |format|
|
||||
format.mobile { redirect_to :back }
|
||||
format.js { render nothing: true, status: 403 }
|
||||
format.json { render nothing: true, status: 403 }
|
||||
format.mobile { redirect_back fallback_location: stream_path }
|
||||
format.js { head :forbidden }
|
||||
format.json { head :forbidden }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class ConversationsController < ApplicationController
|
|||
end
|
||||
|
||||
unless person_ids.present?
|
||||
render text: I18n.t("javascripts.conversation.create.no_recipient"), status: 422
|
||||
render plain: I18n.t("javascripts.conversation.create.no_recipient"), status: 422
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -53,7 +53,7 @@ class ConversationsController < ApplicationController
|
|||
flash[:notice] = I18n.t("conversations.create.sent")
|
||||
render json: {id: @conversation.id}
|
||||
else
|
||||
render text: I18n.t("conversations.create.fail"), status: 422
|
||||
render plain: I18n.t("conversations.create.fail"), status: 422
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -82,7 +82,7 @@ class ConversationsController < ApplicationController
|
|||
@conversation.set_read(current_user)
|
||||
render partial: "conversations/show", locals: {conversation: @conversation}
|
||||
else
|
||||
render nothing: true, status: 404
|
||||
head :not_found
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class HomeController < ApplicationController
|
|||
def toggle_mobile
|
||||
session[:mobile_view] = session[:mobile_view].nil? ? true : !session[:mobile_view]
|
||||
|
||||
redirect_to :back
|
||||
redirect_back fallback_location: root_path
|
||||
end
|
||||
|
||||
def force_mobile
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ class InvitationsController < ApplicationController
|
|||
t("invitations.create.rejected", emails: invalid_emails.join(", "))
|
||||
end
|
||||
|
||||
redirect_to :back
|
||||
redirect_back fallback_location: stream_path
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -55,7 +55,7 @@ class InvitationsController < ApplicationController
|
|||
else
|
||||
t("invitations.create.closed")
|
||||
end
|
||||
redirect_to :back
|
||||
redirect_back fallback_location: stream_path
|
||||
end
|
||||
|
||||
def valid_email?(email)
|
||||
|
|
@ -71,6 +71,6 @@ class InvitationsController < ApplicationController
|
|||
end
|
||||
|
||||
def inviter_params
|
||||
params.require(:email_inviter).permit(:message, :locale, :emails)
|
||||
params.require(:email_inviter).permit(:message, :locale, :emails).to_h
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ class LikesController < ApplicationController
|
|||
def create
|
||||
like = like_service.create(params[:post_id])
|
||||
rescue ActiveRecord::RecordNotFound, ActiveRecord::RecordInvalid
|
||||
render text: I18n.t("likes.create.error"), status: 422
|
||||
render plain: I18n.t("likes.create.error"), status: 422
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { render nothing: true, status: 201 }
|
||||
format.html { head :created }
|
||||
format.mobile { redirect_to post_path(like.post_id) }
|
||||
format.json { render json: like.as_api_response(:backbone), status: 201 }
|
||||
end
|
||||
|
|
@ -24,9 +24,9 @@ class LikesController < ApplicationController
|
|||
|
||||
def destroy
|
||||
if like_service.destroy(params[:id])
|
||||
render nothing: true, status: 204
|
||||
head :no_content
|
||||
else
|
||||
render text: I18n.t("likes.destroy.error"), status: 404
|
||||
render plain: I18n.t("likes.destroy.error"), status: 404
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -18,14 +18,6 @@ class MessagesController < ApplicationController
|
|||
logger.info "event=create type=message user=#{current_user.diaspora_handle} status=success " \
|
||||
"message=#{message.id} chars=#{params[:message][:text].length}"
|
||||
Diaspora::Federation::Dispatcher.defer_dispatch(current_user, message)
|
||||
|
||||
# TODO: can be removed when messages are not relayed anymore
|
||||
conversation_owner = conversation.author.owner
|
||||
if conversation_owner && conversation_owner != current_user
|
||||
remote_subs = conversation.participants.remote.ids
|
||||
opts = {subscriber_ids: remote_subs}
|
||||
Diaspora::Federation::Dispatcher.defer_dispatch(conversation_owner, message, opts) unless remote_subs.empty?
|
||||
end
|
||||
else
|
||||
flash[:error] = I18n.t('conversations.new_conversation.fail')
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,4 @@
|
|||
class NodeInfoController < ApplicationController
|
||||
respond_to :json
|
||||
respond_to :html, only: :statistics
|
||||
|
||||
def jrd
|
||||
render json: NodeInfo.jrd(CGI.unescape(node_info_url("123.123").sub("123.123", "%{version}")))
|
||||
end
|
||||
|
|
@ -17,7 +14,7 @@ class NodeInfoController < ApplicationController
|
|||
|
||||
def statistics
|
||||
respond_to do |format|
|
||||
format.json { render json: StatisticsPresenter.new }
|
||||
format.json { head :not_acceptable }
|
||||
format.all { @statistics = NodeInfoPresenter.new("1.0") }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ class NotificationsController < ApplicationController
|
|||
|
||||
def index
|
||||
conditions = {:recipient_id => current_user.id}
|
||||
if params[:type] && Notification.types.has_key?(params[:type])
|
||||
conditions[:type] = Notification.types[params[:type]]
|
||||
if params[:type] && types.has_key?(params[:type])
|
||||
conditions[:type] = types[params[:type]]
|
||||
end
|
||||
if params[:show] == "unread" then conditions[:unread] = true end
|
||||
page = params[:page] || 1
|
||||
|
|
@ -44,7 +44,7 @@ class NotificationsController < ApplicationController
|
|||
|
||||
@grouped_unread_notification_counts = {}
|
||||
|
||||
Notification.types.each_with_object(current_user.unread_notifications.group_by(&:type)) {|(name, type), notifications|
|
||||
types.each_with_object(current_user.unread_notifications.group_by(&:type)) {|(name, type), notifications|
|
||||
@grouped_unread_notification_counts[name] = notifications.has_key?(type) ? notifications[type].count : 0
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ class NotificationsController < ApplicationController
|
|||
end
|
||||
|
||||
def read_all
|
||||
current_type = Notification.types[params[:type]]
|
||||
current_type = types[params[:type]]
|
||||
notifications = Notification.where(recipient_id: current_user.id, unread: true)
|
||||
notifications = notifications.where(type: current_type) if params[:type]
|
||||
notifications.update_all(unread: false)
|
||||
|
|
@ -93,4 +93,17 @@ class NotificationsController < ApplicationController
|
|||
}
|
||||
}.as_json
|
||||
end
|
||||
|
||||
def types
|
||||
{
|
||||
"also_commented" => "Notifications::AlsoCommented",
|
||||
"comment_on_post" => "Notifications::CommentOnPost",
|
||||
"liked" => "Notifications::Liked",
|
||||
"mentioned" => "Notifications::MentionedInPost",
|
||||
"mentioned_in_comment" => "Notifications::MentionedInComment",
|
||||
"reshared" => "Notifications::Reshared",
|
||||
"started_sharing" => "Notifications::StartedSharing"
|
||||
}
|
||||
end
|
||||
helper_method :types
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ class ParticipationsController < ApplicationController
|
|||
post = current_user.find_visible_shareable_by_id(Post, params[:post_id])
|
||||
if post
|
||||
current_user.participate! post
|
||||
render nothing: true, status: :created
|
||||
head :created
|
||||
else
|
||||
render nothing: true, status: :forbidden
|
||||
head :forbidden
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -15,9 +15,9 @@ class ParticipationsController < ApplicationController
|
|||
participation = current_user.participations.find_by target_id: params[:post_id]
|
||||
if participation
|
||||
participation.destroy
|
||||
render nothing: true, status: :ok
|
||||
head :ok
|
||||
else
|
||||
render nothing: true, status: :unprocessable_entity
|
||||
head :unprocessable_entity
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@ class PeopleController < ApplicationController
|
|||
|
||||
rescue_from Diaspora::AccountClosed do
|
||||
respond_to do |format|
|
||||
format.any { redirect_to :back, :notice => t("people.show.closed_account") }
|
||||
format.json { render :nothing => true, :status => 410 } # 410 GONE
|
||||
format.any { redirect_back fallback_location: root_path, notice: t("people.show.closed_account") }
|
||||
format.json { head :gone }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -115,15 +115,15 @@ class PeopleController < ApplicationController
|
|||
def retrieve_remote
|
||||
if params[:diaspora_handle]
|
||||
Workers::FetchWebfinger.perform_async(params[:diaspora_handle])
|
||||
render :nothing => true
|
||||
head :ok
|
||||
else
|
||||
render :nothing => true, :status => 422
|
||||
head :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def contacts
|
||||
respond_to do |format|
|
||||
format.json { render nothing: true, status: 406 }
|
||||
format.json { head :not_acceptable }
|
||||
|
||||
format.any do
|
||||
@person = Person.find_by_guid(params[:person_id])
|
||||
|
|
|
|||
|
|
@ -66,10 +66,10 @@ class PhotosController < ApplicationController
|
|||
:status => 201}
|
||||
end
|
||||
else
|
||||
render :nothing => true, :status => 422
|
||||
head :unprocessable_entity
|
||||
end
|
||||
else
|
||||
render :nothing => true, :status => 422
|
||||
head :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ class PhotosController < ApplicationController
|
|||
current_user.retract(photo)
|
||||
|
||||
respond_to do |format|
|
||||
format.json{ render :nothing => true, :status => 204 }
|
||||
format.json { head :no_content }
|
||||
format.html do
|
||||
flash[:notice] = I18n.t 'photos.destroy.notice'
|
||||
if StatusMessage.find_by_guid(photo.status_message_guid)
|
||||
|
|
@ -125,27 +125,28 @@ class PhotosController < ApplicationController
|
|||
end
|
||||
|
||||
def legacy_create
|
||||
if params[:photo][:aspect_ids] == "all"
|
||||
params[:photo][:aspect_ids] = current_user.aspects.collect { |x| x.id }
|
||||
elsif params[:photo][:aspect_ids].is_a?(Hash)
|
||||
params[:photo][:aspect_ids] = params[:photo][:aspect_ids].values
|
||||
photo_params = params.require(:photo).permit(:pending, :set_profile_photo, aspect_ids: [])
|
||||
if photo_params[:aspect_ids] == "all"
|
||||
photo_params[:aspect_ids] = current_user.aspects.map(&:id)
|
||||
elsif photo_params[:aspect_ids].is_a?(Hash)
|
||||
photo_params[:aspect_ids] = params[:photo][:aspect_ids].values
|
||||
end
|
||||
|
||||
params[:photo][:user_file] = file_handler(params)
|
||||
photo_params[:user_file] = file_handler(params)
|
||||
|
||||
@photo = current_user.build_post(:photo, params[:photo])
|
||||
@photo = current_user.build_post(:photo, photo_params)
|
||||
|
||||
if @photo.save
|
||||
|
||||
unless @photo.pending
|
||||
unless @photo.public?
|
||||
aspects = current_user.aspects_from_ids(params[:photo][:aspect_ids])
|
||||
aspects = current_user.aspects_from_ids(photo_params[:aspect_ids])
|
||||
current_user.add_to_streams(@photo, aspects)
|
||||
end
|
||||
current_user.dispatch_post(@photo, :to => params[:photo][:aspect_ids])
|
||||
current_user.dispatch_post(@photo, to: photo_params[:aspect_ids])
|
||||
end
|
||||
|
||||
if params[:photo][:set_profile_photo]
|
||||
if photo_params[:set_profile_photo]
|
||||
profile_params = {:image_url => @photo.url(:thumb_large),
|
||||
:image_url_medium => @photo.url(:thumb_medium),
|
||||
:image_url_small => @photo.url(:thumb_small)}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,17 @@
|
|||
class PollParticipationsController < ApplicationController
|
||||
include ApplicationHelper
|
||||
before_filter :authenticate_user!
|
||||
before_action :authenticate_user!
|
||||
|
||||
def create
|
||||
answer = PollAnswer.find(params[:poll_answer_id])
|
||||
poll_participation = current_user.participate_in_poll!(target, answer) if target
|
||||
respond_to do |format|
|
||||
format.html { redirect_to :back }
|
||||
format.mobile { redirect_to stream_path }
|
||||
format.json { render json: poll_participation, :status => 201 }
|
||||
end
|
||||
rescue ActiveRecord::RecordInvalid
|
||||
respond_to do |format|
|
||||
format.html { redirect_to :back }
|
||||
format.mobile { redirect_to stream_path }
|
||||
format.json { render :nothing => true, :status => 403 }
|
||||
format.json { head :forbidden }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -25,4 +22,4 @@ class PollParticipationsController < ApplicationController
|
|||
current_user.find_visible_shareable_by_id(Post, params[:post_id]) || raise(ActiveRecord::RecordNotFound.new)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# the COPYRIGHT file.
|
||||
|
||||
class PostsController < ApplicationController
|
||||
before_action :authenticate_user!, only: :destroy
|
||||
before_action :authenticate_user!, only: %i(destroy mentionable)
|
||||
before_action :set_format_if_malformed_from_status_net, only: :show
|
||||
|
||||
respond_to :html, :mobile, :json, :xml
|
||||
|
|
@ -13,7 +13,7 @@ class PostsController < ApplicationController
|
|||
end
|
||||
|
||||
rescue_from Diaspora::NotMine do
|
||||
render text: I18n.t("posts.show.forbidden"), status: 403
|
||||
render plain: I18n.t("posts.show.forbidden"), status: 403
|
||||
end
|
||||
|
||||
def show
|
||||
|
|
@ -22,12 +22,11 @@ class PostsController < ApplicationController
|
|||
presenter = PostPresenter.new(post, current_user)
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
gon.post = presenter
|
||||
gon.post = presenter.with_initial_interactions
|
||||
render locals: {post: presenter}
|
||||
end
|
||||
format.mobile { render locals: {post: post} }
|
||||
format.xml { render xml: DiasporaFederation::Salmon::XmlPayload.pack(Diaspora::Federation::Entities.post(post)) }
|
||||
format.json { render json: presenter }
|
||||
format.json { render json: presenter.with_interactions }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -37,23 +36,28 @@ class PostsController < ApplicationController
|
|||
oembed = params.slice(:format, :maxheight, :minheight)
|
||||
render json: OEmbedPresenter.new(post, oembed)
|
||||
rescue
|
||||
render nothing: true, status: 404
|
||||
head :not_found
|
||||
end
|
||||
|
||||
def interactions
|
||||
def mentionable
|
||||
respond_to do |format|
|
||||
format.json {
|
||||
post = post_service.find!(params[:id])
|
||||
render json: PostInteractionPresenter.new(post, current_user)
|
||||
if params[:id].present? && params[:q].present?
|
||||
render json: post_service.mentionable_in_comment(params[:id], params[:q])
|
||||
else
|
||||
head :no_content
|
||||
end
|
||||
}
|
||||
format.any { render nothing: true, status: 406 }
|
||||
format.any { head :not_acceptable }
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
head :not_found
|
||||
end
|
||||
|
||||
def destroy
|
||||
post_service.destroy(params[:id])
|
||||
respond_to do |format|
|
||||
format.json { render nothing: true, status: 204 }
|
||||
format.json { head :no_content }
|
||||
format.any { redirect_to stream_path }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ class ProfilesController < ApplicationController
|
|||
end
|
||||
|
||||
respond_to do |format|
|
||||
format.js { render :nothing => true, :status => 200 }
|
||||
format.js { head :ok }
|
||||
format.any {
|
||||
if current_user.getting_started?
|
||||
redirect_to getting_started_path
|
||||
|
|
@ -77,6 +77,6 @@ class ProfilesController < ApplicationController
|
|||
def profile_params
|
||||
params.require(:profile).permit(:first_name, :last_name, :gender, :bio,
|
||||
:location, :searchable, :tag_string, :nsfw,
|
||||
:public_details, date: %i(year month day)) || {}
|
||||
:public_details, date: %i[year month day]).to_h || {}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class ReportController < ApplicationController
|
|||
if report.save
|
||||
render json: true, status: 200
|
||||
else
|
||||
render nothing: true, status: 409
|
||||
head :conflict
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ class ResharesController < ApplicationController
|
|||
def create
|
||||
reshare = reshare_service.create(params[:root_guid])
|
||||
rescue ActiveRecord::RecordNotFound, ActiveRecord::RecordInvalid
|
||||
render text: I18n.t("reshares.create.error"), status: 422
|
||||
render plain: I18n.t("reshares.create.error"), status: 422
|
||||
else
|
||||
render json: ExtremePostPresenter.new(reshare, current_user), status: 201
|
||||
render json: PostPresenter.new(reshare, current_user).with_interactions, status: 201
|
||||
end
|
||||
|
||||
def index
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
class SearchController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
|
||||
|
||||
def search
|
||||
if search_query.starts_with?('#')
|
||||
if search_query.length > 1
|
||||
respond_to do |format|
|
||||
respond_to do |format|
|
||||
format.json {redirect_to tags_path(:q => search_query.delete("#."))}
|
||||
format.any {redirect_to tag_path(:name => search_query.delete("#."))}
|
||||
end
|
||||
else
|
||||
flash[:error] = I18n.t('tags.show.none', :name => search_query)
|
||||
redirect_to :back
|
||||
redirect_back fallback_location: stream_path
|
||||
end
|
||||
else
|
||||
redirect_to people_path(:q => search_query)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
|
||||
def search_query
|
||||
@search_query ||= (params[:q] || params[:term] || '').strip
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
# the COPYRIGHT file.
|
||||
|
||||
class SessionsController < Devise::SessionsController
|
||||
after_filter :reset_authentication_token, :only => [:create]
|
||||
before_filter :reset_authentication_token, :only => [:destroy]
|
||||
after_action :reset_authentication_token, only: [:create]
|
||||
before_action :reset_authentication_token, only: [:destroy]
|
||||
|
||||
def reset_authentication_token
|
||||
current_user.reset_authentication_token! unless current_user.nil?
|
||||
|
|
|
|||
|
|
@ -47,14 +47,8 @@ class StatusMessagesController < ApplicationController
|
|||
end
|
||||
|
||||
def create
|
||||
normalized_params = params.merge(
|
||||
services: normalize_services,
|
||||
aspect_ids: normalize_aspect_ids,
|
||||
public: normalize_public_flag
|
||||
)
|
||||
status_message = StatusMessageCreationService.new(current_user).create(normalized_params)
|
||||
status_message = StatusMessageCreationService.new(current_user).create(normalize_params)
|
||||
respond_to do |format|
|
||||
format.html { redirect_to :back }
|
||||
format.mobile { redirect_to stream_path }
|
||||
format.json { render json: PostPresenter.new(status_message, current_user), status: 201 }
|
||||
end
|
||||
|
|
@ -71,9 +65,8 @@ class StatusMessagesController < ApplicationController
|
|||
def handle_create_error(error)
|
||||
logger.debug error
|
||||
respond_to do |format|
|
||||
format.html { redirect_to :back }
|
||||
format.mobile { redirect_to stream_path }
|
||||
format.json { render text: error.message, status: 403 }
|
||||
format.json { render plain: error.message, status: 403 }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -89,8 +82,19 @@ class StatusMessagesController < ApplicationController
|
|||
request.env["HTTP_REFERER"].include?("/people/" + current_user.guid)
|
||||
end
|
||||
|
||||
def normalize_services
|
||||
[*params[:services]].compact
|
||||
def normalize_params
|
||||
params.permit(
|
||||
:location_address,
|
||||
:location_coords,
|
||||
:poll_question,
|
||||
status_message: %i[text provider_display_name],
|
||||
poll_answers: []
|
||||
).to_h.merge(
|
||||
services: [*params[:services]].compact,
|
||||
aspect_ids: normalize_aspect_ids,
|
||||
public: [*params[:aspect_ids]].first == "public",
|
||||
photos: [*params[:photos]].compact
|
||||
)
|
||||
end
|
||||
|
||||
def normalize_aspect_ids
|
||||
|
|
@ -102,10 +106,6 @@ class StatusMessagesController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def normalize_public_flag
|
||||
[*params[:aspect_ids]].first == "public"
|
||||
end
|
||||
|
||||
def remove_getting_started
|
||||
current_user.disable_getting_started
|
||||
end
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ class TagFollowingsController < ApplicationController
|
|||
name_normalized = ActsAsTaggableOn::Tag.normalize(params['name'])
|
||||
|
||||
if name_normalized.nil? || name_normalized.empty?
|
||||
render :nothing => true, :status => 403
|
||||
head :forbidden
|
||||
else
|
||||
@tag = ActsAsTaggableOn::Tag.find_or_create_by(name: name_normalized)
|
||||
@tag_following = current_user.tag_followings.new(:tag_id => @tag.id)
|
||||
|
|
@ -23,7 +23,7 @@ class TagFollowingsController < ApplicationController
|
|||
if @tag_following.save
|
||||
render :json => @tag.to_json, :status => 201
|
||||
else
|
||||
render :nothing => true, :status => 403
|
||||
head :forbidden
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -35,11 +35,11 @@ class TagFollowingsController < ApplicationController
|
|||
|
||||
if tag_following && tag_following.destroy
|
||||
respond_to do |format|
|
||||
format.any(:js, :json) { render :nothing => true, :status => 204 }
|
||||
format.any(:js, :json) { head :no_content }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.any(:js, :json) {render :nothing => true, :status => 403}
|
||||
format.any(:js, :json) { head :forbidden }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@ class TagsController < ApplicationController
|
|||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.json{ render :nothing => true, :status => 422 }
|
||||
format.html{ redirect_to tag_path('partytimeexcellent') }
|
||||
format.json { head :unprocessable_entity }
|
||||
format.html { redirect_to tag_path("partytimeexcellent") }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class UsersController < ApplicationController
|
|||
flash[:error] = t("users.update.settings_not_updated")
|
||||
end
|
||||
|
||||
redirect_to :back
|
||||
redirect_back fallback_location: privacy_settings_path
|
||||
end
|
||||
|
||||
def destroy
|
||||
|
|
@ -60,7 +60,7 @@ class UsersController < ApplicationController
|
|||
else
|
||||
flash[:error] = t "users.destroy.no_password"
|
||||
end
|
||||
redirect_to :back
|
||||
redirect_back fallback_location: edit_user_path
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -150,16 +150,7 @@ class UsersController < ApplicationController
|
|||
:auto_follow_back_aspect_id,
|
||||
:getting_started,
|
||||
:post_default_public,
|
||||
email_preferences: %i(
|
||||
someone_reported
|
||||
also_commented
|
||||
mentioned
|
||||
comment_on_post
|
||||
private_message
|
||||
started_sharing
|
||||
liked
|
||||
reshared
|
||||
)
|
||||
email_preferences: UserPreference::VALID_EMAIL_TYPES.map(&:to_sym)
|
||||
)
|
||||
end
|
||||
# rubocop:enable Metrics/MethodLength
|
||||
|
|
|
|||
|
|
@ -1,69 +0,0 @@
|
|||
# Copyright (c) 2010-2012, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
module AnalyticsHelper
|
||||
def include_mixpanel
|
||||
include_analytics "mixpanel" do
|
||||
nonced_javascript_tag do
|
||||
<<-JS.html_safe
|
||||
(function(d,c){var a,b,g,e;a=d.createElement('script');a.type='text/javascript';a.async=!0;a.src=('https:'===d.location.protocol?'https:':'http:')+'//api.mixpanel.com/site_media/js/api/mixpanel.2.js';b=d.getElementsByTagName('script')[0];b.parentNode.insertBefore(a,b);c._i=[];c.init=function(a,d,f){var b=c;'undefined'!==typeof f?b=c[f]=[]:f='mixpanel';g='disable track track_pageview track_links track_forms register register_once unregister identify name_tag set_config'.split(' ');
|
||||
for(e=0;e<g.length;e++)(function(a){b[a]=function(){b.push([a].concat(Array.prototype.slice.call(arguments,0)))}})(g[e]);c._i.push([a,d,f])};window.mixpanel=c})(document,[]);
|
||||
mixpanel.init("#{AppConfig.privacy.mixpanel_uid}");
|
||||
JS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def include_mixpanel_guid
|
||||
return unless current_user
|
||||
include_analytics "mixpanel" do
|
||||
nonced_javascript_tag do
|
||||
<<-JS.html_safe
|
||||
mixpanel.name_tag("#{current_user.guid}");
|
||||
JS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def chartbeat_head_block
|
||||
return unless configured?("chartbeat")
|
||||
nonced_javascript_tag("var _sf_startpt=(new Date()).getTime()")
|
||||
end
|
||||
|
||||
def include_chartbeat
|
||||
include_analytics "chartbeat" do
|
||||
nonced_javascript_tag do
|
||||
<<-JS.html_safe
|
||||
var _sf_async_config = { uid: #{AppConfig.privacy.chartbeat_uid}, domain: "#{AppConfig.pod_uri.host}" };
|
||||
(function() {
|
||||
function loadChartbeat() {
|
||||
window._sf_endpt = (new Date()).getTime();
|
||||
var e = document.createElement('script');
|
||||
e.setAttribute('language', 'javascript');
|
||||
e.setAttribute('type', 'text/javascript');
|
||||
e.setAttribute('src',
|
||||
(('https:' == document.location.protocol) ? 'https://a248.e.akamai.net/chartbeat.download.akamai.com/102508/' : 'http://static.chartbeat.com/') +
|
||||
'js/chartbeat.js');
|
||||
document.body.appendChild(e);
|
||||
};
|
||||
var oldonload = window.onload;
|
||||
window.onload = (typeof window.onload != 'function') ?
|
||||
loadChartbeat : function() { oldonload(); loadChartbeat(); };
|
||||
})();
|
||||
JS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def include_analytics(service, &block)
|
||||
return unless configured?(service)
|
||||
yield block
|
||||
end
|
||||
|
||||
def configured?(service)
|
||||
AppConfig.privacy.send("#{service}_uid").present?
|
||||
end
|
||||
end
|
||||
|
|
@ -52,11 +52,13 @@ module ApplicationHelper
|
|||
def jquery_include_tag
|
||||
buf = []
|
||||
if AppConfig.privacy.jquery_cdn?
|
||||
version = Jquery::Rails::JQUERY_2_VERSION
|
||||
version = Jquery::Rails::JQUERY_3_VERSION
|
||||
buf << [javascript_include_tag("//code.jquery.com/jquery-#{version}.min.js")]
|
||||
buf << [nonced_javascript_tag("!window.jQuery && document.write(unescape('#{j javascript_include_tag('jquery2')}'));")]
|
||||
buf << [
|
||||
nonced_javascript_tag("!window.jQuery && document.write(unescape('#{j javascript_include_tag('jquery3')}'));")
|
||||
]
|
||||
else
|
||||
buf << [javascript_include_tag("jquery2")]
|
||||
buf << [javascript_include_tag("jquery3")]
|
||||
end
|
||||
buf << [javascript_include_tag("jquery_ujs")]
|
||||
buf << [nonced_javascript_tag("jQuery.ajaxSetup({'cache': false});")]
|
||||
|
|
|
|||
|
|
@ -21,16 +21,6 @@ module InterimStreamHackinessHelper
|
|||
end
|
||||
end
|
||||
|
||||
def publisher_hidden_text
|
||||
if params[:prefill].present?
|
||||
params[:prefill]
|
||||
elsif defined?(@stream)
|
||||
@stream.publisher.prefill
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def from_group(post)
|
||||
if defined?(@stream) && params[:controller] == 'multis'
|
||||
@stream.post_from_group(post)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ module MetaDataHelper
|
|||
end
|
||||
|
||||
def default_image_url
|
||||
asset_url "assets/branding/logos/asterisk.png"
|
||||
asset_url("assets/branding/logos/asterisk.png", skip_pipeline: true)
|
||||
end
|
||||
|
||||
def default_author_name
|
||||
|
|
|
|||
|
|
@ -7,25 +7,30 @@ module MobileHelper
|
|||
reshare = Reshare.where(author_id: current_user.person_id,
|
||||
root_guid: absolute_root.guid).first
|
||||
klass = reshare.present? ? "active" : "inactive"
|
||||
link_to "", reshares_path(root_guid: absolute_root.guid),
|
||||
link_to content_tag(:span, post.reshares.size, class: "count reshare-count"),
|
||||
reshares_path(root_guid: absolute_root.guid),
|
||||
title: t("reshares.reshare.reshare_confirmation", author: absolute_root.author_name),
|
||||
class: "entypo-reshare reshare-action #{klass}"
|
||||
else
|
||||
content_tag :div, nil, class: "entypo-reshare reshare-action disabled"
|
||||
content_tag :div,
|
||||
content_tag(:span, post.reshares.size, class: "count reshare-count"),
|
||||
class: "entypo-reshare reshare-action disabled"
|
||||
end
|
||||
else
|
||||
content_tag :div, nil, class: "entypo-reshare reshare-action disabled"
|
||||
content_tag :div,
|
||||
content_tag(:span, post.reshares.size, class: "count reshare-count"),
|
||||
class: "entypo-reshare reshare-action disabled"
|
||||
end
|
||||
end
|
||||
|
||||
def mobile_like_icon(post)
|
||||
if current_user && current_user.liked?(post)
|
||||
link_to "",
|
||||
link_to content_tag(:span, post.likes.size, class: "count like-count"),
|
||||
"#",
|
||||
data: {url: post_like_path(post.id, current_user.like_for(post).id)},
|
||||
class: "entypo-heart like-action active"
|
||||
else
|
||||
link_to "",
|
||||
link_to content_tag(:span, post.likes.size, class: "count like-count"),
|
||||
"#",
|
||||
data: {url: post_likes_path(post.id)},
|
||||
class: "entypo-heart like-action inactive"
|
||||
|
|
@ -33,7 +38,9 @@ module MobileHelper
|
|||
end
|
||||
|
||||
def mobile_comment_icon(post)
|
||||
link_to "", new_post_comment_path(post), class: "entypo-comment comment-action inactive"
|
||||
link_to content_tag(:span, post.comments.size, class: "count comment-count"),
|
||||
new_post_comment_path(post),
|
||||
class: "entypo-comment comment-action inactive"
|
||||
end
|
||||
|
||||
def show_comments_link(post, klass="")
|
||||
|
|
@ -43,15 +50,12 @@ module MobileHelper
|
|||
entypo_class = "entypo-chevron-down"
|
||||
end
|
||||
|
||||
if post.comments_count > 0
|
||||
link_to "#{t('admins.stats.comments', count: post.comments_count)}<i class='#{entypo_class}'></i>".html_safe,
|
||||
post_comments_path(post, format: "mobile"),
|
||||
class: "show-comments #{klass}"
|
||||
else
|
||||
html = "<span class='show-comments'>"
|
||||
html << t("admins.stats.comments", count: post.comments_count)
|
||||
html << "</span>"
|
||||
end
|
||||
link_to safe_join([
|
||||
t("admins.stats.comments", count: post.comments_count),
|
||||
content_tag(:i, nil, class: entypo_class)
|
||||
]),
|
||||
post_comments_path(post, format: "mobile"),
|
||||
class: "show-comments #{klass}"
|
||||
end
|
||||
|
||||
def additional_photos
|
||||
|
|
|
|||
|
|
@ -2,42 +2,46 @@ module NotificationsHelper
|
|||
include PeopleHelper
|
||||
include PostsHelper
|
||||
|
||||
def object_link(note, actors)
|
||||
def object_link(note, actors_html)
|
||||
target_type = note.popup_translation_key
|
||||
actors_count = note.actors.size
|
||||
opts = {actors: actors_html, count: note.actors.size}
|
||||
|
||||
if note.instance_of?(Notifications::Mentioned)
|
||||
if post = note.linked_object
|
||||
translation(target_type,
|
||||
actors: actors,
|
||||
count: actors_count,
|
||||
post_link: link_to(post_page_title(post), post_path(post)).html_safe)
|
||||
else
|
||||
t(note.deleted_translation_key, :actors => actors, :count => actors_count).html_safe
|
||||
if note.respond_to?(:linked_object)
|
||||
if note.linked_object.nil? && note.respond_to?(:deleted_translation_key)
|
||||
target_type = note.deleted_translation_key
|
||||
elsif note.is_a?(Notifications::Mentioned)
|
||||
opts.merge!(opts_for_mentioned(note.linked_object))
|
||||
elsif %w(Notifications::CommentOnPost Notifications::AlsoCommented Notifications::Reshared Notifications::Liked)
|
||||
.include?(note.type)
|
||||
opts.merge!(opts_for_post(note.linked_object))
|
||||
end
|
||||
elsif note.instance_of?(Notifications::CommentOnPost) || note.instance_of?(Notifications::AlsoCommented) || note.instance_of?(Notifications::Reshared) || note.instance_of?(Notifications::Liked)
|
||||
if post = note.linked_object
|
||||
translation(target_type,
|
||||
actors: actors,
|
||||
count: actors_count,
|
||||
post_author: h(post.author_name),
|
||||
post_link: link_to(post_page_title(post),
|
||||
post_path(post),
|
||||
data: {ref: post.id},
|
||||
class: "hard_object_link").html_safe)
|
||||
else
|
||||
t(note.deleted_translation_key, :actors => actors, :count => actors_count).html_safe
|
||||
end
|
||||
else #Notifications:StartedSharing, etc.
|
||||
translation(target_type, :actors => actors, :count => actors_count)
|
||||
end
|
||||
translation(target_type, opts)
|
||||
end
|
||||
|
||||
def translation(target_type, opts = {})
|
||||
{:post_author => nil}.merge!(opts)
|
||||
t("#{target_type}", opts).html_safe
|
||||
end
|
||||
|
||||
def opts_for_post(post)
|
||||
{
|
||||
post_author: html_escape(post.author_name),
|
||||
post_link: link_to(post_page_title(post),
|
||||
post_path(post),
|
||||
data: {ref: post.id},
|
||||
class: "hard_object_link").html_safe
|
||||
}
|
||||
end
|
||||
|
||||
def opts_for_mentioned(mentioned)
|
||||
post = mentioned.instance_of?(Comment) ? mentioned.parent : mentioned
|
||||
{
|
||||
post_link: link_to(post_page_title(post), post_path(post)).html_safe
|
||||
}.tap {|opts|
|
||||
opts[:comment_path] = post_path(post, anchor: mentioned.guid).html_safe if mentioned.instance_of?(Comment)
|
||||
}
|
||||
end
|
||||
|
||||
def notification_people_link(note, people=nil)
|
||||
actors =people || note.actors
|
||||
number_of_actors = actors.size
|
||||
|
|
|
|||
|
|
@ -31,13 +31,13 @@ module UsersHelper
|
|||
# specified from AVAILABLE_COLOR_THEMES in
|
||||
# config/initializers/color_themes.rb.
|
||||
#
|
||||
# @example if AVAILABLE_COLOR_THEMES = {"original"=>"Original dark", "dark_green" => "Dark green"}
|
||||
# @example if AVAILABLE_COLOR_THEMES = ["original", "dark_green"]
|
||||
# available_color_themes
|
||||
# #=> [["Original dark", "original"], ["Dark green", "dark_green"]]
|
||||
# #=> [["Original gray", "original"], ["Dark green", "dark_green"]]
|
||||
def available_color_themes
|
||||
opts = []
|
||||
AVAILABLE_COLOR_THEMES.map do |theme_code, theme_name|
|
||||
opts << [theme_name, theme_code]
|
||||
AVAILABLE_COLOR_THEMES.map do |theme_code|
|
||||
opts << [I18n.t("color_themes.#{theme_code}"), theme_code]
|
||||
end
|
||||
opts
|
||||
end
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue