Conflicts:
	app/views/welcome/_search_project.html.erb
	config/locales/en.yml
	config/locales/zh.yml
memcached_alan
whimlex 10 years ago
commit 22aae1910b

@ -91,10 +91,6 @@ GEM
descendants_tracker (0.0.4) descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1) thread_safe (~> 0.3, >= 0.3.1)
diff-lcs (1.2.5) diff-lcs (1.2.5)
dnsruby (1.57.0)
email_verifier (0.0.7)
dnsruby (>= 1.5)
rails (>= 3.0.0)
equalizer (0.0.9) equalizer (0.0.9)
erubis (2.7.0) erubis (2.7.0)
execjs (2.2.1) execjs (2.2.1)
@ -170,7 +166,6 @@ GEM
mysql2 (0.3.11-x86-mingw32) mysql2 (0.3.11-x86-mingw32)
nenv (0.2.0) nenv (0.2.0)
net-ldap (0.3.1) net-ldap (0.3.1)
newrelic_rpm (3.9.9.275)
nokogiri (1.6.3) nokogiri (1.6.3)
mini_portile (= 0.6.0) mini_portile (= 0.6.0)
nokogiri (1.6.3-x86-mingw32) nokogiri (1.6.3-x86-mingw32)
@ -320,7 +315,6 @@ DEPENDENCIES
capybara (~> 2.4.1) capybara (~> 2.4.1)
coderay (~> 1.0.6) coderay (~> 1.0.6)
coffee-rails (~> 3.2.1) coffee-rails (~> 3.2.1)
email_verifier
factory_girl (~> 4.4.0) factory_girl (~> 4.4.0)
faker faker
fastercsv (~> 1.5.0) fastercsv (~> 1.5.0)
@ -336,7 +330,6 @@ DEPENDENCIES
mocha (~> 1.1.0) mocha (~> 1.1.0)
mysql2 (= 0.3.11) mysql2 (= 0.3.11)
net-ldap (~> 0.3.1) net-ldap (~> 0.3.1)
newrelic_rpm
nokogiri (~> 1.6.3) nokogiri (~> 1.6.3)
paperclip (~> 3.5.4) paperclip (~> 3.5.4)
rack-mini-profiler! rack-mini-profiler!

@ -6,6 +6,7 @@ module Mobile
require_relative 'apis/watches' require_relative 'apis/watches'
require_relative 'apis/upgrade' require_relative 'apis/upgrade'
require_relative 'apis/homeworks' require_relative 'apis/homeworks'
require_relative 'apis/comments'
class API < Grape::API class API < Grape::API
version 'v1', using: :path version 'v1', using: :path
format :json format :json
@ -37,6 +38,7 @@ module Mobile
mount Apis::Watches mount Apis::Watches
mount Apis::Upgrade mount Apis::Upgrade
mount Apis::Homeworks mount Apis::Homeworks
mount Apis::Comments
#add_swagger_documentation ({api_version: 'v1', base_path: 'http://u06.shellinfo.cn/trustie/api'}) #add_swagger_documentation ({api_version: 'v1', base_path: 'http://u06.shellinfo.cn/trustie/api'})
#add_swagger_documentation ({api_version: 'v1', base_path: '/api'}) if Rails.env.development? #add_swagger_documentation ({api_version: 'v1', base_path: '/api'}) if Rails.env.development?

