application_helper.rb 7.31 KB
Newer Older
gitlabhq's avatar
gitlabhq committed
1
require 'digest/md5'
Sergey Linnik's avatar
Sergey Linnik committed
2
require 'uri'
Robert Speicher's avatar
Robert Speicher committed
3

gitlabhq's avatar
gitlabhq committed
4
module ApplicationHelper
5 6
  COLOR_SCHEMES = {
    1 => 'white',
7
    2 => 'dark',
8 9 10 11
    3 => 'solarized-dark',
    4 => 'monokai',
  }
  COLOR_SCHEMES.default = 'white'
12

13 14 15 16 17 18 19 20 21 22 23
  # Helper method to access the COLOR_SCHEMES
  #
  # The keys are the `color_scheme_ids`
  # The values are the `name` of the scheme.
  #
  # The preview images are `name-scheme-preview.png`
  # The stylesheets should use the css class `.name`
  def color_schemes
    COLOR_SCHEMES.freeze
  end

24 25
  # Check if a particular controller is the current one
  #
26 27
  # args - One or more controller names to check
  #
28 29 30
  # Examples
  #
  #   # On TreeController
31 32 33 34 35
  #   current_controller?(:tree)           # => true
  #   current_controller?(:commits)        # => false
  #   current_controller?(:commits, :tree) # => true
  def current_controller?(*args)
    args.any? { |v| v.to_s.downcase == controller.controller_name }
36 37
  end

Johannes Schleifenbaum's avatar
Johannes Schleifenbaum committed
38
  # Check if a particular action is the current one
Robert Speicher's avatar
Robert Speicher committed
39 40 41 42 43 44 45 46 47 48 49 50 51
  #
  # args - One or more action names to check
  #
  # Examples
  #
  #   # On Projects#new
  #   current_action?(:new)           # => true
  #   current_action?(:create)        # => false
  #   current_action?(:new, :create)  # => true
  def current_action?(*args)
    args.any? { |v| v.to_s.downcase == action_name }
  end

Steven Thonus's avatar
Steven Thonus committed
52 53 54 55 56
  def group_icon(group_path)
    group = Group.find_by(path: group_path)
    if group && group.avatar.present?
      group.avatar.url
    else
57
      image_path('no_group_avatar.png')
Steven Thonus's avatar
Steven Thonus committed
58 59 60
    end
  end

61
  def avatar_icon(user_email = '', size = nil)
skv's avatar
skv committed
62
    user = User.find_by(email: user_email)
63 64 65

    if user
      user.avatar_url(size) || default_avatar
66 67 68 69 70
    else
      gravatar_icon(user_email, size)
    end
  end

71
  def gravatar_icon(user_email = '', size = nil)
72 73 74
    GravatarService.new.execute(user_email, size) ||
      default_avatar
  end
75

76 77
  def default_avatar
    image_path('no_avatar.png')
gitlabhq's avatar
gitlabhq committed
78 79 80
  end

  def last_commit(project)
Nihad Abbasov's avatar
Nihad Abbasov committed
81
    if project.repo_exists?
82
      time_ago_with_tooltip(project.repository.commit.committed_date)
Nihad Abbasov's avatar
Nihad Abbasov committed
83
    else
gitlabhq's avatar
gitlabhq committed
84 85
      "Never"
    end
86
  rescue
gitlabhq's avatar
gitlabhq committed
87
    "Never"
gitlabhq's avatar
gitlabhq committed
88 89
  end

90
  def grouped_options_refs
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
91 92
    repository = @project.repository

gitlabhq's avatar
gitlabhq committed
93
    options = [
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
94
      ["Branches", repository.branch_names],
Robert Speicher's avatar
Robert Speicher committed
95
      ["Tags", VersionSorter.rsort(repository.tag_names)]
gitlabhq's avatar
gitlabhq committed
96 97
    ]

98
    # If reference is commit id - we should add it to branch/tag selectbox
99
    if(@ref && !options.flatten.include?(@ref) &&
100 101 102 103
       @ref =~ /^[0-9a-zA-Z]{6,52}$/)
      options << ["Commit", [@ref]]
    end

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
104
    grouped_options_for_select(options, @ref || @project.default_branch)
gitlabhq's avatar
gitlabhq committed
105 106
  end

107 108 109
  def emoji_autocomplete_source
    # should be an array of strings
    # so to_s can be called, because it is sufficient and to_json is too slow
Riyad Preukschas's avatar
Riyad Preukschas committed
110
    Emoji.names.to_s
111 112
  end

113
  def app_theme
114
    Gitlab::Theme.css_class_by_id(current_user.try(:theme_id))
Drew Blessing's avatar
Drew Blessing committed
115 116 117 118
  end

  def theme_type
    Gitlab::Theme.type_css_class_by_id(current_user.try(:theme_id))
119
  end
randx's avatar
randx committed
120

121
  def user_color_scheme_class
122
    COLOR_SCHEMES[current_user.try(:color_scheme_id)] if defined?(current_user)
123 124
  end

125 126
  # Define whenever show last push event
  # with suggestion to create MR
randx's avatar
randx committed
127
  def show_last_push_widget?(event)
