Xwitter 0.2.2 → 0.3.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c3206d5937b3dd8ace31d035f2adf449345238404988dca84161ff08e6a6c92
4
- data.tar.gz: f6e28c151af151500e1a89e8e2c82d7107c44e3e9b0d621ae567e30a7f6ca505
3
+ metadata.gz: f4e6bcb2959064f032dbe69ce723dac00ce897d23ed51c786c094981414b3ed6
4
+ data.tar.gz: 1dc433bc78c1d995df2068e830c42324f25747c4333f439e32f4011788850acc
5
5
  SHA512:
6
- metadata.gz: 9b2ec24637aaa2f548b36cd8f176ae49ca7bfb68615a9ea51e285dba740d694985dcd61c9f0fcb3920584e2bc19946db6c4d66282133a76c9019a729cbb5e2b5
7
- data.tar.gz: 815a2749130be886714347715a2bef9c00cfe28850eb21bbc37592495273919acd9f507dbeaa4e361e42c1c52ec5e1e7f6fa444707c4ec296b230fd78e2cd7d7
6
+ metadata.gz: 3d9dd7529af133847d773bdd7608fe092d938524c0bd8cbd75d25582f11c054e29563a99572ba64c0bacf2c696ced2da47555dac2d6d4b30c178fff91c3a72c9
7
+ data.tar.gz: 0e52ca5e37dd9551378c74158d5311ff480ce65241ff413e0e967998b701d1adcb7a99f945df3dbc6b6fbd88ccf723c550af1a328017c20819d4510ef708c649
data/.gitignore CHANGED
@@ -7,6 +7,7 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  /log/
10
+ /storage/
10
11
  /db/migrate/
11
12
  *.sqlite3
12
13
 
data/Gemfile CHANGED
@@ -5,6 +5,7 @@ ruby '2.5.1'
5
5
 
6
6
  gem 'rails', '~> 5.2.1'
7
7
  gem 'pg', require: false
8
+ gem 'composite_primary_keys'
8
9
 
9
10
  gem 'puma', '~> 3.11'
10
11
  gem 'slim-rails'
data/Gemfile.lock CHANGED
@@ -60,6 +60,8 @@ GEM
60
60
  coffee-script-source
61
61
  execjs
62
62
  coffee-script-source (1.12.2)
63
+ composite_primary_keys (11.1.0)
64
+ activerecord (~> 5.2.1)
63
65
  concurrent-ruby (1.1.3)
64
66
  connection_pool (2.2.2)
65
67
  crass (1.0.4)
@@ -219,6 +221,7 @@ DEPENDENCIES
219
221
  bootsnap (>= 1.1.0)
220
222
  byebug
221
223
  coffee-rails (~> 4.2)
224
+ composite_primary_keys
222
225
  devise (~> 4.5.0)
223
226
  jbuilder (~> 2.5)
224
227
  listen (>= 3.0.5, < 3.2)
data/Schemafile CHANGED
@@ -3,6 +3,7 @@ create_table "users" do |t|
3
3
  t.string "email", null: false
4
4
  t.string "name"
5
5
  t.string "screen_name"
6
+ t.text "description"
6
7
  t.string "encrypted_password", null: false
7
8
  t.string "reset_password_token"
8
9
  t.boolean "public", null: false, default: true
@@ -31,6 +32,14 @@ create_table "messages", force: :cascade do |t|
31
32
  end
32
33
  add_foreign_key "messages", "users"
33
34
 
35
+ create_table "message_topics", force: :cascade, id: false do |t|
36
+ t.string "topic", null: false
37
+ t.bigint "message_id", null: false
38
+ t.index ["topic", "message_id"], unique: true
39
+ t.index ["message_id"]
40
+ end
41
+ add_foreign_key "message_topics", "messages"
42
+
34
43
  create_table "likes", force: :cascade do |t|
35
44
  t.bigint "user_id", null: false
36
45
  t.bigint "message_id", null: false
@@ -49,3 +58,26 @@ add_foreign_key "likes", "users"
49
58
  add_foreign_key "likes", "messages"