@ -0,0 +1,79 @@
#coding=utf-8
module Mobile
module Apis
class Comments < Grape::API
resource :comments do
desc '课程通知评论'
params do
requires :token, type: String
requires :comments, type: String
end
post ':id' do
cs = CommentService.new
cs_params = {
id: params[:id],
comment: params.reject{|k,v| [:id].include?(k)}}
comments = cs.news_comments cs_params,current_user
raise "create comments failed #{comments.errors.full_messages}" if comments.new_record?
present :data, comments, with: Mobile::Entities::Comment
present :status, 0
end
desc '作业留言(教师布置的作业)'
params do
requires :token, type: String
requires :message,type: String, desc: '留言'
#optional :reference_content, type: String ,desc: '引用的内容'
#optional :reference_user_id, type: Integer,desc: '被引用的人'
end
post ':id/create_homework_message' do
cs_params = {
id: params[:id],
token: params[:token],
reference_content: params[:reference_content],
bid_message: params.reject{|k,v| [:id,:token,:reference_content].include?(k)}}
cs = CommentService.new
message = cs.homework_message cs_params,current_user
present :data, message, with: Mobile::Entities::Jours
present :status, 0
end
desc '课程留言'
params do
requires :token, type: String
requires :course_message,type: String, desc: '留言'
end
post ':id/leave_course_message' do
cs_params = {
id: params[:id],
token: params[:token],
new_form: params.reject{|k,v| [:id,:token].include?(k)}}
cs = CommentService.new
message = cs.leave_course_message cs_params,current_user
present :data, message, with: Mobile::Entities::Jours
present :status, 0
end
desc '回复留言'
params do
requires :token, type: String
requires :reference_id, type: Integer,desc: '所属留言树的根留言id最顶层的非回复的留言,留言对象中的m_parent_id'
requires :reference_user_id,type: Integer ,desc: '被回复的留言的作者id'
#requires :reference_message_id,type: Integer,desc: '被回复的留言的id'
requires :user_notes,type: String,desc: '留言的内容'
requires :jour_type,type: String,desc: '等于父留言的jour_type'
requires :jour_id,type:Integer, desc: '等于父留言的jour_id'
end
post ':reference_message_id/create_reply'do
cs = CommentService.new
message = cs.create_reply params,current_user
raise "create reply failed #{message.errors.full_messages}" if message.new_record?
present :data, message, with: Mobile::Entities::Jours
present :status, 0
end
end
end
end
end

@ -188,17 +188,18 @@ module Mobile
desc "课程通知列表" desc "课程通知列表"
params do params do
optional :token, type: String
end end
get ":course_id/news" do get ":course_id/news" do
cs = CoursesService.new cs = CoursesService.new
news = cs.course_news_list params news = cs.course_news_list params,current_user.nil? ? User.find(2):current_user
present :data, news, with: Mobile::Entities::News present :data, news, with: Mobile::Entities::News
present :status, 0 present :status, 0
end end
desc "显示课程通知" desc "显示课程通知"
params do params do
optional :token, type: String
end end
get "news/:id" do get "news/:id" do
cs = CoursesService.new cs = CoursesService.new
@ -208,6 +209,16 @@ module Mobile
present :status, 0 present :status, 0
end end
desc '课程动态'
params do
requires :token, type: String
end
get "course_dynamic/:id" do
cs = CoursesService.new
count = cs.course_dynamic(params,current_user)
present :data, count, with: Mobile::Entities::CourseDynamic
present :status, 0
end
end end
end end

@ -70,6 +70,32 @@ module Mobile
present :status, 0 present :status, 0
end end
desc "作品打分"
params do
requires :token, type: String
requires :is_teacher, type: String,desc: '是否为教师(匿评作品详情返回的结果中可获取此参数的值)'
requires :is_anonymous_comments, type: String, desc: '是否为匿评(匿评作品详情返回的结果中可获取此参数的值)'
optional :stars_value, type: Integer,desc: '用户给出的评分'
optional :cur_page,type: Integer,desc: '匿评作品详情返回的结果中可获取此参数的值'
optional :cur_type, type: Integer,desc: '匿评作品详情返回的结果中可获取此参数的值'
optional :user_message, type: String, desc: '用户评论'
end
post ':homework_id/scoring' do
cs_params = {
new_form: params.reject{|k,v| [:token,:is_teacher,:is_anonymous_comments,:stars_value,:cur_page,:cur_type,:homework_id].include?(k)},
token: params[:token],
is_teacher: params[:is_teacher],
is_anonymous_comments: params[:is_anonymous_comments],
stars_value: params[:stars_value],
cur_page: params[:cur_page],
cur_type: params[:cur_type],
homework_id: params[:homework_id]
}
Homeworks.get_service.add_score_and_jour cs_params,current_user
present :status, 0
end
end end
end end

