Impressive. I'm sure there are some here that understand all that stuff you are talking about, I'm not one obviously; but it doesn't take a genius to spot a genius. Stay on it. Don't seek re-affirmation because I have found in life you'll rarely get it. If you think it'll work, then block out what the world says and get it up and going because just as you pointed out about predicting the markets, no one can predict if an idea will be successful or not. If you believe in it... that's all that matters. The world is full of nay-sayers, I think the ratio is probably like 99:1. Count me as one of the "1's" however. Of course I can add nothing technical to your framework lol, but I did notice you left out pets in this list: Your projects Your job positions Your skills Your research and articles Stories in the workplace Your problems at work Computer science Algorithms and machine learning Statistics and quantitative methods Topics in Mathematics Topics in Physics People and companies Macroeconomic and politics Work Philosophy and life wisdom Social media trends New technologies New software New hardware Real estates deals Investors lounge, finance Artworks deals Equipment deals Main Languages: C, C++, C# Main Languages: VB.NET Main Languages: Java Main Languages: Assembly Main Languages, web front end Main Languages, web back end Interpreters and data analysis tools Your hobbies and passions Health and wealth Life hacks and useful tips Chit-chat, news, opinions Inspiring stories Pets are a big thing these days. Probably more than ever. I'm sure your cat would agree. GL and never quit. You've already done more in this thread alone than most ever will. ~vz
Thank you vanzandt. That beautiful encouragement is way too kind of you. > I did notice you left out pets in this list. Thank you. Please enumerate all your ideas and suggestions I am also compiling a list for the NY site. So I will add possible suggestions and then I will submit here again the new list in English too (for the NY site, with items specific to New York, like the slang, Central Park, and so on...). For that, I will need some "serious" help and feedback, as obviously, I do not know well life over there, apart from what we see in the movies and news The list above was that of the "professional" site (say the LinkedD... "replacement"). "Pets" are currently included in the Rome site (several items dedicated, as Roman cats are famous ) and in the ITA-EN cafe exchange site, but I did not include them explicitly for the "professional" site. It might be added actually, although the "passions" item in this list could partially cover it ... > If you think it'll work, then block out what the world says I always like to get anything without blocks. Even the negativity because there is always a reason behind any remark, and I always want to understand exactly that reason (if any) to possibly come back stronger > I think the ratio is probably like 99:1. Count me as one of the "1's" however. I take note
To recap a bit, we started from the simple idea of making a new social medium, propaganda free, and now I am messing on 5 different sites ) Well, the point is that since the engine can be "shared", it's just convenient to have different "incarnations" of a social medium. Why? Technically, because, for me, being forced to adapt the engine to slightly different "destinations" and languages forces me to a higher level of abstraction, which usually makes the entire code and architecture much more robust, maintainable, and powerful. Strategically, a network of media is certainly better than just 1 medium. Simply because a user can just by curiosity take a look at the other sites and that creates a multiplier of views and interactions. The initial magic network "pentacle" is now formed by: 1) A "professional life" site (say a better version of Linkedin ) 2) A more relaxing and casual site for cultural exchanges between ITA and EN-speaking people or anyway interested in different cultures and languages: Italiano-English Cafè 3) A specialized local medium for Rome, which will contain both classified ads to buy and sell anything, but also discussion forums and topics about all the most characteristic aspects of Rome. This site will use the "Romanesco" dialect and will be also full of funny sayings and proverbs. 4) A site for trading journals and other trading-related stuff. Pretty much similar to ET but on an EU domain, and of course will take care of sending traffic and advertising ET too of course 5) A site replicating the idea of the local Rome journal for NYC. This goes well also with site 2) and probably 2-3-5 can generate some good interaction. This will not be just a classified ads site, but will host discussions and every ad will actually potentially become a discussion thread. For the last one, I am in a bit of trouble both because of the language barrier and because I do not know the city. Anyway, I will give it a preliminary try, and then we can adjust on the fly based on feedback (or even remake it entirely later if necessary . For now, I have basically copied the categories I had created for Rome and attempted a brutal "translation", adding some entries. The first difficulty I found is in sports. In Italy, we do not have much variety, since soccer is sadly dominating, but it seems to me that in the US the situation is much more varied. So I am a bit perplexed about that (probably will need to make a separate entry for any main sport ?). On the Rome site, I put a lot of traditional proverbs in Romanesco, which are very funny. But I am not able to recreate the same "feeling" for NY, as it seems they do not have a massive tradition of proverbs (do they?) Some examples of proverbs we have (these are very funny, but very difficult to render in a different culture... even the translation in current Italian loses it all): https://www.frasimania.it/proverbi-romani/ https://www.lepiubellefrasi.it/proverbi-romani.html https://frasissime.com/detti-romani/ ... Corrections and suggestions are most welcome: Manual jobs: Professionals and trades Workers Shops Catering Domestic workers Transportation Security Agriculture Jobs - Assistants, Carers: Elderly and disabled assistance House assistance, Alzheimer's, Parkinson's Animation, children's surveillance Animal supervision and training Intellectual work: Informatics Engineering Graphic arts Journalism Accounting Real estate Healthcare Aesthetics Tourism Show and entertainment Sales Customer care Human resources Insurance and Banks Consulting Legal Public calls for tenders? Jobs - Teachers: School Tutoring Languages Music Singing Teachers - Other Jobs - Instructors: Fitness Combat disciplines Bodyweight disciplines Soft gymnastics Athletics Football, Basketball, Baseball, Hockey, Soccer Rehabilitation, postural gymnastics Instructors - Other Getting to know other people: Company, friendship More than a friendship Escort (adult only) Training Partners Study Partners Training groups Study groups Things and animals: Handmade Collectibles Antiques Animals and accessories Instruments, scores, librettos Electronics, Cell Phones, Audio Video, Photography IT and accessories Consoles, video games, and accessories Home & Garden Work tools, hobbies Clothing and accessories Books, magazines, games Cars, motorcycles, and vehicles: Cars Vintage car Cars - Accessories Motorcycles Motorcycles - Off-Road Vintage motorcycles Motorcycles - Accessories Caravans, motorhomes, camping Boats, nautical Bikes and accessories Electric vehicles Other vehicles Trade: Rental and Leasing Vans, commercial vehicles Machinery Large equipment Commercial furniture Business, licenses Investment proposals, equity partners Gifts: Gifts: Free items, cleanup Gifts: Toys, books Gifts: Animals, puppies Properties: Houses, apartments - condo Houses, villas - independent Land and cottages Car shelter, garage Business premises Apartments, rooms Rentals: Rentals - Box, garage rentals Rentals - Holiday houses Rentals - Commercial Premises Rentals - Other Being a New Yorker: Slang New York cuisine Songs, Poems, Sayings History of New York New York walks NY videos and photos Happening in Central Park Memories of the past Celebrities Loved by New Yorkers Movies about NY YouTubers loved by New Yorkers NY politicians DIY of New Yorkers Being a NY - Typical places: Famous and typical places of NY Typical NY shops and craftsmen Trattorias, typical NY taverns Typical NY pizzerias Typical NY bakeries Typical NY pastry shops Typical NY bars, cafes, pubs Typical NYC venues NY local recommendation Social: Centers for the elderly Shelters and centers for the homeless Volunteer initiatives Events, invitations Parks and attractions Popular sport Gyms Museums, exhibitions, churches School: from kindergarten to high school School: university Public transport Public services Bureaucracy and offices Vox Populi: Missing/found persons Missing/found items It happens on social media, news Word of mouth, useful info City of NY Trouble Reporting Warning of dangers Reporting scams Thank others for their help Neighborhood stories Criminal and unsolved stories Beautiful stories Note that the Rome and New York sites will also host classified ads to buy and sell things, while the other 3 forums are for discussions only. In particular, the ITA-EN cafe will be the one with the largest array of pure discussion topics. Note that users of the sites will never be asked for money in any form and all ads will be free. (Any revenues, if any in the far future, may only come from qualified sponsors.)
Might as well add some local flavor to the mix.... "Recipes from around the world" For example, I'd love to see the various pasta sauce recipes from small villages across Italy. And pizza dough lol. Or any other specialty from any other region of the world. Like prawns masala from India or something. Local recipes are cool.
For sure. When it comes to eating, Italy is the right place, and from the top down I'd say it is a crescendo of goodness Here are a few recipes I found in English: https://www.seriouseats.com/essential-italian-pasta-sauces https://thiswaytoitaly.com/best-popular-italian-sauces/ https://annainthekitchen.com/best-italian-pasta-sauces/ https://www.eataly.com/us_en/magazine/recipes/first-course-recipes/top-5-italian-sauces ... pizza: https://www.italiadelight.it/traditional-italian-pizzas-how-many-are-there/?lang=en https://www.idealista.it/en/news/li...28/2491-most-popular-authentic-italian-pizzas ...
Let's see something about the error and messaging system. I believe it is important to give full insight to a user about what is going on inside the app and about possible errors. Nothing is more frustrating than some incomprehensible message delivered through a modal window. (Well, unless it is required for confirmation purposes.) A classic of (older conception) msft programs, blocking a program for anything, and spreading very bad programming habits. Let's start by saying that I believe that modal windows for delivering simple messages should be a just cause for dismissal ( just kidding ) Now, in web app errors or messages can come essentially: 1) from the client 2) from the server A simple example of 1) is when you type your email in a login form and the application informs you that your email has an invalid format. That kind of messaging happens locally because the check does not involve any operation that needs to be done on the server (such as querying a DB or uploading a file, or whatever). The simple message can be delivered to the user in a temporary message flashing quickly on the screen because a quick hint is sufficient. No need to insult the intelligence of the user or to do much more (like alert() functions or other nonsense of the sort.). A simple example of 2) is for instance when you are subscribing to the site and you input an email or a nickname that is already in use. In that case, there is no way for the local browser and javascript to know that, and the message is coming from the server after it has determined that the email or nick is already inside the database. Clearly, the possible errors and messages are a very large number, at least as many as the possible interaction of the user with the server (so any kind of DB interaction or file transmission, etc.). The messages (error or some operation confirmation) that originates from the server are transmitted to the client and the receiving javascript will take care of presenting that information to the user in a proper noninvasive way. So in practice, we can imagine the following scheme: 1a- Errors coming from the server 1b- Messages coming from the server 2a- Errors coming from the client 2b- Messages coming from the client Then there are 2 possible ways of presenting the material: T) A "temporary" way: quick information is briefly "flashed" to the user, and can be automatically dismissed because there is no need to bother the user too much P) A "permanent" way: in this case, a nonmodal window will present the information so that the user can read it at his pace (copy if necessary, etc.) and close it with a click. An example of T), is positive feedback on a file upload. We can just quickly flash the information. (Even if the user does not see it, it does not matter: it's just "entertainment" ) An example of P), could be the user attempting to upload an executable, and in that case, we may provide him a more detailed explanation in a window that he can readily close with just one click. Another point is about stacking errors and messages. For instance, if you are uploading 20 or more attachments, some of them could give errors and some could land fine. So we want to stack all errors with their causes together in a unique information window, without blocking the upload operation, but just reporting on what could not be done within the required loop. So you see that, in order to keep into account all these necessities, we need at least some planning for a good (nonmodal) messaging system And certainly not the alert() method
I am currently working on the post editor/viewer, to make it more intuitive. This takes a considerable amount of patience, as this is the "core" of the client-side part of the application, and where the possible users will spend most of their time. I am replicating the edit/save button in 2 different locations so that they will be always easily reachable. This clearly forces us to create separate objects for all this stuff that is replicated. The buttons could be of the type: edit, save, save and close, and close. discard changes, remove post, and so on. Also depending on the "state" of the editor/viewer (document saved or not, editing or just viewing, etc) the configuration of the shown button has to change, so one has to put in place all these mechanisms to manage dynamically the visibility of these buttons. In order to do that I have practically dissected the whole editor/viewer and rewritten most functionalities in the form of distinct classes (objects) so I can easily move them around to find the best locations. When I work on the layout I like to set all the divs' backgrounds to some very flashy colors, so that I can see precisely where each element ends and how are relatively positioned. In the picture below you can see this "harlequinade", and actually also a view that no user will ever see , where I have in view both the viewer and the editor for the same post simultaneously visible. In the final application, the user will only see one at a time of these 2 components (as he will either be viewing or editing). (In reality, the application keeps both and moves the HTML between these windows, according to necessity). Clearly, when done, the harlequinade will disappear and we will be back to smooth and cozy colors
I finished reassembling the post editor/viewer. Here is a short demo of the current state (it's the ita-en cafe site): I am now refining and restructuring code, to make it more "maintainable" and compact, by making reusable objects wherever useful. The post editor/viewer is the largest control in the application, totaling several thousands of lines of code, most of which define other objects. For source code lovers, I am attaching the code controlling the editor buttons, which were the cause of the last changes we made. In practice, the scheme is as follows. The viewer/editor is an interface "control" that can either show the user the post or let him edit, depending on if he is the author and is in edit mode or not. It is essentially made of two graphics areas (viewer/editor), only one of which is displayed at one time. When the author starts editing, a post is created on the server. On view (posts are paginated), the post is transferred from the server to the viewer, and in the edit, the post is transferred from the "viewer" to the "editor". If saved, the post is sent back to the server with changes. If changes are discarded, the editor is just closed and we are back to the "viewer". If a user is not the author of a post, the "editor" part of the control is not created at all, and there will only be the "viewer" component. "Editor" and "viewer" behave differently. Apart from the fact that the editor has obviously all the editing functionalities, also the way the text is displayed is different. For the viewer window, in fact, we do not desire any scrolling in the Y direction. While it is useful to have while editing, the editor window will automatically fit the text while the editor maintains a scrolling window. While in the "editor", we can resize images and videos, while in the viewer, we can only click on images to show them at their original size if they are larger than shown (similar to what happens here on ET, but inside the window, instead of "popping up"). Here is some code to show the interplay between buttons: Code: class SetOfEditorButtons { Create_cSetOfEditorButtons(pev, LarghezzaBottone) { this.pev = pev; this.div_SetOfEditorButtons_Container = document.createElement('div'); this.div_SetOfEditorButtons_Container.style.cssText = `display:inline-block; vertical-align:top; padding:10px`; //bottone Save this.button_SavePostOnline = document.createElement('button'); setup_BUTTON_LOOK_ANIMATION(this.button_SavePostOnline, `${_SiteJS.ADict.SAVE_ONLINE_BUTTON_TEXT}`); this.button_SavePostOnline.style.cssText += `display:block; width:${LarghezzaBottone}; color:yellow; background-color:red; margin-top:10px;`; this.div_SetOfEditorButtons_Container.appendChild(this.button_SavePostOnline); //bottone Save and Exit this.button_SaveAndExit = document.createElement('button'); setup_BUTTON_LOOK_ANIMATION(this.button_SaveAndExit, `${_SiteJS.ADict.SAVE_AND_EXIT_BUTTON_TEXT}`); this.button_SaveAndExit.style.cssText += `display:block; width:${LarghezzaBottone}; color:yellow; background-color:red; margin-top:10px;`; this.div_SetOfEditorButtons_Container.appendChild(this.button_SaveAndExit); //bottone discard unsaved changes this.button_DiscardPostChanges = document.createElement('button'); setup_BUTTON_LOOK_ANIMATION(this.button_DiscardPostChanges, _SiteJS.ADict.DISCARD_CHANGES_BUTTON_TEXT); this.button_DiscardPostChanges.style.cssText += `display:block; width:${LarghezzaBottone}; margin-top:10px;`; this.div_SetOfEditorButtons_Container.appendChild(this.button_DiscardPostChanges); //bottone exit post edit / view online this.button_da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server = document.createElement('button'); setup_BUTTON_LOOK_ANIMATION(this.button_da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server, `${_SiteJS.ADict.RETURN_ONLINE_BUTTON_TEXT}`); this.button_da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server.style.cssText += `display:block; width:${LarghezzaBottone}; color: cyan; margin-top:10px;`; this.div_SetOfEditorButtons_Container.appendChild(this.button_da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server); //remove post button and remove functionality this.button_RemovePost = CreateRemoveButton(LarghezzaBottone, this.pev.pep); //come funzione perche serve anche per il viewer if (this.button_RemovePost) { this.button_RemovePost.style.marginTop = "40px"; this.div_SetOfEditorButtons_Container.appendChild(this.button_RemovePost) } //salvataggio post e immagini this.button_SavePostOnline.onclick = async () => { await this.pev.da_EDITOR_Salva_Post_Su_Server(); }; //save and exit this.button_SaveAndExit.onclick = async () => { await this.pev.da_EDITOR_Salva_Post_Su_Server(); await this.pev.da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server(); }; //ritorno online senza salvare this.button_DiscardPostChanges.onclick = () => { if (!this.pev.postIsUnchangedOrJustSaved) { //se gia salvato non serve if (confirm(_SiteJS.ADict.EDITOR_AVVISO_LOSE_CHANGES)) { this.pev.div_EditorWindow.innerHTML = ""; this.postIsUnchangedOrJustSaved = true; //switch a viewer this.pev.Author_Is_In_EDITOR = false; this.pev.StylesAndInterfaceDependingOnEditStatus(); } } }; this.button_da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server.onclick = async () => { await this.pev.da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server(); }; this.setButtons_DEPENDING_ON_EDIT_STATE(); } setButtons_DEPENDING_ON_EDIT_STATE() { if (!this.pev.isEditable) { notifyUnexpected(); } if (this.button_RemovePost) { if (RemoveButtonFunctionalityHasExpired(this.pev.pep)) { this.button_RemovePost.remove() } } if (this.pev.Author_Is_In_EDITOR) { if (this.pev.postIsUnchangedOrJustSaved) { this.button_SavePostOnline.style.display = "none"; //save online this.button_DiscardPostChanges.style.display = "none"; //discard changes this.button_SaveAndExit.style.display = "none"; this.button_da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server.style.display = "block"; //exit edit } else { this.button_SavePostOnline.style.display = "block"; this.button_DiscardPostChanges.style.display = "block"; this.button_SaveAndExit.style.display = "block"; this.button_da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server.style.display = "none"; } } else { this.button_SavePostOnline.style.display = "none"; this.button_DiscardPostChanges.style.display = "none"; this.button_SaveAndExit.style.display = "none"; this.button_da_EDITOR_Vai_A_Viewer_Ricaricando_Post_Da_Server.style.display = "none"; } } } class SetOfViewerButtons { Create_cSetOfViewerButtons(pev, LarghezzaBottone, InVerticale) { this.pev = pev; this.div_cSetOfViewerButtons_Container = document.createElement('div'); this.div_cSetOfViewerButtons_Container.style.cssText = `display:inline-flex; padding:10px; `; if (InVerticale) { this.div_cSetOfViewerButtons_Container.style.flexDirection = "column"; } else { this.div_cSetOfViewerButtons_Container.style.flexDirection = "row"; this.div_cSetOfViewerButtons_Container.style.marginLeft = "40px"; } //bottone Edit this.button_EditPost = document.createElement('button'); setup_BUTTON_LOOK_ANIMATION(this.button_EditPost, `Edit ✍️`); this.button_EditPost.style.cssText += `width:${LarghezzaBottone};`; this.div_cSetOfViewerButtons_Container.appendChild(this.button_EditPost); //remove post button and remove functionality this.button_RemovePost = CreateRemoveButton(LarghezzaBottone, this.pev.pep); //come funzione perche serve anche per editor if (this.button_RemovePost) { if (InVerticale) { this.button_RemovePost.style.marginTop = "40px"; } else { this.button_RemovePost.style.marginLeft = "40px"; this.button_RemovePost.style.width = "auto"; } this.div_cSetOfViewerButtons_Container.appendChild(this.button_RemovePost) } //aggancio handler per cambiare stato edit/view con bottone this.button_EditPost.onclick = () => { if (this.pev.Author_Is_In_EDITOR) { tempNotify("Already in Edit mode", false); return; } this.pev.vaiDaVIEW_Mode_A_EDIT_Mode(); //copia contenuto viewer in editor }; this.setButtons_DEPENDING_ON_EDIT_STATE(); } setButtons_DEPENDING_ON_EDIT_STATE() { if (!this.pev.isEditable) { notifyUnexpected(); } if (this.button_RemovePost) { if (RemoveButtonFunctionalityHasExpired(this.pev.pep)) { this.button_RemovePost.remove() } } if (this.pev.Author_Is_In_EDITOR) { this.button_EditPost.display = "none"; } else { this.button_EditPost.display = "block"; } } } function CreateRemoveButton(LarghezzaBottone, pep) { if (RemoveButtonFunctionalityHasExpired(pep)) { return } //bottone per rimuovere post let button_RemovePost = document.createElement('button'); setup_BUTTON_LOOK_ANIMATION(button_RemovePost, _SiteJS.ADict.REMOVE_POST_BUTTON_TEXT); button_RemovePost.style.cssText += `color:yellow; padding:10px; width:${LarghezzaBottone}`; button_RemovePost.onclick = async () => { let elapsedHours = (new Date() - pep.ThreadPost_Current.DateOfPostCreation) / 3600000; if (elapsedHours > 1) { tempNotify("Post can't be removed after more than 1 hour"); button_RemovePost.remove(); return; } if (!confirm("Confirm post removal?")) { return } let myFormData = new FormData(); myFormData.append("xhrPostPurpose", "removePost"); myFormData.append("PostID", pep.ThreadPost_Current.PostID); myFormData.append("ThreadID", pep.ThreadPost_Current.ThreadID); let xhr = await PostFormData(myFormData, pep.aspxPageTarget, `Removing post id: ${pep.ThreadPost_Current.PostID} thread id: ${pep.ThreadPost_Current.ThreadID}`); if (xhr) { await pep.afterPostRemove_callBack(xhr); } else { tempNotify(`Failed to remove post`) } }; return button_RemovePost; }
Over the weekend, I have been working to add another feature, that is showing who is following who. Later I might even create a "network chart" if it is worth it, but for the moment I am just listing in a brutal way, in the user profile, who are the followers and who is followed by the user. In the meantime, I am thinking about the general looks of the media and watching some videos about NYC to make sure I do not miss the obvious. For Rome, I am switching to yellow and red, as we have a tradition of those colors. See, for instance, the soccer team logo: https://it.wikipedia.org/wiki/Associazione_Sportiva_Roma One video on NYC that I found pretty useful and informative is this one because it enumerates the main facts in a pretty schematic way: Thank you to the creator! If you recall, we have added a table for the followers: The Js client code is similar in concept to the search we have seen before. On the server side, a query like the following will take care of retrieving, for instance, the users who are followed by a given user: Code: public List<UserInfo> Users_Seguiti_Da_Utente(int UserID) { string MySQL = "SELECT FollowedUsers.FollowedUserID, FollowedUsers.DateSubscriptionCreated, Users.* FROM FollowedUsers LEFT JOIN Users ON FollowedUsers.FollowedUserID=Users.UserID WHERE " + " FollowedUsers.UserID=@UserID AND Users.StatusUser=0 ORDER BY FollowedUsers.DateSubscriptionCreated DESC;"; using (var MyConn = this.MakeConnection()) { MyConn.Open(); using (var MyCmd = this.MakeCommand(MySQL, MyConn)) { MyCmd.Parameters.Add("@UserID", System.Data.OleDb.OleDbType.Integer).Value = UserID; using (var r = MyCmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection)) { if (r.HasRows) { List<UserInfo> ListaUsers = new List<UserInfo>(); while (r.Read()) { // skippo i primi 2 campi int startIndex = 2; UserInfo UserInfo = this.Fill_UserInfo_FromDBFields(r, startIndex); ListaUsers.Add(UserInfo); } return ListaUsers; } } } } return null; }
Working on refinements and "cleaning" and especially thinking about the suitable categories to add (especially for NYC). I have added another table to the DB (for future weekly digest) and removed/added some fields from the login table (instead of recording postId or threadId for direct access on "fast login", I am just recording the entire query string, which seems more general. I have also removed the "notification flags" from the "extended user info" and dedicated specific tables to notifications management). current situation