Meteor : Countdown timer - meteor

This might be a big ask, but I'm completely stuck so any help is appreciated.
I'm trying to create a countdown timer that runs from Sunday to Sunday and just restarts at the end of the week. I've tried using countdown packages in atmosphere but the documentation is limited and never seems to work. I've also tried to download and run 3rd party jquery packages however they always seem to crash meteor.
Could someone point me in the right direction or show me how to do this in meteor?
Specific details:
Countdown timer used to run an auction.
Auction runs for 7 days, Starts Sunday at 12:00am finishes 7 days
later.
Auction resets and starts again after 7 days.
Countdown timer will be visible by users on multiple pages.
Countdown timer units to be displayed - Days, Hours, Minutes, Seconds (eg.
6 days, 3 hours, 55 minutes, 22 seconds until the next auction
begins.)

The question is too large. But i can suggest the small step to work with this. Your auction scheme will need to have a endDateTime to store the value (even it will start/end in Sunday). On the template you need to display the timer, set one ReactiveVar as number (to count down), one ReactiveVar as string (to display to result)
Template['countDownTemplate'].created = function() {
var due, dueDate, duration, now, num, self;
self = this;
dueDate = Template.instance().data['auction']['endDateTime'];
now = moment.utc();
due = moment.utc(dueDate, 'YYYY-MM-DD hh:mm:ss');
duration = moment.duration(due.diff(now));
num = Math.floor(duration.asSeconds());
if (num >= 0) {
self['remaining'] = new ReactiveVar<number>(num);
self['timeRemaining'] = new ReactiveVar<string>(convertPeriod(num));
self['interval'] = Meteor.setInterval((function() {
var remaining;
remaining = self['remaining'].get();
self['remaining'].set(remaining - 1);
self['timeRemaining'].set(convertPeriod(self['remaining'].get()));
if (remaining === 0) {
Meteor.clearInterval(self['interval']);
} else {
remaining = Math.floor(moment.duration(due.diff(now)).asSeconds());
}
}), 1000);
}
};
(the convertPeriod will be based on the remaining number to convert into your correct format)
The rest is just about showing timeRemaining in the correct format with the convertPeriod

Related

Update firebase database value every 5 seconds using Pub/sub OR Cloud Tasks?

I am new to Firebase and I am totally confused about what should I use. Here is my flow.
I have a collection score on firebase and it has values
- start_time
- count
- max_count
Now when start_time matches with the current time, I need to increment the count every five seconds till it matches max_count to the database. This should be in the backend. Now here I got confused. What can be suitable for this?
There are so many documents about Cloud Tasks and Pub/Sub.
If I Call the firebase function from Pub/Sub to update the count every 5 seconds then I will be paying for un-used compute time for calling a function.
I am not aware more about Cloud Tasks that is it matches my requirement? Can anyone please guide me?
Neither Cloud Tasks nor Pub/Sub would be the right solution for this and I wouldn't recommend using a cron-type service for such a menial task.
Instead consider moving the incremental logic to your client and just storing start_time and max_count in your database. Here's an example:
// Let's set a start_time 10 seconds in the future and pretend this was in the database
const start_time = Math.floor((new Date()).getTime() / 1000) + 10;
// Pretend this came from the database, we only want to iterate 10 times
const max_count = 10;
let prev_count = 0;
document.write("Waiting 10 seconds before starting<br />");
// Let's iterate once a second until we reach the start_time
let interval = setInterval(() => {
const now = Math.floor((new Date()).getTime() / 1000);
// If it's not start time, exit
if (now < start_time) return;
// Determine the count by dividing by 5 seconds
let count = Math.floor((now - start_time) / 5);
if (count > prev_count) {
document.write(`Tick: ${count}<br />`);
}
prev_count = count;
if (count >= max_count) {
clearInterval(interval);
}
}, 1000);
If you need the count stored in the database, have it update the count value in your database each time it increments.

SwiftUI or Combine Clock/Timer events