@ -22,13 +22,15 @@ module Mobile
desc "显示用户" desc "显示用户"
params do params do
requires :id, type: Integer
end end
get ':id' do route_param :id do
us = UsersService.new get do
ue = us.show_user params us = UsersService.new
present :data, ue,with: Mobile::Entities::User ue = us.show_user params
present :status, 0 present :data, ue,with: Mobile::Entities::User
present :status, 0
end
end end
desc "修改用户" desc "修改用户"
@ -80,8 +82,9 @@ module Mobile
desc "用户搜索" desc "用户搜索"
params do params do
requires :name, type: String, desc: '用户名关键字' requires :name, type: String, desc: '用户名关键字'
requires :search_by, type: String,desc: '搜索依据0 昵称1 用户名2 邮箱'
end end
get 'search' do get 'search/search_user' do
us = UsersService.new us = UsersService.new
user = us.search_user params user = us.search_user params
present :data, user, with: Mobile::Entities::User present :data, user, with: Mobile::Entities::User

@ -0,0 +1,30 @@
module Mobile
module Entities
class Comment < Grape::Entity
include Redmine::I18n
def self.comment_expose(field)
expose field do |f,opt|
if f.is_a?(Hash) && f.key?(field)
f[field]
elsif f.is_a?(::Comment)
if f.respond_to?(field)
if field == :created_on
format_time(f.send(field))
else
f.send(field)
end
end
end
end
end
comment_expose :id
expose :author, using: Mobile::Entities::User do |c, opt|
if c.is_a? ::Comment
c.author
end
end
comment_expose :comments
comment_expose :created_on
end
end
end

@ -0,0 +1,17 @@
module Mobile
module Entities
class CourseDynamic < Grape::Entity
def self.course_dynamic_expose(field)
expose field do |c,opt|
c[field] if (c.is_a?(Hash) && c.key?(field))
end
end
course_dynamic_expose :course_name
course_dynamic_expose :need_anonymous_comments_count
course_dynamic_expose :student_commit_number
course_dynamic_expose :news_count
course_dynamic_expose :message_count
end
end
end

@ -17,6 +17,8 @@ module Mobile
case field case field
when :homework_times when :homework_times
f.bid.courses.first.homeworks.index(f.bid) + 1 unless (f.bid.nil? || f.bid.courses.nil? || f.bid.courses.first.nil?) f.bid.courses.first.homeworks.index(f.bid) + 1 unless (f.bid.nil? || f.bid.courses.nil? || f.bid.courses.first.nil?)
when :comment_status
f.bid.comment_status
end end
end end
end end
@ -28,6 +30,8 @@ module Mobile
homework_attach_expose :homework_times homework_attach_expose :homework_times
homework_attach_expose :description homework_attach_expose :description
homework_attach_expose :created_at homework_attach_expose :created_at
#comment_status 0:所属作业尚未开启匿评1匿评中 2匿评结束
homework_attach_expose :comment_status
expose :attachments,using: Mobile::Entities::Attachment do |f, opt| expose :attachments,using: Mobile::Entities::Attachment do |f, opt|
if f.respond_to?(:attachments) if f.respond_to?(:attachments)
f.send(:attachments) f.send(:attachments)

@ -18,12 +18,15 @@ module Mobile
end end
end end
jours_expose :id jours_expose :id
jours_expose :jour_type
jours_expose :jour_id
expose :user,using: Mobile::Entities::User do |f, opt| expose :user,using: Mobile::Entities::User do |f, opt|
f.user f.user
end end
jours_expose :created_on jours_expose :created_on
jours_expose :notes jours_expose :notes
jours_expose :m_reply_id jours_expose :m_reply_id
jours_expose :m_parent_id
expose :reply_user,using: Mobile::Entities::User do |f, opt| expose :reply_user,using: Mobile::Entities::User do |f, opt|
f.at_user f.at_user
end end

@ -34,7 +34,11 @@ module Mobile
#评论数量 #评论数量
news_expose :comments_count news_expose :comments_count
#评论 #评论
news_expose :comments expose :comments, using: Mobile::Entities::Comment do |f, opt|
if f.is_a?(Hash) && f.key?(:comments)
f[:comments]
end
end
end end

