2020-03-23 21:46:26 +01:00
|
|
|
// The Construct
|
|
|
|
//
|
|
|
|
// Copyright (C) The Construct Developers, Authors & Contributors
|
|
|
|
// Copyright (C) 2016-2020 Jason Volk <jason@zemos.net>
|
|
|
|
//
|
|
|
|
// Permission to use, copy, modify, and/or distribute this software for any
|
|
|
|
// purpose with or without fee is hereby granted, provided that the above
|
|
|
|
// copyright notice and this permission notice is present in all copies. The
|
|
|
|
// full license for this software is available in the LICENSE file.
|
|
|
|
|
|
|
|
decltype(ircd::m::user::notifications::type_prefix)
|
|
|
|
ircd::m::user::notifications::type_prefix
|
|
|
|
{
|
|
|
|
"ircd.push.note"
|
|
|
|
};
|
|
|
|
|
2020-03-24 23:01:36 +01:00
|
|
|
ircd::m::user::notifications::opts
|
|
|
|
ircd::m::user::notifications::unmake_type(const string_view &type)
|
|
|
|
{
|
|
|
|
const string_view &room_id
|
|
|
|
{
|
|
|
|
type.substr(type.find('!'))
|
|
|
|
};
|
|
|
|
|
|
|
|
const string_view &only
|
|
|
|
{
|
|
|
|
lstrip(split(type, '!').first, type_prefix)
|
|
|
|
};
|
|
|
|
|
|
|
|
opts ret;
|
|
|
|
ret.only = lstrip(only, '.');
|
|
|
|
ret.room_id = room_id? room::id{room_id} : room::id{};
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-03-24 22:54:47 +01:00
|
|
|
/// valid result examples:
|
|
|
|
///
|
|
|
|
/// ircd.push.note.highlight!AAAANTUiY1fBZ230:zemos.net
|
|
|
|
/// ircd.push.note.highlight
|
|
|
|
/// ircd.push.note!AAAANTUiY1fBZ230:zemos.net
|
|
|
|
/// ircd.push.note
|
2020-03-23 21:46:26 +01:00
|
|
|
ircd::string_view
|
|
|
|
ircd::m::user::notifications::make_type(const mutable_buffer &buf,
|
|
|
|
const opts &opts)
|
|
|
|
{
|
|
|
|
return fmt::sprintf
|
|
|
|
{
|
2020-03-24 22:54:47 +01:00
|
|
|
buf, "%s%s%s%s",
|
2020-03-23 21:46:26 +01:00
|
|
|
type_prefix,
|
|
|
|
opts.only? "."_sv : string_view{},
|
|
|
|
opts.only,
|
2020-03-24 22:54:47 +01:00
|
|
|
string_view{opts.room_id},
|
2020-03-23 21:46:26 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ircd::m::user::notifications::empty(const opts &opts)
|
|
|
|
const
|
|
|
|
{
|
2020-03-25 00:40:23 +01:00
|
|
|
return !for_each(opts, closure_meta{[&]
|
2020-03-23 21:46:26 +01:00
|
|
|
(const auto &, const auto &)
|
|
|
|
{
|
|
|
|
return false;
|
2020-03-25 00:40:23 +01:00
|
|
|
}});
|
2020-03-23 21:46:26 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t
|
|
|
|
ircd::m::user::notifications::count(const opts &opts)
|
|
|
|
const
|
|
|
|
{
|
|
|
|
size_t ret(0);
|
2020-03-25 00:40:23 +01:00
|
|
|
for_each(opts, closure_meta{[&ret]
|
2020-03-23 21:46:26 +01:00
|
|
|
(const auto &, const auto &)
|
|
|
|
{
|
|
|
|
++ret;
|
|
|
|
return true;
|
2020-03-25 00:40:23 +01:00
|
|
|
}});
|
2020-03-23 21:46:26 +01:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ircd::m::user::notifications::for_each(const opts &opts,
|
2020-03-25 00:40:23 +01:00
|
|
|
const closure &closure)
|
|
|
|
const
|
|
|
|
{
|
|
|
|
return for_each(opts, closure_meta{[&closure]
|
|
|
|
(const auto &type, const auto &event_idx)
|
|
|
|
{
|
|
|
|
return m::query(std::nothrow, event_idx, "content", [&closure, &event_idx]
|
|
|
|
(const json::object &content)
|
|
|
|
{
|
|
|
|
return closure(event_idx, content);
|
|
|
|
});
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ircd::m::user::notifications::for_each(const opts &opts,
|
|
|
|
const closure_meta &closure)
|
2020-03-23 21:46:26 +01:00
|
|
|
const
|
|
|
|
{
|
|
|
|
const user::room user_room
|
|
|
|
{
|
|
|
|
user
|
|
|
|
};
|
|
|
|
|
|
|
|
char type_buf[event::TYPE_MAX_SIZE];
|
|
|
|
const auto type
|
|
|
|
{
|
|
|
|
make_type(type_buf, opts)
|
|
|
|
};
|
|
|
|
|
2020-03-24 21:06:24 +01:00
|
|
|
const room::type events
|
2020-03-23 21:46:26 +01:00
|
|
|
{
|
2020-03-24 22:54:47 +01:00
|
|
|
user_room, type, {-1UL, -1L}, true
|
2020-03-23 21:46:26 +01:00
|
|
|
};
|
|
|
|
|
2020-03-26 22:02:42 +01:00
|
|
|
if(!opts.sorted || opts.room_id)
|
|
|
|
return events.for_each([&opts, &closure]
|
|
|
|
(const auto &type, const auto &depth, const auto &event_idx)
|
|
|
|
{
|
|
|
|
if(opts.from && event_idx > opts.from) //TODO: XXX
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if(opts.to && event_idx <= opts.to) //TODO: XXX
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return closure(type, event_idx);
|
|
|
|
});
|
|
|
|
|
|
|
|
std::vector<event::idx> idxs;
|
|
|
|
idxs.reserve(events.count());
|
|
|
|
events.for_each([&opts, &idxs]
|
2020-03-24 21:06:24 +01:00
|
|
|
(const auto &type, const auto &depth, const auto &event_idx)
|
2020-03-23 21:46:26 +01:00
|
|
|
{
|
2020-03-26 22:02:42 +01:00
|
|
|
if(opts.from && event_idx > opts.from)
|
2020-03-24 21:06:24 +01:00
|
|
|
return true;
|
2020-03-23 21:46:26 +01:00
|
|
|
|
2020-03-26 22:02:42 +01:00
|
|
|
if(opts.to && event_idx <= opts.to)
|
|
|
|
return true;
|
2020-03-24 21:06:24 +01:00
|
|
|
|
2020-03-26 22:02:42 +01:00
|
|
|
idxs.emplace_back(event_idx);
|
|
|
|
return true;
|
2020-03-24 21:06:24 +01:00
|
|
|
});
|
2020-03-26 22:02:42 +01:00
|
|
|
|
|
|
|
std::sort(rbegin(idxs), rend(idxs));
|
|
|
|
for(const auto &idx : idxs)
|
|
|
|
if(!closure(string_view{}, idx)) //NOTE: no type string to closure
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
2020-03-23 21:46:26 +01:00
|
|
|
}
|