Feature requests

That’s out of goofy’s hands. I need to spend a little more time investigating what can be easily configured for tweet displays, but from what I’ve seen so far it’s going to be less than what some are hoping for.

I think most times I’ve seen tweets embedded in websites or news articles it has also been with a static number of tweets/replies.

Can you make the Trump Bot less racist plz, tia.

1 Like

afaik goofy has no control over anything like that. I think the bots just post a tweet link and the forum software handles the rest. Tweet formatting is deeply buried in Ruby so there’s not much we can do unless somebody wants to start coding up a plugin.

Can you move it up with a CSS transform? Something like
transform: translateY(-10px);

Wait, no. Those pastebin links are added by the bots? Maybe that is a goofy issue.

Why doesn’t the most recently posted in thread show up at the top of the links on the front page? Is there a way to make that a sitewide change?

As far as I know it does, although I haven’t really stared at the main forum page to be sure. Let me do that before posting, actually.

EDIT: You’re right, the main page doesn’t auto refresh, or it does but takes a while as zikzak says.

They do, but it can take up to 15 minutes. I’ve tried to find a way to make it instantaneous and failed.

Well then it’s nice to know that I wasn’t being completely silly F5ing the main page, it’s a tough habit to break.

What do they think we live in just one thread? Jeez. ;)

Observation: Without subcategories it isn’t immediately obvious that there is somewhere on the front page to click to see all the threads in a category rather than just the top ten listed.

All the other Discourse sites fill up the left side of the front page by having shit tons of categories. Either that or it’s just a jumble of everything with latest or top or whatever. Nobody uses the boxes because they’re beyond ugly.

Yes, and yes.

Something like this seems to be the most common approach:

Here’s a “damn the categories, just list everything” approach:

I don’t really like either or think they work for us. But our current setup has an awful lot of dead real estate and non-obvious navigation.

I think it’s going to be fairly involved project and I’m mostly just thinking out loud. It might be a good thing to look at as a longer term goal rather than something we try to implement right away.

Most of the stuff seems to in /lib/twitter_api.rb, I think?

# frozen_string_literal: true

# lightweight Twitter api calls
class TwitterApi

  class << self
    include ActionView::Helpers::NumberHelper

    def prettify_tweet(tweet)
      text = tweet["full_text"].dup
      if (entities = tweet["entities"]) && (urls = entities["urls"])
        urls.each do |url|
          text.gsub!(url["url"], "<a target='_blank' href='#{url["expanded_url"]}'>#{url["display_url"]}</a>")
        end
      end

      text = link_hashtags_in link_handles_in text

      result = Rinku.auto_link(text, :all, 'target="_blank"').to_s

      if tweet['extended_entities'] && media = tweet['extended_entities']['media']
        media.each do |m|
          if m['type'] == 'photo'
            if large = m['sizes']['large']
              result << "<div class='tweet-images'><img class='tweet-image' src='#{m['media_url_https']}' width='#{large['w']}' height='#{large['h']}'></div>"
            end
          elsif m['type'] == 'video'
            if large = m['sizes']['large']
              result << "<div class='tweet-images'><iframe class='tweet-video' src='https://twitter.com/i/videos/#{tweet['id_str']}' width='#{large['w']}' height='#{large['h']}' frameborder='0' allowfullscreen></iframe></div>"
            end
          end
        end
      end

      result
    end

    def prettify_number(count)
      number_to_human(count, format: '%n%u', precision: 2, units: { thousand: 'K', million: 'M', billion: 'B' })
    end

    def user_timeline(screen_name)
      JSON.parse(twitter_get(user_timeline_uri_for screen_name))
    end

    def tweet_for(id)
      JSON.parse(twitter_get(tweet_uri_for id))
    end

    alias_method :status, :tweet_for

    def raw_tweet_for(id)
      twitter_get(tweet_uri_for id)
    end

    def twitter_credentials_missing?
      consumer_key.blank? || consumer_secret.blank?
    end

    protected

    def link_handles_in(text)
      text.scan(/(?:^|\s)@(\w+)/).flatten.uniq.each do |handle|
        text.gsub!(/(?:^|\s)@#{handle}/, [
          " <a href='https://twitter.com/#{handle}' target='_blank'>",
            "@#{handle}",
          "</a>"
        ].join)
      end

      text.strip
    end

    def link_hashtags_in(text)
      text.scan(/(?:^|\s)#(\w+)/).flatten.uniq.each do |hashtag|
        text.gsub!(/(?:^|\s)##{hashtag}/, [
          " <a href='https://twitter.com/search?q=%23#{hashtag}' ",
          "target='_blank'>",
            "##{hashtag}",
          "</a>"
        ].join)
      end

      text.strip
    end

    def user_timeline_uri_for(screen_name)
      URI.parse "#{BASE_URL}/1.1/statuses/user_timeline.json?screen_name=#{screen_name}&count=50&include_rts=false&exclude_replies=true"
    end

    def tweet_uri_for(id)
      URI.parse "#{BASE_URL}/1.1/statuses/show.json?id=#{id}&tweet_mode=extended"
    end

    unless defined? BASE_URL
      BASE_URL = 'https://api.twitter.com'.freeze
    end

    def twitter_get(uri)
      request = Net::HTTP::Get.new(uri)
      request.add_field 'Authorization', "Bearer #{bearer_token}"
      http(uri).request(request).body
    end

    def authorization
      request = Net::HTTP::Post.new(auth_uri)

      request.add_field 'Authorization',
        "Basic #{bearer_token_credentials}"
      request.add_field 'Content-Type',
        'application/x-www-form-urlencoded;charset=UTF-8'

      request.set_form_data 'grant_type' => 'client_credentials'

      http(auth_uri).request(request).body
    end

    def bearer_token
      @access_token ||= JSON.parse(authorization).fetch('access_token')
    end

    def bearer_token_credentials
      Base64.strict_encode64(
        "#{URI::encode(consumer_key)}:#{URI::encode(consumer_secret)}"
      )
    end

    def auth_uri
      URI.parse "#{BASE_URL}/oauth2/token"
    end

    def http(uri)
      Net::HTTP.new(uri.host, uri.port).tap { |http| http.use_ssl = true }
    end

    def consumer_key
      SiteSetting.twitter_consumer_key
    end

    def consumer_secret
      SiteSetting.twitter_consumer_secret
    end

  end
end

But changing that means either writing a plugin or maintaining forked code, and forking the code seems like a bad idea to me. Discourse pushes major updates pretty frequently and they recommend doing a full docker container update every 2 months, which will wipe out any changes we make.

fwiw, these tweet issues seem pretty minor to me.

Just, like, my opinion.

1 Like

Request: Zikzak should have a Thin Man avatar again.

1 Like

3 Likes

I don’t know how you all do this but I recommend threads automatically go to the last post instead of the first post in the thread or it’s completely unusable for me. (for many of you getting rid of me is a feature but right now I think it’s 100% trash just from this and I know a lot of you spent a lot of time and effort on this) I don’t want to scroll through an entire thread every time I open it.

Are you reading the site logged in?

Regarding that picture:

Is there a reason some of the lines of text are running together a little bit? I’ve been seeing this on some posts here and I don’t know why this is happening. I didn’t notice this until today, so I think it’s a recent development.