@ -283,4 +283,43 @@ class AdminController < ApplicationController
end end
end end
#企业主页定制
def enterprise_page_made
@enterprise_page = FirstPage.find_by_page_type('enterprise')
if @enterprise_page.nil?
@enterprise_page = FirstPage.new
@enterprise_page.page_type = 'enterprise'
end
if request.get?
@first_page = FirstPage.find_by_page_type('project')
elsif request.post?
@first_page = FirstPage.find_by_page_type('project')
@first_page.web_title = params[:web_title]
@enterprise_page.web_title = params[:web_title]
@enterprise_page.title = params[:course_title]
@enterprise_page.image_width = params[:image_width]
@enterprise_page.image_height = params[:image_height]
@enterprise_page.description = params[:course_description]
if @first_page.save && @enterprise_page.save
respond_to do |format|
format.html {
flash[:notice] = l(:notice_successful_update)
redirect_to enterprise_page_made_url
}
format.api { render_api_ok }
end
else
respond_to do |format|
flash.now[:error] = "#{l :label_first_page_create_fail}: #{@first_page.errors.full_messages[0]}\n\t#{@enterprise_page.errors.full_messages[0]}"
#flash.now[:error] = "#{l :label_first_page_create_fail}: #{@course_page.errors.full_messages[0]}"
format.html {
render :action => 'enterprise_page_made'
}
format.api { render_validation_errors(@first_page) }
format.api { render_validation_errors(@enterprise_page) }
end
end
end
end
end end

@ -254,8 +254,8 @@ class CoursesController < ApplicationController
end end
@is_remote = true @is_remote = true
@result_count = @results.count @result_count = @results.count
@results = paginateHelper @results @results = paginateHelper @results, 10
@search_name = q
end end
def addgroups def addgroups
@ -428,17 +428,34 @@ class CoursesController < ApplicationController
# @results = paginateHelper @results@score_sort_by = "desc" # @results = paginateHelper @results@score_sort_by = "desc"
@is_remote = true @is_remote = true
@score_sort_by = params[:sort_by] if params[:sort_by] @score_sort_by = params[:sort_by] if params[:sort_by]
@search_name = params[:search_name] if params[:search_name]
group_id = params[:group_id] group_id = params[:group_id]
if group_id == '0' if !@search_name.nil?
page = params[:page].nil? ? 0 : (params['page'].to_i - 1) if group_id == '0'
@results = student_homework_score(0,page, 10,@score_sort_by) page = params[:page].nil? ? 0 : (params['page'].to_i - 1)
@results = paginateHelper_for_members @results, 10 @results = searchmember_by_name(student_homework_score(0,0,0,@score_sort_by), @search_name)
@result_count = @results.count
@results = paginateHelper @results, 10
else
@group = CourseGroup.find(group_id)
@results = searchmember_by_name(student_homework_score(group_id, 0, 0,@score_sort_by),@search_name)
@result_count = @results.count
@results = paginateHelper @results, 10
end
else else
@group = CourseGroup.find(group_id) if group_id == '0'
@results = student_homework_score(group_id, 0, 0,@score_sort_by) page = params[:page].nil? ? 0 : (params['page'].to_i - 1)
@results = paginateHelper @results, 10 @results = student_homework_score(0,page, 10,@score_sort_by)
@results = paginateHelper_for_members @results, 10
else
@group = CourseGroup.find(group_id)
@results = student_homework_score(group_id, 0, 0,@score_sort_by)
@results = paginateHelper @results, 10
end
end end
end end
# 显示每个学生的作业评分详情 # 显示每个学生的作业评分详情
def show_member_score def show_member_score

@ -0,0 +1,6 @@
class OrganizationsController < ApplicationController
layout 'project_base'
def index
@projects = Project.find_by_sql("SELECT * FROM projects WHERE id IN (select MAX(id) from projects GROUP BY enterprise_name)")
end
end

@ -1,6 +0,0 @@
class OriginizationsController < ApplicationController
layout 'project_base'
def index
@enterprises = Project.find_by_sql("select distinct(enterprise_name) from projects")
end
end

@ -20,11 +20,12 @@
class ProjectsController < ApplicationController class ProjectsController < ApplicationController
layout :select_project_layout layout :select_project_layout
menu_item :overview menu_item :overview, :only => :show
menu_item :roadmap, :only => :roadmap menu_item :roadmap, :only => :roadmap
menu_item :settings, :only => :settings menu_item :settings, :only => :settings
menu_item :homework, :only => [:homework, :new_homework] menu_item :homework, :only => [:homework, :new_homework]
menu_item :feedback, :only => :feedback menu_item :feedback, :only => :feedback
menu_item :share, :only => :share
before_filter :find_project, :except => [ :index, :search,:list, :new, :create, :copy, :statistics, :new_join, before_filter :find_project, :except => [ :index, :search,:list, :new, :create, :copy, :statistics, :new_join,
:course, :enterprise_course, :course_enterprise,:view_homework_attaches] :course, :enterprise_course, :course_enterprise,:view_homework_attaches]

