mirror of
https://github.com/Growstuff/growstuff.git
synced 2026-04-11 10:28:45 -04:00
This commit introduces a new feature that allows members to set their location using two methods: a "Find my location" button that uses the browser's Geolocation API, and a Leaflet.js map for manual marker placement. Key changes: - Adds a new `set_location` page for members to update their location. - Integrates a Leaflet.js map for visual location selection. - Implements a "Find my location" button using the browser's Geolocation API. - Uses reverse geocoding to determine a user's suburb/city/town from coordinates. - Enhances privacy by rounding latitude and longitude to two decimal places, reducing location accuracy. - Provides a fallback mechanism for when reverse geocoding fails, storing a generic location string. - Adds comprehensive feature tests for the new functionality.
146 lines
4.0 KiB
Ruby
146 lines
4.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class MembersController < ApplicationController
|
|
load_and_authorize_resource except: %i(finish_signup unsubscribe view_follows view_followers show set_location update_location)
|
|
skip_authorize_resource only: %i(nearby unsubscribe finish_signup)
|
|
respond_to :html, :json, :rss
|
|
|
|
def index
|
|
@sort = params[:sort]
|
|
@members = members
|
|
respond_to do |format|
|
|
format.html # index.html.haml
|
|
format.json { render json: @members.to_json(only: member_json_fields) }
|
|
end
|
|
end
|
|
|
|
def show
|
|
@member = Member.confirmed.kept.find_by!(slug: params[:slug])
|
|
@flickr_auth = @member.auth('flickr')
|
|
@posts = @member.posts
|
|
|
|
@activity = TimelineService.member_query(@member).limit(30)
|
|
|
|
@late = []
|
|
@super_late = []
|
|
@harvesting = []
|
|
@others = []
|
|
|
|
@member.plantings.active.annual.each do |planting|
|
|
if planting.finish_is_predicatable?
|
|
if planting.super_late?
|
|
@super_late << planting
|
|
elsif planting.late?
|
|
@late << planting
|
|
elsif planting.harvest_time?
|
|
@harvesting << planting
|
|
else
|
|
@others << planting
|
|
end
|
|
end
|
|
end
|
|
|
|
@harvests = Harvest.search(
|
|
where: { owner_id: @member.id },
|
|
boost_by: [:created_at],
|
|
limit: 16,
|
|
load: false
|
|
)
|
|
|
|
respond_to do |format|
|
|
format.html # show.html.haml
|
|
format.json { render json: @member.to_json(only: member_json_fields) }
|
|
format.rss do
|
|
render(
|
|
layout: false,
|
|
locals: { member: @member }
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
def unsubscribe
|
|
verifier = ActiveSupport::MessageVerifier.new(ENV.fetch('RAILS_SECRET_TOKEN', nil))
|
|
decrypted_message = verifier.verify(params[:message])
|
|
|
|
@member = Member.find(decrypted_message[:member_id])
|
|
@type = decrypted_message[:type]
|
|
@member.update(@type => false)
|
|
|
|
flash.now[:notice] = I18n.t('members.unsubscribed', email_type: EMAIL_TYPE_STRING[@type])
|
|
rescue ActiveSupport::MessageVerifier::InvalidSignature
|
|
flash.now[:alert] = I18n.t('members.unsubscribe.error')
|
|
end
|
|
|
|
def finish_signup
|
|
@member = current_member
|
|
return unless request.patch? && params[:member]
|
|
|
|
if @member.update(member_params)
|
|
@member.skip_reconfirmation!
|
|
bypass_sign_in(@member)
|
|
redirect_to root_path, notice: I18n.t('members.welcome')
|
|
else
|
|
flash[:alert] = I18n.t('members.signup.error')
|
|
@show_errors = true
|
|
end
|
|
end
|
|
|
|
def set_location
|
|
@member = Member.find_by_slug!(params[:id])
|
|
authorize! :update, @member
|
|
end
|
|
|
|
def update_location
|
|
@member = Member.find_by_slug!(params[:id])
|
|
authorize! :update, @member
|
|
|
|
if params[:member][:latitude].present? && params[:member][:longitude].present?
|
|
lat = params[:member][:latitude].to_f.round(2)
|
|
lng = params[:member][:longitude].to_f.round(2)
|
|
params[:member][:latitude] = lat
|
|
params[:member][:longitude] = lng
|
|
|
|
results = Geocoder.search([lat, lng])
|
|
if results.first
|
|
params[:member][:location] = results.first.city || results.first.town || results.first.village || results.first.hamlet
|
|
else
|
|
params[:member][:location] = "Location near #{lat}, #{lng}"
|
|
end
|
|
end
|
|
|
|
if @member.update(member_params)
|
|
redirect_to member_path(@member), notice: 'Location updated.'
|
|
else
|
|
render :set_location
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
EMAIL_TYPE_STRING = {
|
|
send_notification_email: "direct message notifications",
|
|
send_planting_reminder: "planting reminders"
|
|
}.freeze
|
|
|
|
def member_params
|
|
params.require(:member).permit(:login_name, :tos_agreement, :email, :newsletter, :location, :latitude, :longitude)
|
|
end
|
|
|
|
def member_json_fields
|
|
%i(
|
|
id login_name
|
|
slug bio created_at
|
|
location latitude longitude
|
|
)
|
|
end
|
|
|
|
def members
|
|
if @sort == 'recently_joined'
|
|
Member.recently_joined
|
|
else
|
|
Member.order(:login_name)
|
|
end.kept.confirmed.paginate(page: params[:page])
|
|
end
|
|
end
|