Using SwiftUI (or Combine) how might I set up a series of one or more events that are triggered by the (system) clock. Examples might include:
Every night at midnight,
On the hour,
Every fifteen minutes on the quarter hour,
Finally, on a slightly different note: On the 29th of February 2020 at 12:15.
An approximation is easily achieved by setting up a timer event that fires every second and then checking the hours/minutes/seconds, etc. but this seems very inefficient for events that may be many hours or days apart.
I'm looking for something that is closely synchronised to the actual system clock and fires off a single event at the required time rather than firing loads of events and having each one ask "Are we there yet?".
I would suggest the following:
DispatchQueue.global(qos: .background).async {
let isoDate = "2020-01-13T16:58:30+0000"
let dateFormatter = ISO8601DateFormatter()
let date = dateFormatter.date(from:isoDate)!
let t = Timer(fire: date, interval: 2, repeats: true) { timer in
print("fired")
}
let runLoop = RunLoop.current
runLoop.add(t, forMode: .default)
runLoop.run()
}
string to date conversion I used this answer to format the time correctly.
The example is in GMT.
documentation apple you can look up timer tolerance which can be adjusted if you need the timer to be very accurate.
interval is in seconds so this solution won't get more accurate than seconds
You might want to enable the Background Modes capability to go for the very long running timers. Never done that so I can't help here.
All your examples should work. I hope this helps!
I had to implement this feature too using Combine / SwiftUI : a Timer that would execute at start then every day, hour or minutes (for testing), here is my solution if it can be useful or improved :)
class PeriodicPublisher {
var periodicFormat: PeriodicFormat = .daily
init(_ format: PeriodicFormat = .daily) {
self.periodicFormat = format
}
// Must have an equatable for removeDuplicate
struct OutputDate: Equatable {
let compared: String
let original: String
init(_ comparedDatePart: String, _ originalDate: String) {
self.compared = comparedDatePart
self.original = originalDate
}
static func ==(lhs: OutputDate, rhs: OutputDate) -> Bool {
return lhs.compared == rhs.compared
}
}
enum PeriodicFormat {
case daily
case hourly
case minutely
func toComparableDate() -> String {
switch self {
case .daily:
return "yyyy-MM-dd"
case .hourly:
return "HH"
case .minutely:
return "mm"
}
}
}
func getPublisher() -> AnyPublisher<OutputDate, Never> {
let compareDateFormatter = DateFormatter()
compareDateFormatter.dateFormat = self.periodicFormat.toComparableDate()
let originalTimerDateFormatter = DateFormatter()
originalTimerDateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
var nowDate: Just<OutputDate> {
let comparedDate = compareDateFormatter.string(from: Date())
let originalDate = originalTimerDateFormatter.string(from: Date())
return Just(OutputDate(comparedDate, originalDate))
}
let timerDate = Timer.publish(every: 2.0, tolerance: 1.0, on: .main, in: .default, options: nil)
.autoconnect()
.map { dateString -> OutputDate in
return OutputDate(compareDateFormatter.string(from: dateString), originalTimerDateFormatter.string(from: dateString))
}
.eraseToAnyPublisher()
return Publishers.Merge(nowDate, timerDate)
.map { $0 }
.removeDuplicates()
.eraseToAnyPublisher()
}
}
How does it work ?
Every 2 seconds the scheduler issue current date (with Timer.publish()), this date is used to create a "OutputDate" holding two properties : one "comparable" part used to compare if something has changed and one "original" part so it can be useful for the consumer.
Comparable property is Timer's date formatted with toComparableDate given the provided configuration (.daily, .hourly, .minutely). Using "removeDuplicates" on this property allow to publish "OutputDate" only when this value changes. Every day or hour or minute.
Publishers.Merge is used to publish a value immediately after instantiation, otherwise nothing happens before the first Timer.publish(every). Here 2 seconds.
How to use it ?
You would use it with Combine like this :
PeriodicPublisher(.daily).getPublisher().sink { date in
print("Day has changed \(date.original)")
}

momentjs - strange behave with startOf and endOf

I'm trying to get the start and the end a a specific day.
Here's the code:
var newDay, newDayEnd, newDayStart;
if (newDay === '') {
newDay = moment();
}
newDay.subtract('day', 1);
newDayStart = newDay.startOf('day');
newDayEnd = newDay.endOf('day');
I'm trying to debug it, and I noticed that when if goes trough the values are correct, but as soon as it reaches newDay.endOf('day') it sets all the variable to the end of the specified day (23.59.59)
I'm using the above function on button click. Every time I click a button, it goes back one day (newDay.subtract('day', 1)) and I need to be able to get start and end of the new day (newDay variable)
Any help?
What am I doing wrong here? I don't understand.
Thanks
Moment objects are mutable, so you have to clone() them before modifying them.
As you can read from the endOf docs:
Mutates the original moment by setting it to the end of a unit of time.
Working example:
var newDay, newDayEnd, newDayStart;
newDay = moment().subtract(1, 'day');
newDayStart = newDay.clone().startOf('day');
newDayEnd = newDay.clone().endOf('day');
console.log(newDayStart.format(), newDayEnd.format());
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.min.js"></script>

How to display popup message in the asp.net page only for certain days

I need to display pop up message on when loading the ASP.NET page. NOw I am using JQuery dialog to display information but the I need to show this dialog box only for certain days (max 30 days). How can I achieve this?
One way you can do all of it is client-side (subject of course to client side clock):
var start = new Date(2015,2, 1); //start date March 1, 2015, toggle date to test
var diff = Math.floor((new Date() - start)/86400000);
if(diff < 30) {
alert("Popped because it has only been " + diff + " days");
} else {
console && console.log("No alert, exceeded 30 days - it's been %o days", diff);
}
If you want server side/server time, then refer to DateTime and trigger the alert (e.g. inject the js, a variable in the js, etc.)
Hth.

Something Like setAsToday(date)?

With default view set to agendaWeek. If I load fullCalendar at 11:59PM the today day slot is not automatically updated after 12:00AM until I refresh the browser.
This is how I fixed it:
Call a function every 5 minutes (or any interval that suits your requirements)
$(function() {
var tInterval = 5*60*1000;
timelineInterval = window.setInterval(updateFcToday, tInterval); // Update timeline after every 5 minutes
});
Add a function like this to the page that contains your calendar:
function updateFcToday() {
var curTime = new Date();
if(curTime.getHours() == 0 && curTime.getMinutes() <= 5) // this five minutes is same interval that we are calling this function for. Both should be the same
{// the day has changed
var todayElem = $(".fc-today");
todayElem.removeClass("fc-today");
todayElem.removeClass("fc-state-highlight");
todayElem.next().addClass("fc-today");
todayElem.next().addClass("fc-state-highlight");
}
}

Resources