@ -25,17 +25,30 @@ class WelcomeController < ApplicationController
before_filter :entry_select, :only => [:index] before_filter :entry_select, :only => [:index]
def index def index
unless params[:originization].nil? # 企业版定制: params[:project]为传过来的参数
@originization = params[:originization] unless params[:organization].nil?
@originization_projects = Project.find_by_sql(["select * from projects where enterprise_name =? ", @originization]) @cur_projects = Project.find(params[:organization])
@e_count = @originization_projects.count @organization = @cur_projects.enterprise_name
if @e_count < 10 @organization_projects = (current_user.admin? || User.current.member_of?(@cur_projects)) ? Project.where("enterprise_name =? ", @organization) : Project.all_public.where("enterprise_name =? ", @organization)
part_count = 10 -@e_count @e_count = @organization_projects.count
# @part_projects = find_all_hot_project part_count, order @part_projects = []
@part_projects = find_miracle_project(part_count, 3,"score desc") # 取十个
limit = 10 - @e_count @organization_projects.each do |obj|
break if(@organization_projects[10] == obj)
@part_projects << Project.visible.find_by_id("#{obj.id}") unless obj.id.nil?
end end
# 不够十个的用最火项目替代
@e_count < 9 ? @part_projects = find_miracle_project( 9 - @e_count, 3,"score desc") : @part_projects
# 配置文件首页定制
@enterprise_page = FirstPage.find_by_page_type('enterprise')
if @enterprise_page.nil?
@enterprise_page = FirstPage.new
@enterprise_page.page_type = 'enterprise'
end
# 主页配置部分结束
end end
# end 企业版定制结束
if @first_page.nil? || @first_page.sort_type.nil? if @first_page.nil? || @first_page.sort_type.nil?
@projects = find_miracle_project(10, 3,"score desc") @projects = find_miracle_project(10, 3,"score desc")
else else

@ -7,6 +7,7 @@ class ZipdownController < ApplicationController
SAVE_FOLDER = "#{Rails.root}/files" SAVE_FOLDER = "#{Rails.root}/files"
OUTPUT_FOLDER = "#{Rails.root}/tmp/archiveZip" OUTPUT_FOLDER = "#{Rails.root}/tmp/archiveZip"
def assort def assort
if params[:obj_class] == "Bid" if params[:obj_class] == "Bid"
bid = Bid.find params[:obj_id] bid = Bid.find params[:obj_id]

@ -37,4 +37,27 @@ module ApiHelper
end end
result result
end end
#########################################################
#sw
#获取课程未匿评数量
#param: user => "用户", course_id => "查询的课程ID"
#return: 作业的数量
#########################################################
def get_course_anonymous_evaluation user,course
count = 0
if course
is_teacher = is_course_teacher user,course
if is_teacher #如果是老师,显示学生提交的作业数
course.homeworks.each do |bid|
count += bid.homeworks.count
end
else #如果是学生,显示未匿评的数量
course.homeworks.each do |bid|
count += get_student_not_batch_homework_list bid,user
end
end
end
[count,is_teacher]
end
end end