128 129 130 131 132 133 134 135 136 137 138
    # Skip if event is not about added or modified non-master branch
    return false unless event && event.last_push_to_non_root? && !event.rm_ref?

    project = event.project

    # Skip if project repo is empty or MR disabled
    return false unless project && !project.empty_repo? && project.merge_requests_enabled

    # Skip if user already created appropriate MR
    return false if project.merge_requests.where(source_branch: event.branch_name).opened.any?

139 140 141
    # Skip if user removed branch right after that
    return false unless project.repository.branch_names.include?(event.branch_name)

142
    true
randx's avatar
randx committed
143
  end
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
144

145 146 147
  def hexdigest(string)
    Digest::SHA1.hexdigest string
  end
148

Florian Unglaub's avatar
Florian Unglaub committed
149
  def authbutton(provider, size = 64)
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
150
    file_name = "#{provider.to_s.split('_').first}_#{size}.png"
151
    image_tag(image_path("authbuttons/#{file_name}"), alt: "Sign in with #{provider.to_s.titleize}")
Florian Unglaub's avatar
Florian Unglaub committed
152
  end
153

154
  def simple_sanitize(str)
155 156 157
    sanitize(str, tags: %w(a span))
  end

158

159
  def body_data_page
160 161 162 163
    path = controller.controller_path.split('/')
    namespace = path.first if path.second

    [namespace, controller.controller_name, controller.action_name].compact.join(":")
164
  end
165 166 167 168 169 170 171 172 173 174

  # shortcut for gitlab config
  def gitlab_config
    Gitlab.config.gitlab
  end

  # shortcut for gitlab extra config
  def extra_config
    Gitlab.config.extra
  end
175

176 177 178
  def search_placeholder
    if @project && @project.persisted?
      "Search in this project"
179
    elsif @snippet || @snippets || @show_snippets
180
      'Search snippets'
181 182 183 184 185
    elsif @group && @group.persisted?
      "Search in this group"
    else
      "Search"
    end
186
  end
187 188 189 190

  def broadcast_message
    BroadcastMessage.current
  end
191 192 193 194

  def highlight_js(&block)
    string = capture(&block)

195 196 197 198 199 200 201 202
    content_tag :div, class: "highlighted-data #{user_color_scheme_class}" do
      content_tag :div, class: 'highlight' do
        content_tag :pre do
          content_tag :code do
            string.html_safe
          end
        end
      end
203 204
    end
  end
205 206 207

  def time_ago_with_tooltip(date, placement = 'top', html_class = 'time_ago')
    capture_haml do
208 209
      haml_tag :time, date.to_s,
        class: html_class, datetime: date.getutc.iso8601, title: date.stamp("Aug 21, 2011 9:23pm"),
210 211
        data: { toggle: 'tooltip', placement: placement }

212
      haml_tag :script, "$('." + html_class + "').timeago().tooltip()"
213 214
    end.html_safe
  end
215 216

  def render_markup(file_name, file_content)
217 218
    GitHub::Markup.render(file_name, file_content).
      force_encoding(file_content.encoding).html_safe
219 220
  rescue RuntimeError
    simple_format(file_content)
221
  end
222

223 224 225 226 227 228 229 230
  def markup?(filename)
    Gitlab::MarkdownHelper.markup?(filename)
  end

  def gitlab_markdown?(filename)
    Gitlab::MarkdownHelper.gitlab_markdown?(filename)
  end

231 232 233 234 235
  def spinner(text = nil, visible = false)
    css_class = "loading"
    css_class << " hide" unless visible

    content_tag :div, class: css_class do
236
      content_tag(:i, nil, class: 'fa fa-spinner fa-spin') + text
237 238
    end
  end
239 240

  def link_to(name = nil, options = nil, html_options = nil, &block)
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
    begin
      uri = URI(options)
      host = uri.host
      absolute_uri = uri.absolute?
    rescue URI::InvalidURIError, ArgumentError
      host = nil
      absolute_uri = nil
    end

    # Add "nofollow" only to external links
    if host && host != Gitlab.config.gitlab.host && absolute_uri
      if html_options
        if html_options[:rel]
          html_options[:rel] << " nofollow"
        else
          html_options.merge!(rel: "nofollow")
        end
258
      else
259 260
        html_options = Hash.new
        html_options[:rel] = "nofollow"
261 262
      end
    end
263

264 265
    super
  end
266 267 268 269

  def escaped_autolink(text)
    auto_link ERB::Util.html_escape(text), link: :urls
  end
270 271 272 273 274 275 276 277

  def promo_host
    'about.gitlab.com'
  end

  def promo_url
    'https://' + promo_host
  end
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295

  def page_filter_path(options={})
    exist_opts = {
      state: params[:state],
      scope: params[:scope],
      label_name: params[:label_name],
      milestone_id: params[:milestone_id],
      assignee_id: params[:assignee_id],
      author_id: params[:author_id],
      sort: params[:sort],
    }

    options = exist_opts.merge(options)

    path = request.path
    path << "?#{options.to_param}"
    path
  end
296 297 298 299

  def outdated_browser?
    browser.ie? && browser.version.to_i < 10
  end
gitlabhq's avatar
gitlabhq committed
300
end