50
59
  add_foreign_key "shares", "users"
51
60
  add_foreign_key "shares", "messages"
61
+
62
+ # ActiveStorage
63
+ create_table :active_storage_blobs do |t|
64
+ t.string :key, null: false
65
+ t.string :filename, null: false
66
+ t.string :content_type
67
+ t.text :metadata
68
+ t.bigint :byte_size, null: false
69
+ t.string :checksum, null: false
70
+ t.datetime :created_at, null: false
71
+
72
+ t.index [ :key ], unique: true
73
+ end
74
+
75
+ create_table :active_storage_attachments do |t|
76
+ t.string :name, null: false
77
+ t.references :record, null: false, polymorphic: true, index: false
78
+ t.references :blob, null: false
79
+
80
+ t.datetime :created_at, null: false
81
+
82
+ t.index [ :record_type, :record_id, :name, :blob_id ], name: "index_active_storage_attachments_uniqueness", unique: true
83
+ end
@@ -11,3 +11,30 @@ body.theme-dark {
11
11
  }
12
12
  }
13
13
  }
14
+
15
+ body.theme-leaf {
16
+ color: #162727;
17
+ a { color: #20c728; }
18
+ h1 {
19
+ color: #384b54;
20
+ }
21
+ .timeline {
22
+ .message-item:hover {
23
+ background-color: #dfece7;
24
+ }
25
+ }
26
+ }
27
+
28
+ body.theme-leaf-dark {
29
+ background-color: #224845;
30
+ color: #dce6e6;
31
+ a { color: #20c728; }
32
+ h1 {
33
+ color: #f4f6f7;
34
+ }
35
+ .timeline {
36
+ .message-item:hover {
37
+ background-color: #365f5d;
38
+ }
39
+ }
40
+ }
@@ -45,6 +45,7 @@ class ProfilesController < ApplicationController
45
45
 
46
46
  # Never trust parameters from the scary internet, only allow the white list through.
47
47
  def user_params
48
- params.require(:user).permit(:theme, :name, :screen_name)
48
+ params.require(:user)
49
+ .permit(:name, :screen_name, :description, :profile_image, :theme)
49
50
  end
50
51
  end
@@ -0,0 +1,7 @@
1
+ class TopicsController < ApplicationController
2
+ # GET /users/1
3
+ # GET /users/1.json
4
+ def show
5
+ @messages = Message.topic_of(params[:id])
6
+ end
7
+ end
@@ -1,4 +1,38 @@
1
1
  class Message < ApplicationRecord
2
2
  belongs_to :user
3
+ has_many :message_topics, dependent: :delete_all
3
4
  validates :text, length: { maximum: 140 }
5
+
6
+ after_save :regenerate_topics
7
+
8
+ def self.topic_of(topic)
9
+ Message.joins(:message_topics).where(message_topics: { topic: topic })
10
+ end
11
+
12
+ def split_full
13
+ text.split(/([  ,.、。])/)
14
+ end
15
+
16
+ def split(full: true)
17
+ if full
18
+ text.split(/([  ,.、。])/)
19
+ else
20
+ text.split(/[  ,.、。]/)
21
+ end
22
+ end
23
+
24
+ def topics
25
+ split.uniq.delete_if { |word| !Message.topic?(word) }
26
+ end
27
+
28
+ def self.topic?(word)
29
+ (4..15).cover?(word.length)
30
+ end
31
+
32
+ def regenerate_topics
33
+ MessageTopic.where(message: self).delete_all
34
+ topics.each do |word|
35
+ MessageTopic.create(message: self, topic: word) if Message.topic?(word)
36
+ end
37
+ end
4
38
  end
@@ -0,0 +1,4 @@
1
+ class MessageTopic < ApplicationRecord
2
+ self.primary_keys = [:message_id, :topic]
3
+ belongs_to :message
4
+ end
data/app/models/user.rb CHANGED
@@ -9,6 +9,10 @@ class User < ApplicationRecord
9
9
  has_many :observed, foreign_key: "to_user_id", class_name: "Observe"
10
10
  has_many :observed_users, through: :observed, source: "from_user"
11
11
 
12
+ has_one_attached :profile_image
13
+
14
+ validates :description, length: { maximum: 200 }
15
+
12
16
  def follow?(user)
13
17
  observe_users.include?(user)
14
18
  end
@@ -1,7 +1,13 @@
1
1
  doctype html
2
2
  html
3
3
  head
4
- title Xwitter
4
+ title
5
+ - if @message.try(:persisted?)
6
+ | #{@message.text} #{@message.user.screen_name} (@#{@message.user.name}) | Xwitter
7
+ - elsif @user
8
+ | Xwitter - #{@user.screen_name} (@#{@user.name})
9
+ - else
10
+ | Xwitter
5
11
  = csrf_meta_tags
6
12
  = csp_meta_tag
7
13
  = javascript_include_tag 'application', 'data-turbolinks-track': 'reload'
@@ -9,9 +15,12 @@ html
9
15
  = stylesheet_pack_tag 'application'
10
16
  = stylesheet_link_tag 'application', 'data-turbolinks-track': 'reload'
11
17
  = stylesheet_link_tag 'https://cdnjs.cloudflare.com/ajax/libs/open-iconic/1.1.1/font/css/open-iconic-bootstrap.min.css'
12
- body(class="theme-#{current_user.theme.to_s}")
18
+ body(class="theme-#{current_user.try(:theme)}")
13
19
  .navbar
14
- = link_to '/', root_path
20
+ div
21
+ = link_to '/', root_path, class: 'btn'
22
+ - if @user.try(:persisted?)
23
+ = link_to '@' + @user.name, '/' + @user.name, class: 'btn'
15
24
 
16
25
  .container
17
26
  = yield
@@ -1,14 +1,5 @@
1
1
  .timeline
2
2
  ul
3
- - messages.order("created_at DESC").each do |message|
3
+ - messages.order("created_at DESC").limit(50).each do |message|
4
4
  li.message-item(onclick="Turbolinks.visit('/messages/#{message.id}')")
5
- p
6
- = message.user.screen_name
7
- | &nbsp;
8
- = link_to '@' + message.user.name, '/' + message.user.name
9
-
10
- p= message.text
11
- p= l message.created_at
12
- - if user_signed_in? && message.user == current_user
13
- .oi.oi-trash
14
- = link_to 'Destroy', message, data: { confirm: 'Are you sure?' }, method: :delete
5
+ = render 'messages/show', message: message
@@ -1,11 +1,23 @@
1
- div
1
+ - detail ||= false
2
+ - if detail
3
+ h1
4
+ = message.user.screen_name
5
+ | &nbsp;
6
+ small= link_to '@' + message.user.name, '/' + message.user.name
7
+ - else
2
8
  p
3
9
  = message.user.screen_name
4
10
  | &nbsp;
5
11
  = link_to '@' + message.user.name, '/' + message.user.name
6
12
 
7
- p= message.text
8
- p= l message.created_at
9
- - if user_signed_in? && message.user == current_user
10
- .oi.oi-trash
11
- = link_to 'Destroy', message, data: { confirm: 'Are you sure?' }, method: :delete
13
+ p
14
+ - message.split_full.each do |word|
15
+ - if Message.topic? word
16
+ = link_to word, topic_path(word)
17
+ - else
18
+ = word
19
+
20
+ p= l message.created_at
21
+ - if !detail && user_signed_in? && message.user == current_user
22
+ .oi.oi-trash
23
+ = link_to 'Destroy', message, data: { confirm: 'Are you sure?' }, method: :delete
@@ -0,0 +1,17 @@
1
+ div
2
+ p
3
+ = message.user.screen_name
4
+ | &nbsp;
5
+ = link_to '@' + message.user.name, '/' + message.user.name
6
+
7
+ p
8
+ - message.split_full.each do |word|
9
+ - if Message.topic? word
10
+ = link_to word, topic_path(word)
11
+ - else
12
+ = word
13
+
14
+ p= l message.created_at
15
+ - if user_signed_in? && message.user == current_user
16
+ .oi.oi-trash
17
+ = link_to 'Destroy', message, data: { confirm: 'Are you sure?' }, method: :delete
@@ -1,10 +1,4 @@
1
- h1
2
- = @message.user.screen_name
3
- | &nbsp;
4
- small= link_to "@#{@message.user.name}", '/' + @message.user.name
5
- p= @message.text
6
- p= l @message.created_at
7
-
1
+ = render 'show', message: @message, detail: true
8
2
  - if @message.user == current_user
9
3
  => link_to 'Edit', edit_message_path(@message)
10
4
  '|
@@ -12,7 +12,13 @@
12
12
  .field
13
13
  = f.label :screen_name
14
14
  = f.text_field :screen_name
15
+ .field
16
+ = f.label :description
17
+ = f.text_area :description
18
+ .field
19
+ = f.label :profile_image
20
+ = f.file_field :profile_image
15
21
  .field
16
22
  = f.label :theme
17
- = f.select :theme, %w[dark], include_blank: 'default'
23
+ = f.select :theme, %w[dark leaf], include_blank: 'default'
18
24
  .actions = f.submit
@@ -1,3 +1,4 @@
1
+ = image_tag @user.profile_image.variant(resize: "320x200") if @user.profile_image.attached?
1
2
  h2
2
3
  = @user.screen_name
3
4
  | &nbsp;
@@ -14,6 +15,8 @@ h2
14
15
  - if @user.follow?(current_user)
15
16
  span.badge Followed you
16
17
 
18
+ p= @user.description
19
+
17
20
  = link_to "Followings: #{@observes.count}", follows_path(username: @user.name), class: 'btn'
18
21
  = link_to "Followers: #{@observed.count}", followed_path(username: @user.name), class: 'btn'
19
22
 
@@ -0,0 +1,2 @@
1
+ h1 Topic #{params[:id]}
2
+ = render 'messages/index', messages: @messages
data/config/routes.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  Rails.application.routes.draw do
2
2
  resource :profile
3
3
  resources :messages
4
+ resources :topics, path: 'topic'
4
5
  devise_for :users
5
6
  root 'messages#index'
6
7
  get ':username', to: 'profiles#show'
@@ -1,3 +1,3 @@
1
1
  module Xwitter
2
- VERSION = "0.2.2"
2
+ VERSION = "0.3.0.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: Xwitter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - myun2
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-11-16 00:00:00.000000000 Z
11
+ date: 2018-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -74,6 +74,7 @@ files:
74
74
  - app/controllers/follows_controller.rb
75
75
  - app/controllers/messages_controller.rb
76
76
  - app/controllers/profiles_controller.rb
77
+ - app/controllers/topics_controller.rb
77
78
  - app/helpers/application_helper.rb
78
79
  - app/helpers/messages_helper.rb
79
80
  - app/helpers/users_helper.rb
@@ -88,6 +89,7 @@ files:
88
89
  - app/models/application_record.rb
89
90
  - app/models/concerns/.keep
90
91
  - app/models/message.rb
92
+ - app/models/message_topic.rb
91
93
  - app/models/observe.rb
92
94
  - app/models/user.rb
93
95
  - app/views/follows/followed.html.slim
@@ -99,6 +101,7 @@ files:
99
101
  - app/views/messages/_index.html.slim
100
102
  - app/views/messages/_message.json.jbuilder
101
103
  - app/views/messages/_show.html.slim
104
+ - app/views/messages/_text.html.slim
102
105
  - app/views/messages/edit.html.slim
103
106
  - app/views/messages/index.html.slim
104
107
  - app/views/messages/index.json.jbuilder
@@ -110,6 +113,7 @@ files:
110
113
  - app/views/profiles/edit.html.slim
111
114
  - app/views/profiles/show.html.slim
112
115
  - app/views/profiles/show.json.jbuilder
116
+ - app/views/topics/show.html.slim
113
117
  - app/views/users/confirmations/new.html.erb
114
118
  - app/views/users/mailer/confirmation_instructions.html.erb
115
119
  - app/views/users/mailer/email_changed.html.erb