@ -130,4 +130,22 @@ module HomeworkAttachHelper
WHERE homework_attaches.bid_id = #{bid.id} AND homework_evaluations.user_id = #{user.id} ORDER BY m_score DESC") WHERE homework_attaches.bid_id = #{bid.id} AND homework_evaluations.user_id = #{user.id} ORDER BY m_score DESC")
student_batch_homework_list student_batch_homework_list
end end
#########################################################
#sw
#获取学生未进行匿评的数量
#param: bid => 作业 user => 用户
#return 指定用户未进行匿评的作业的数量
#user必须是学生用户
#######################################################
def get_student_not_batch_homework_list bid,user
HomeworkAttach.find_by_sql("SELECT * FROM(SELECT homework_attaches.*,
(SELECT AVG(stars) FROM seems_rateable_rates WHERE rateable_type = 'HomeworkAttach' AND rateable_id = homework_attaches.id AND is_teacher_score = 1) AS t_score,
(SELECT AVG(stars) FROM seems_rateable_rates WHERE rateable_type = 'HomeworkAttach' AND rateable_id = homework_attaches.id AND is_teacher_score = 0) AS s_score,
(SELECT stars FROM seems_rateable_rates WHERE rateable_type = 'HomeworkAttach' AND rateable_id = homework_attaches.id AND rater_id = #{user.id} AND is_teacher_score = 0) AS m_score
FROM homework_attaches
INNER JOIN homework_evaluations ON homework_evaluations.homework_attach_id = homework_attaches.id
WHERE homework_attaches.bid_id = #{bid.id} AND homework_evaluations.user_id = #{user.id}) AS table1
WHERE table1.m_score IS NULL").count
end
end end

@ -93,7 +93,9 @@ class Bid < ActiveRecord::Base
# 'deadline' # 'deadline'
def add_jour(user, notes, reference_user_id = 0, options = {}) def add_jour(user, notes, reference_user_id = 0, options = {})
if options.count == 0 if options.count == 0
self.journals_for_messages << JournalsForMessage.new(:user_id => user.id, :notes => notes, :reply_id => reference_user_id) jfm = JournalsForMessage.new(:user_id => user.id, :notes => notes, :reply_id => reference_user_id)
self.journals_for_messages << jfm
jfm
else else
jfm = self.journals_for_messages.build(options) jfm = self.journals_for_messages.build(options)
jfm.save jfm.save

@ -23,7 +23,7 @@ class Forum < ActiveRecord::Base
acts_as_taggable acts_as_taggable
scope :by_join_date, order("created_at DESC") scope :by_join_date, order("created_at DESC")
after_create :send_email #after_create :send_email
def reset_counters! def reset_counters!
self.class.reset_counters!(id) self.class.reset_counters!(id)
end end

@ -50,10 +50,15 @@ class Mailer < ActionMailer::Base
@forum_url = url_for(:controller => 'forums', :action => 'show', :id => @forum.id) @forum_url = url_for(:controller => 'forums', :action => 'show', :id => @forum.id)
@issue_author_url = url_for(user_activities_url(@author)) @issue_author_url = url_for(user_activities_url(@author))
recipients ||= [] recipients ||= []
mems = memo.self_and_siblings # if !memo.parent_id.nil?
mems.each do |mem| # mems = memo.self_and_siblings
recipients << mem.author.mail unless recipients.include? mem.author.mail # mems.each do |mem|
end # recipients << mem.author.mail unless recipients.include? mem.author.mail
# end
# else
# recipients << memo.author.mail
# end
recipients << @author.mail
# cc = wiki_content.page.wiki.watcher_recipients - recipients # cc = wiki_content.page.wiki.watcher_recipients - recipients
@memo_url = url_for(forum_memo_url(@forum, (@memo.parent_id.nil? ? @memo : @memo.parent_id))) @memo_url = url_for(forum_memo_url(@forum, (@memo.parent_id.nil? ? @memo : @memo.parent_id)))
@ -98,10 +103,7 @@ class Mailer < ActionMailer::Base
#收件人邮箱 #收件人邮箱
@recipients ||= [] @recipients ||= []
@members.each do |teacher| @members.each do |teacher|
@recipients << teacher.user.mail @recipients << teacher.user.mail
end end
mail :to => @recipients, mail :to => @recipients,
:subject => "#{l(:label_your_course)}#{journals_for_message.jour.name}#{l(:label_have_message)} " :subject => "#{l(:label_your_course)}#{journals_for_message.jour.name}#{l(:label_have_message)} "

@ -47,7 +47,7 @@ class Memo < ActiveRecord::Base
"parent_id", "parent_id",
"replies_count" "replies_count"
after_create :add_author_as_watcher, :reset_counters!, :sendmail#,:be_user_score -- 公共区发帖暂不计入得分 after_create :add_author_as_watcher, :reset_counters! #, :sendmail#,:be_user_score -- 公共区发帖暂不计入得分
# after_update :update_memos_forum # after_update :update_memos_forum
after_destroy :reset_counters!#,:down_user_score -- 公共区发帖暂不计入得分 after_destroy :reset_counters!#,:down_user_score -- 公共区发帖暂不计入得分
# after_create :send_notification # after_create :send_notification

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save