本記事は 駆け出しエンジニアの第一歩!AdventCalendar2020 7日目の記事です。
作りたいもの
下図のように、自分のメッセージと自分以外のメッセージでユーザーアイコンの位置や吹き出しの向きが変わるチャット機能を作ります。
前提条件
- チャット機能自体はできている
- bootstrap4がインストールされている
やることまとめ
- 自分用の吹き出しと相手用の吹き出しのCSSクラスを用意する
- Viewファイルにて、メッセージごとに自分or自分以外のメッセージかを判定する
- それぞれの判定ごとに適用するCSSクラスを変える
1.自分用の吹き出しと相手用の吹き出しのCSSクラスを用意する
吹き出しの枠をデザインするCSSクラスを作成します。
自分のメッセージの場合、吹き出しの尻尾が左側に来るように、
自分以外のメッセージの場合、吹き出しの尻尾が右側に来るようにします。
// 自分のメッセージの吹き出し
.says {
float: left;
position: relative;
width: calc(100% - 56px);
padding: 16px;
background: #ffffff;
border-radius: 15px;
line-height: 1.5;
word-break: break-all;
}
.says:after {
content: "";
display: inline-block;
position: absolute;
top: 3px;
left: -19px;
border: 8px solid transparent;
border-right: 18px solid #ffffff;
-webkit-transform: rotate(35deg);
transform: rotate(35deg);
}
// 自分以外のメッセージの吹き出し
.other-user-says {
float: right;
position: relative;
width: calc(100% - 56px);
padding: 16px;
background: #ffffff;
border-radius: 15px;
line-height: 1.5;
word-break: break-all;
}
.other-user-says:after {
content: "";
display: inline-block;
position: absolute;
top: 3px;
right: -19px;
border: 8px solid transparent;
border-right: 18px solid #ffffff;
-webkit-transform: rotate(145deg);
transform: rotate(145deg);
}
2.Viewファイルにて、メッセージごとに自分or自分以外のメッセージかを判定する
each文でmessageを全て読み込んだ後、メッセージごとに紐づいているユーザーが自分か自分以外かをif文で判定します。
この後、判定結果に応じて、適用する吹き出しのCSSクラスを変えていきます。
message.html.erb
<% messages.each do |m| %>
<!-- 自分のメッセージの場合 -->
<% if m.user == current_user %>
<!-- 自分以外のメッセージの場合 -->
<% else %>
<% end %>
<% end %>
3. それぞれの判定ごとに適用するCSSクラスを変える
自分のメッセージの場合、自分用の吹き出しのCSSクラスを適用し、
自分以外のメッセージの場合、自分以外用の吹き出しのCSSクラスを適用するようにします。
message.html.erb
<% messages.each do |m| %>
<!-- 自分のメッセージの場合 -->
<% if m.user == current_user %>
<tr class="row justify-content-center">
<!-- アイコンを左側に表示する -->
<td class="col-2">
<%= link_to attachment_image_tag(m.user, :image, :fill, 80, 80, fallback: "noimage.png", size:'80x80', class:"profile-image align-top"), user_path(m.user) %>
</td>
<!-- メッセージを右側に表示する -->
<td class="col-10">
<%= m.user.display_name %> <br>
<!-- 自分用の吹き出しCSSクラスを適用する -->
<div class="says">
<p><%= safe_join(m.content.split("\n"),tag(:br)) %></p>
<span><%= l m.created_at %></span>
</div>
</td>
</tr>
<!-- 自分以外のメッセージの場合 -->
<% else %>
<tr class="row justify-content-center">
<!-- メッセージを左側に表示する -->
<td class="col-10">
<div class="col-11 float-right">
<%= m.user.display_name %> <br>
</div>
<!-- 自分以外用の吹き出しCSSクラスを適用する -->
<div class="other-user-says">
<p><%= safe_join(m.content.split("\n"),tag(:br)) %></p>
<span><%= l m.created_at %></span>
</div>
</td>
<!-- アイコンを右側に表示する -->
<td class="col-2">
<%= link_to attachment_image_tag(m.user, :image, :fill, 80, 80, fallback: "noimage.png", size:'80x80', class:"profile-image align-top"), user_path(m.user) %>
</td>
</tr>
<% end %>
<% end %>
終わりに
今回は私個人のアプリで実際に実装したものを題材にしたので、人によってはビューの書き方は異なってくると思います!
ご参考になれば幸いです…!