Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to prevent scroll in custom Calendar with dataviewJS #550

Closed
FfEzT opened this issue Mar 7, 2024 · 0 comments
Closed

How to prevent scroll in custom Calendar with dataviewJS #550

FfEzT opened this issue Mar 7, 2024 · 0 comments

Comments

@FfEzT
Copy link

FfEzT commented Mar 7, 2024

So I've writen my version of plugin
Because I need to implement my notes with my custom properties
Such as:

  • Time (in ISO format)
  • duration (format 1d5h17m, if val is 'x' the default duration is 1h30m

And this is my version of calendar with using Dataviewjs and FullCalendar

But I am facing some problems

  1. when I edit smth in calendar or note view update and scroll sets null
  2. how to create notes in this view

I think I need to convert it into plugin
But may be there is another way
(I don't want to learn how to create plugins)

`dataviewjs

this.container.style.minHeight = "100vh";

const FORMAT_DEFAULT_ADD = 'x'
const FORMAT_DAY = 'd'
const FORMAT_HOUR = 'h'
const FORMAT_MINUTE = 'm'

const DAY_REG = /\d+d/
const HOUR_REG = /\d+h/
const MINUTE_REG = /\d+m/

const DEFAULT_ADD = {
	d: 0,
	h: 1,
	m: 30 
}

const MillisecsInSecond = 1000
const SecsInMinute = 60
const MinutesInHour = 60
const HoursInDay = 24
const MillisecsInMinute = MillisecsInSecond * SecsInMinute
const MillisecsInHour = MillisecsInMinute * MinutesInHour
const MillisecsInDay = MillisecsInHour * HoursInDay
const DEFAULT_ADD_IN_MILLISEC = DEFAULT_ADD.d * MillisecsInDay + DEFAULT_ADD.h * MillisecsInHour + DEFAULT_ADD.m *  MillisecsInMinute


const { renderCalendar } = app.plugins.plugins["obsidian-full-calendar"];
const MDCache = app.metadataCache


const millisecToString = (millisec) => {
	const days = Math.floor(
		millisec / (MillisecsInDay)
	)
	millisec -= days * MillisecsInDay
	
	const hours = Math.floor(
		millisec / (MillisecsInHour)
	)
	millisec -= hours * MillisecsInHour
	
	const minutes = Math.floor(
		millisec / (MillisecsInMinute)
	)
	millisec -= minutes * MillisecsInMinute

	let resString = ''
	if (days)
		resString += days.toString() + FORMAT_DAY
	if (hours)
		resString += hours.toString() + FORMAT_HOUR
	if (minutes)
		resString += minutes.toString() + FORMAT_MINUTE

	return resString
}

const getEvents = () => {
	let events = []
	let pages = dv.pages('"databases"')
	
	for (let i = 0; i < pages.length; ++i) {
		let page = pages.values[i]
		if (!page.date) {
			continue
		}
		
		const structure = {
			id: page.file.path,
			title: page.file.name,
			start: new Date(page.date),
			
			allDay: true,
			
			// TODO 
			// color: "red",
			editable: true,
		}

		if (page.duration === FORMAT_DEFAULT_ADD) {
			structure.allDay = false
			let tmpTime = new Date(page.date)
				
			tmpTime.setMinutes(
				tmpTime.getMinutes() + DEFAULT_ADD.m
			)
			tmpTime.setHours(
				tmpTime.getHours() + DEFAULT_ADD.h
			)
			tmpTime.setDate(
				tmpTime.getDate() + DEFAULT_ADD.d
			)
			
			structure.end = tmpTime
		}
		else if (page.duration) {
			const duration = page.duration.values
			
			structure.allDay = false
			
			let tmpTime = new Date(page.date)
			if (duration.minutes)
				tmpTime.setMinutes(
					tmpTime.getMinutes() + duration.minutes
				)
			
			if (duration.hours)
				tmpTime.setHours(
					tmpTime.getHours() + duration.hours
				)
			if (duration.days)
				tmpTime.setDate(
					tmpTime.getDate() + duration.days
				)
			
			structure.end = tmpTime
		}
		
		events.push(structure)
	}

	return events
}

const settings = {
	firstDay: 1,
	weekNumbers:true,
	eventClick: (info) => {
		const tFile = MDCache.getFirstLinkpathDest(
			info.event.id, ''
		)
	
		// false = open in the current tab
		const leaf = this.app.workspace.getLeaf(!app.isMobile)
		leaf.openFile(tFile)
	},
	modifyEvent: async (newPos, oldPos) => {
	
		let tmpTime = new Date(newPos.start)
		tmpTime.setMinutes(
			tmpTime.getMinutes() - tmpTime.getTimezoneOffset()
		)
		
		const newTime = tmpTime.toISOString().slice(0,-5)
		
		const tFile = MDCache.getFirstLinkpathDest(
			newPos.id, ''
		)
		await app.fileManager.processFrontMatter(
			tFile,
			(property) => {
				property['date'] = newTime

				let resDuration
				if (newPos.allDay) {
					resDuration = ''
				}
				else if (oldPos.allDay) {
					resDuration = FORMAT_DEFAULT_ADD
				}
				else {
					const srcMillisec = newPos.end - newPos.start
					
					resDuration = DEFAULT_ADD_IN_MILLISEC === srcMillisec
					? FORMAT_DEFAULT_ADD : millisecToString(srcMillisec)
				}

				property['duration'] = resDuration
			}
		)

		// true for update place in Calendar
		return 1;
	}
}

const calendar = renderCalendar(
	this.container,
	{
		events: getEvents()
	},
	settings,
)
calendar.setOption('weekNumbers', true)
// to fix bug first render
window.setTimeout(
	_ => {
		if (app.isMobile)
			calendar.changeView('timeGrid3Days')
		else
			calendar.changeView('timeGridWeek')
	},
	1
)

calendar.render()

`dataviewjs

U can paste this code using notes with properties 'date' (for example 2024-03-07T22:00:00) and 'duration' (1h30m)

This is my first public share on GitHub.
(Maybe it should be in the discussions)

@FfEzT FfEzT closed this as completed Mar 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant