feature/share-libs
rb 374 lines 10.1 KB
Raw
1 # frozen_string_literal: true
2
3 # Fix this later
4 # rubocop:disable Metrics/ClassLength
5 class UsersController < ApplicationController
6 def initialize
7 @youtube_likes_export_count = 0
8 super
9 end
10
11 def index
12 redirect_to community_path
13 end
14
15 def youtube_likes_export_max_iteration
16 # If development, set to 2, else 10.
17 Rails.env.development? ? 2 : 10
18 end
19
20 def community
21 @users = User.all.paginate(page: params[:page], per_page: 12)
22 @page_title = t('our_community')
23 meta_tags('community')
24 end
25
26 def show_reputation
27 verify_username_or_id
28
29 redirect_to users_path unless @user
30 end
31
32 def friends
33 verify_username_or_id
34 return redirect_to users_path unless @user
35 end
36
37 def followers
38 redirect_to signup_path if params[:id] == 'sign_up'
39 redirect_to login_path if params[:id] == 'sign_in'
40
41 verify_username_or_id
42
43 return redirect_to users_path unless @user
44
45 if !@user.nil? && @user.username == 'splitfire'
46 # If it's splitfire page, set cookies to connect to actioncable.
47 cookies.permanent.signed[:splitfire_user_id] = @user.id
48 end
49
50 meta_tags('profile')
51 end
52
53 def following
54 redirect_to signup_path if params[:id] == 'sign_up'
55 redirect_to login_path if params[:id] == 'sign_in'
56
57 verify_username_or_id
58
59 return redirect_to users_path unless @user
60
61 if !@user.nil? && @user.username == 'splitfire'
62 # If it's splitfire page, set cookies to connect to actioncable.
63 cookies.permanent.signed[:splitfire_user_id] = @user.id
64 end
65
66 meta_tags('profile')
67 end
68
69 def show
70 redirect_to signup_path if params[:id] == 'sign_up'
71 redirect_to login_path if params[:id] == 'sign_in'
72
73 verify_username_or_id
74 return redirect_to users_path unless @user
75
76 @show_comment_form = @user.id != current_user&.id
77 meta_tags('profile')
78 end
79
80 def new
81 redirect_to profile_path(current_user.username_or_id) if user_signed_in?
82
83 meta_tags('signup')
84 @user = User.new(name: params[:name], email: params[:email])
85 @prefilled = params[:email].nil? == false
86 @provider = params[:provider]
87 @provider_name = @provider == 'spotify' ? 'Spotify' : 'YouTube'
88
89 # Remember locale for omniauth
90 session[:omniauth_session_locale] = I18n.locale
91 end
92
93 def onboarding
94 protect_onboarding_paths
95
96 session[:omniauth_session_locale] = I18n.locale
97 @user = current_user
98 session[:onboarding_provider] = @user.provider
99 meta_tags('onboarding')
100 end
101
102 def onboarding_action
103 protect_onboarding_paths
104 compute_next_step
105 render json: { code: 200, next_step: @next_step }
106 end
107
108 def username_check
109 # Find username
110 username = params[:u]
111
112 validate_username username
113
114 render json: {
115 'valid': @is_valid,
116 'message': @message
117 }
118 end
119
120 def username
121 @username = params[:user][:username].downcase
122 current_user.update(username: @username)
123 # See username.js.erb
124 end
125
126 def onboarding_export_spotify
127 return unless user_signed_in?
128
129 SpotifyOnboardingExportJob.perform_now(current_user.id, 'long_term')
130
131 render json: {
132 status: 200
133 }
134 end
135
136 def onboarding_export_youtube
137 return unless user_signed_in?
138
139 onboarding_export_youtube_likes
140 onboarding_export_youtube_playlists
141
142 render json: { status: 200, message: 'Exported.' }
143 end
144
145 def onboarding_export_youtube_likes(page_token = nil)
146 @youtube_likes_export_count += 1
147 client = YoutubeClient.new(current_user.google)
148 response = client.user_likes_videos(page_token)
149 response_json = JSON.parse(response.body)
150
151 export_youtube_videos(response_json['items'], current_user.id)
152
153 if response_json['nextPageToken'].present? && @youtube_likes_export_count < youtube_likes_export_max_iteration
154 onboarding_export_youtube_likes(response_json['nextPageToken'])
155 end
156 end
157
158 def onboarding_export_youtube_playlists
159 client = YoutubeClient.new(current_user.google)
160 client.export_user_playlist
161 end
162
163 def create
164 @user = User.new(user_params)
165 if @user.save
166 # Redirect to login path with email confirmation instruction message
167 flash[:success] = t('welcome_user_unconfirmed')
168 redirect_to login_path
169 else
170 @prefilled = params[:email].nil? == false
171 render 'new'
172 end
173 end
174
175 def settings
176 verify_username_or_id
177 return redirect_to users_path unless @user
178
179 return redirect_to users_path unless @user == current_user
180
181 if !@user.nil? && @user.username == 'splitfire'
182 # If it's splitfire page, set cookies to connect to actioncable.
183 cookies.permanent.signed[:splitfire_user_id] = @user.id
184 end
185
186 meta_tags('profile')
187 end
188
189 def settings_activate_solana
190 verify_username_or_id
191
192 return redirect_to users_path unless @user
193 return redirect_to users_path unless @user == current_user
194
195 create_wallet_if_needed
196 redirect_to settings_path
197 end
198
199 def settings_locale
200 return render json: { result: 'Not signed in' } unless user_signed_in?
201 return render json: { result: 'Locale nil' } unless params[:default_locale]
202
203 user_setting = UserSetting.find_or_create_by(user_id: current_user.id)
204 user_setting.update(locale: params[:default_locale].to_i)
205 render json: { result: true }
206 end
207
208 def update_settings
209 return render json: { code: 500, result: 'Error.' } unless update_settings_valid_request?
210
211 user_setting = UserSetting.find_or_create_by(user_id: current_user.id)
212 user_setting.update_settings(params[:settings][:type], params[:settings][:value])
213
214 render json: {
215 code: 200,
216 user_setting: user_setting.as_json
217 }
218 end
219
220 def update_settings_valid_request?
221 verify_username_or_id
222 return false unless @user
223
224 return false unless @user == current_user
225
226 true
227 end
228
229 # Update from my profile.
230 def update
231 redirect_to root_path unless user_signed_in?
232
233 if params[:user][:username] != 'seto' && params[:user][:username].length < 5
234 flash[:warning] = 'Username minimum 5 characters.'
235 redirect_to my_profile_edit_path
236 return
237 end
238
239 user = User.find_by(id: params[:user][:id])
240 # If no information about the provider and uid, update the them.
241 user.update(
242 name: params[:user][:name],
243 username: params[:user][:username],
244 instagram: params[:user][:instagram],
245 is_private: params[:user][:is_private]
246 )
247
248 redirect_to my_profile_path
249 end
250
251 def edit; end
252
253 def update_resource(resource, params)
254 resource.update_without_password(params)
255 end
256
257 private
258
259 def create_wallet_if_needed
260 create_wallet_solana
261 create_wallet_evm
262 end
263
264 def create_wallet_solana
265 solana_wallet = Wallet.find_by(user_id: @user.id, wallet_type: Wallet.wallet_types[:solana])
266 return unless solana_wallet.nil?
267
268 Wallet.new(user_id: @user.id, wallet_type: Wallet.wallet_types[:solana], status: :pending).save
269 WalletSolanaJob.perform_later(@user.id)
270 end
271
272 def create_wallet_evm
273 evm_wallet = Wallet.find_by(user_id: @user.id, wallet_type: Wallet.wallet_types[:evm])
274 return unless evm_wallet.nil?
275
276 Wallet.new(user_id: @user.id, wallet_type: Wallet.wallet_types[:evm], status: :pending).save
277 WalletEvmJob.perform_later(@user.id)
278 end
279
280 def protect_onboarding_paths
281 return redirect_to root_path unless user_signed_in?
282
283 redirect_to root_path unless current_user.need_onboarding?
284 end
285
286 def user_params
287 params.require(:user).permit(:name, :email, :password, :password_confirmation)
288 end
289
290 def verify_username_or_id
291 @user = User.find_by(username: params[:username])
292 @user ||= User.find_by_id(params[:username])
293
294 @username_string = "@#{@user&.username_or_id}"
295 @username_string += " <i class='bi bi-check-circle-fill'></i>" if @user&.verified?
296 end
297
298 def meta_tags(slug)
299 meta = Meta
300 .select(:title, :description)
301 .where(home: slug, locale: [I18n.locale, I18n.default_locale])
302 .last
303
304 @meta_title = meta.title if meta
305 @meta_description = meta.description if meta
306 end
307
308 def validate_username(username)
309 @is_valid = false
310 if username.length < 4
311 @message = t('username_length_invalid')
312 elsif !username.ascii_only?
313 @message = t('username_character_invalid')
314 elsif username !~ /^[[:alnum:]]+$/
315 @message = t('username_letters_numbers_only')
316 elsif username[0] !~ /[A-Za-z]/
317 @message = t('username_should_starts_with_letters')
318 elsif User.find_by(username: username.downcase).nil? == false
319 @message = t('username_taken')
320 else
321 @is_valid = true
322 @message = t('username_available')
323 end
324 end
325
326 # Onboarding
327
328 def compute_report_complete
329 type = params[:type]
330 case type
331 # This onboarding types are orderly called from the onboarding page
332 when 'username'
333 @next_step = 'spotify' if current_user.need_onboarding_spotify?
334 when 'spotify'
335 current_user.spotify.update(onboarding_status: :onboarded, onboarding_status_progress: 100)
336 @next_step = 'google' if current_user.need_onboarding_google?
337 when 'google'
338 current_user.google.update(onboarding_status: :onboarded, onboarding_status_progress: 100)
339 end
340 end
341
342 def compute_next_step
343 action = params[:onboarding_action]
344 @next_step = 'done'
345 case action
346 # This is get called from the welcome onboarding page to determine the first step
347 when 'next'
348 # Compute next onboarding step
349 if current_user.username.blank?
350 @next_step = 'username'
351 elsif current_user.need_onboarding_spotify?
352 @next_step = 'spotify'
353 elsif current_user.need_onboarding_google?
354 @next_step = 'google'
355 end
356 when 'report_complete'
357 compute_report_complete
358 end
359 end
360
361 def export_youtube_videos(items, user_id)
362 music_videos = items.select { |item| item['snippet']['categoryId'] == '10' }
363 music_videos.each do |video|
364 SongProvider.upsert(
365 { user_id: user_id, provider_type: :youtube, provider_id: video['id'], name: video['snippet']['title'],
366 preview_url: "https://www.youtube.com/watch?v=#{video['id']}", description: video['snippet']['description'],
367 image_url: video['snippet']['thumbnails']['high']['url'] },
368 unique_by: :index_song_providers_on_provider_id_and_provider_type
369 )
370 end
371 end
372
373 # ENDOF Onboarding
374 end